块级元素:div p h1-h6 form ul ol
行内元素:a b br i span input select
1)数据体积方面
json相对于xml来讲,数据的体积小,传输的速度更快。
2)数据交互方面
json和javascript的交互更加方便,更容易解析处理,更好的数据交互。
3)数据描述方面
json对数据的描述性比xml差。
4)传输速度方面
json的传输速度更快
section article aside header hgroup footer nav figure video audio embed mark progress time ruby canvas
IE盒子模型
外盒模型:
element width = content width + padding + border + margin
element height = content height + padding + border + margin
内盒模型:
element width = content width + padding + border
element height= content height + padding + border
w3c盒子模型
外盒模型:
element width = content width + margin
element height = content height + magin
内盒模型:
element width = content width
element height = content height
Trident内核:IE, TT, 360
Gecko内核:火狐
Presto内核:Opera
Webkit内核:safari, chrome
cookie是网站为了标示用户身份而存储在用户本地终端上的数据。cookie数据始终在同源的http请求中携带(即使不需要),只会在浏览器和服务器来回传递。
sessionStorage和localStorage不会自动把数据发送给服务器,只会保存在本地。
title属性没有明确意义只是表示一个标题,h1表示层次明确的标题,对页面信息抓取有很大影响。
strong是表明重点内容,有语气加强的含义,使用阅读设备阅读时,strong会重读,b则表示强调内容。
i内容为斜体,em标示强调的文本。
自然样式标签:b, i, u, s, pre
语义样式标签:strong, em, ins, del, code
datalist:规定输入域的选项列表
keygen:提供一种验证用户的可靠方法
output:用于不同类型的输出
置换元素就是浏览器根据元素的标签和属性来决定元素的具体显示内容,主要的置换元素有:
img, input, textarea, select, object
元素 1
属性 2
文本 3
注释 8
文档 9
- nodeType:节点的类型
- nodeName:节点的名称
- nodevalue:节点的值
- attributes:获取一个属性节点
- firstChild:某一节点的第一个节点
- lastChild:某一节点的最后一个子节点
- childNodes:所在节点的所有子节点
- parentnode:表示所在节点的父节点
- nextSibling:紧挨着当前节点的下一个节点
- previousSibling:紧挨着当前节点的上一个节点
- 结构性元素
- section
- header
- footer
- nav
- article
- 块级元素
- aside
- figure
- code
- dialog
- 行内语义性元素
- meter
- time
- progress
- video
- audio
- 交互性元素
- details
- datagrid
- menu
- command
1.使用HTML创建文档对象模型(DOM)
2.使用CSS创建CSS对象模型(CSSDOM)
3.基于DOM和CSSDOM执行脚本(Script)
4.使用渲染树布局所有元素的大小和位置
5.绘制所有元素
- Reflow(回流):当渲染树中的一部分(或全部)因为元素的尺寸、布局、隐藏等改变而需要重新构建。这就称为回流。
- Repaint(重绘):当渲染树中的一些元素需要更新属性,而这些属性只影响元素的外观、风格、而不影响布局。
重绘不一定会引起回流,但回流必然会引起重绘
导致回流的情况:
- 页面首次加载
- 添加或者删除可见 DOM 元素
- 元素位置的改变
- 元素尺寸改变--边距、填充、边框、宽度和高度
- 内容改变--比如文本改变或者图片大小改变而引起的计算值高度和宽度的改变
- 页面渲染初始化
- 浏览器窗口吃出改变--resize 事件发生
- 文本元素、行内元素、行内块级元素:
text-align: center
- 单个块级元素:
width: 100px; /*必须固定宽度*/
margin: 0 auto;
- 多个块级元素:
.parent {
text-align: center;
}
.child {
display: inline-block;
}
- 使用绝对定位去实现
- 任意个元素:
display: flex;
justify-content: center;
多数显示器默认频率是 60 HZ,即 1 秒刷新 60 次,所以理论最小间隔为 1/60 * 1000ms = 16.7ms
1)link是XHTML标签,除了加载CSS外,还可以定义RSS等其它事务;@import属于CSS范畴,只能加载CSS。
2)link引用CSS时,页面载入时同时加载;@imprt需要页面完全载入之后才会加载。
3)link是XHTML标签,没有兼容问题,@import是CSS2.1提出的,低版本浏览器不支持。
4)link支持使用 javascript控制DOM去改变样式,而@import不支持。
允许开发者能够自定义字体
- px 在缩放页面时无法调整那些使用它作为单位的字体,按钮等的大小。
- em 的值并不是固定的,会继承父级元素的字体的大小,代表倍数。
- rem 的值并不是固定的,始终基于根元素的,也代表倍数。
- visible:hidden;display:none
- 设置margin为负
- id选择器
- 类选择器
- 标签选择器
- 相邻选择器
- 子选择器
- 后代选择器
- 通配符选择器
- 属性选择器
- 伪类选择器
可继承的样式:font-size font-family color ul li dl dd dt
不可继承的样式:border padding margin width height
absolute:生成绝对定位的元素,相对于值不为static的第一个父元素进行定位。
fixed:生成绝对定位的元素,相对于浏览器窗口进行定位。
relative:生成相对定位的元素,相对于正常位置进行定位。
static:默认值,没有定位,元素出现在正常的流中。
inherit:规定从父元素继承position属性的值。
block:像块类型元素一样显示
none:缺省值,像行内元素类型一样显示
inline-block:像行内元素一样显示,但其内容像块类型元素一样显示
list-item:像块类型元素一样显示,并添加样式列表标记
- flex法:父元素添加display:flex,子元素添加margin:auto
- box法:子元素添加display:box;box-orient:horizontal;box-pack:center;box-align:center
- 模拟表格:父元素添加display:table,子元素添加display:table-center;vertical-align:middle
- 利用line-height
子代选择器只作用于其第一代元素,而后代选择器作用于N代元素。
- top right bottom left
- top right and left bottom
- top and bottom right and left
function Graph() {
this.verices = [];
this.edges = [];
}
Graph.prototype = {
addVertex: function(v) {
this.vertices.push(v);
}
}
var g = new Graph();
这种方式只使用于要访问的属性名称是合法的标识符,并且需要只要要访问的属性的名字。如果属性名称是一保留字或包含空格以及标点符号或者数字,则必须要使用方括号来访问属性。
原始值(undefined, null, 布尔值,数字和字符串)与对象有着根本区别,原始值是不可更改的,任何方法都无法更改。
function getMax(str) {
var n = str.length;
var hash = {};
for (var i = 0; i < n; i ++) {
var s = str[i];
if (!hash[s]) {
hash[s] = 1;
} else {
hash[s] ++;
}
}
var key;
var max = 0;
for (var j in hash) {
if (hash[j] > max) {
key = j;
max = hash[key];
}
}
return key;
}
function deepClone(obj) {
var o = obj instanceof Array ? [] : {};
for (var i in obj) {
o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
}
return o;
}
{
"name": "qiniu",
"location": "shanghai", // in shanghai
"tags": ["#golang", "//tech", "/\\\"//enthusiasm\"/"], // //manytags
// a comment line
"property": {
// these are properties
"products":["/storage//", "cdn", "/data/processing/", "////live///"] //4 products
}
}
现在要实现一个解析器,将上述文件转化为合法的json文件,即去掉注释,上述文件转化为:
{
"name": "qiniu",
"location": "shanghai",
"tags": ["#golang", "//tech", "/\\\"//enthusiasm\"/"],
"property": {
"products":["/storage//", "cdn", "/data/processing/", "////live///"]
}
}
const str = JSON.stringify(json).replace(/\/\/ \S+\n/, '');
const result = JSON.parse(str);
document.write是直接写入到页面的内容流,如果在写之前没有调用documen.open,浏览器自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。
innerHTML则是页面元素的一个属性,代表该元素的html内容。你可以精确到一个具体的元素来进行修改。
innerHTML很多情况优于document.write,其原因在于其允许更精确的控制要刷新页面的一个部分。
function request1() {
request2();
}
function request2() {
....
}
function request1() {
return new Promise((resolve, reject) => {
})
}
function request2() {
return new Promise((resolve, reject) => {
})
)
function handle() {
Promise.all([request1, request2]);
}
function flatten(arr) {
var result = [];
var len = arr.length;
for (var i = 0; i < len;i ++) {
var ele = arr[i];
if (ele.length === 1 || !Array.isArray(ele)) {
result.push(ele);
} else {
var temp = flatten(ele);
result = result.concat(temp);
}
}
return result;
}
// function input
var endorsements = [
{skill: 'javascirpt', user: 'Chad'},
{skill: 'javascript', user: 'Bill'},
{skill: 'javascript', user: 'Sue'},
{skill: 'html', user: 'Sue'},
{skill: 'css', user: 'Sue'},
{skill: 'css', user: 'Bill'}
]
// function output
[
{skill: 'javascript', user: ['Chad', 'Bill', 'Sue'], count: 3},
{skill: 'css'}, user: ['Sue', 'Bill'], count: 2},
{skill: 'html', user: ['Sue'], count: 1}
];
function countLanguage(inputArr) {
var outputArr = [];
var outputObj = {};
for (var i = 0; i < inputArr.length; i ++) {
var ele = inputArr[i];
if (!outputObj[ele.skill]) {
var obj = {};
obj.user = [];
obj.skill = ele.skill;
obj.user.push(ele.user);
obj.count = 1;
outputObj[ele.skill] = obj;
console.log(obj.count);
} else {
console.dir(outputObj[ele.skill]);
outputObj[ele.skill].user.push(ele.user);
console.log(outputObj[ele.skill].count);
outputObj[ele.skill].count ++;
}
}
for (var key in outputObj) {
outputArr.push(outputObj[key]);
}
console.dir(outputArr);
}
看到一个惊为天人的方法:
JSON.stringify(obj1) === JSON.stringify(obj2)
1)instanceof 但是在IE上不一定成功
2)isArray方法
3)使用数组的内部属性
fuction isArray(arr) {
return toString.apply(arr) === '[object Array]';
}
/^[a-zA-Z][a-zA-Z0-9_]{5,16}$/
Function.prototype.bind = function() {
var fb = this;
var args = Array.prototype.slice.call(arguments);
var object = args.shift();
return function() {
return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}
1)创建新节点
createDocumentFragment()
createElement()
createTextNode()
2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefor()
3)查找
getElementByTagName()
getElementByName()
getElementById()
- .匹配除了行结束符的一切字符。使用[\s\S]可以真正匹配一切。
- 转义字符类
- \d匹配数字([0-9]),\D匹配非数字([ ^ 0-9])
- \w匹配拉丁字母数字的字符以及下划线([A-Za-z0-9_]),\W匹配所有其它字符。
- \s匹配所有空白字符(空格,制表符,换行符等);\S匹配所有非空白字符。
- regex.test(str):是否存在匹配
- str.search(regex):在哪个索引匹配
- regex.exec(str):捕获分组
- str.match(regex)捕获分组货返回所有匹配的子字符串
- str.replace(search, replacement):查找和替换
function isPalindrom(str) {
return str === str.split('').reverse().join('');
}
通过innerHTML
- IE cancelBubble
- Chrome stopPropagation
insertBefore
insertAdjacentHTML
-
子类的原型对象--类式继承
// declare the father class function SuperClass() { this.superValue = true; } // add common method for the father class SuperClass.prototype.getSuperValue = function() { return this.superValue; }; // declare the child class function SubClass() { this.subValue = false; } // inherit from the father class SubClass.prototype = new SuperClass(); // add common method for SubClass SubClass.prototype.getSubValue = function() { return this.subValue; }
-
创建即继承--构造函数继承
// declare the father class function SuperClass() { this.superValue = true; }; SuperClass.prototype.getSuperValue = function() { return this.superValue; }; function SubClass(superValue) { SuperClass.call(this, superValue); }
Object是所有对象的父对象。
数据封装类对象:Object, Array, Boolean, Number, String
其他对象:Function, Arguments, Math, Date, RegExp, Error
1)创建XMLHttpRequest对象,也就是创建一个异步调用对象。
2)创建一个新的HTTP请求,并制定该请求的方法、URL、以及验证信息。
3)设置响应HTTP请求状态变化的函数。
4)发送HTTP请求。
5)获取异步调用返回的数据。
6)使用javascript和dom实现局部刷新。
0(未初始化)还没有调用open方法
1(载入)已经调用send方法,正在发送请求。
2(载入完成)send方法完成,已经收到全部响应内容。
3(解析)正在解析响应内容。
4(完成)响应内容解析完成。
Object.prototype.toString.call(obj) === "[object Object]"
下面代码的执行结果(原题)
var z = 10;
function foo() {
console.log(z);
}
(function(funArg) {
var z = 20;
funArg();
})(foo);
答案是10
Math.pow(0.1, -1)
- 保持内部的一致性
- 性能优化
- 缩小文件体积,提升性能
- 可以混淆 js 代码
- 减少http请求
- 从设计实现页面简化
- 合理设置http缓存,对于很少改变的资源设置较长的过期时间
- 资源合并和压缩,css,js以及图片文件
- CSS雪碧图
- 图片惰性加载
- 将外部脚本置底,外链脚本在加载时会阻塞其他资源
- 异步执行inline脚本,比如使用defer属性
- 惰性加载js文件
- 将css放在head中
- 减少不必要的http跳转
- 避免重复资源的请求
- 减少直接操作dom元素
- 减少repaint和reflow
- 慎用with
- 对于依赖的模块,amd是提前执行,cmd是延迟执行
- cmd推崇依赖就近,amd推崇依赖前置
- and的api默认是一个当多个用,cmd严格区分
TODO
可以阅读一下underscore, jquery, bootstrap 的源代码。
- HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等,告诉浏览器不用缓存请求;
- 需要根据cookie,认证信息等决定输入内容的动态请求是不能被缓存的;
- 经过HTTPS安全加密的请求
- POST请求
- HTTP请求像迎头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存
- iframe会阻塞主页面onload事件
- iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面并行加载。
- 根据输出的上下文进行编码
- 内容安全策略,向网络浏览器发送一组 html 标头指令,帮助浏览器执行应该执行的脚本
- 通过 httponly 可以防止 js 读取 cookie
- 对用户输入字符进行过滤,防止恶意字符串
- 对字符进行编码,限制用户输入的字符