这里写链接内容
知乎上一个前端面试题答案的解答:
https://www.zhihu.com/question/19568008
MicroMao ,代码诗人小毛
88 人赞同
自己总结的面试题,感兴趣的看下。
HTML+CSS
1、盒子模型,块级元素和行内元素特性与区别。
2、行内块的使用,兼容性解决。
3、清除浮动的方式以及各自的优劣。
4、文档流的概念、定位的理解以及z-index计算规则&浏览器差异性。
5、CSS选择器以及优先级计算。
6、常用的CSS hack。
7、遇到的兼容性问题与解决方法。
8、垂直水平居中的实现方式。
9、常用布局的实现(两列布局、三列适应布局,两列等高适应布局等)。
JavaScript
1、犀牛书封面的犀牛属于神马品种?(蛋逼活跃气氛用。。。)
2、常用的浏览器内核。
3、常用的DOM操作,新建、添加、删除、移动、查找等。
4、String于Array常用方法。
5、设备与平台监测。
6、DOM的默认事件、事件模型、事件委托、阻止默认事件、冒泡事件的方式等。
7、jQuery的bind、live、on、delegate的区别(考察点与上一条重叠,切入点不同)。
8、JS变量提升、匿名函数、原型继承、作用域、闭包机制等。
9、对HTTP协议的理解。
10、Ajax的常用操作,JS跨域的实现原理。
**
2、常用的浏览器内核。
作者:heqian
链接:https://www.zhihu.com/question/41807413/answer/92413711
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
一、Trident内核代表产品Internet Explorer,又称其为IE内核。
Trident(又称为MSHTML),是微软开发的一种排版引擎。使用Trident渲染引擎的浏览器包括:IE、傲游、世界之窗浏览器、Avant、腾讯TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。
二、Gecko内核代表作品Mozilla
FirefoxGecko是一套开放源代码的、以C++编写的网页排版引擎。Gecko是最流行的排版引擎之一,仅次于Trident。使用它的最著名浏览器有Firefox、Netscape6至9。
三、WebKit内核代表作品Safari、Chromewebkit
是一个开源项目,包含了来自KDE项目和苹果公司的一些组件,主要用于Mac OS系统,它的特点在于源码结构清晰、渲染速度极快。缺点是对网页代码的兼容性不高,导致一些编写不标准的网页无法正常显示。主要代表作品有Safari和Google的浏览器Chrome。
四、Presto内核代表作品OperaPresto
是由Opera Software开发的浏览器排版引擎,供Opera 7.0及以上使用。它取代了旧版Opera 4至6版本使用的Elektra排版引擎,包括加入动态功能,例如网页或其部分可随着DOM及Script语法的事件而重新排版。
3、常用的DOM操作,新建、添加、删除、移动、查找等。
http://blog.sina.com.cn/s/blog_49fa034d0101gg7m.html
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement_x_x() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
1.创建元素节点
document.createElement_x_x() 方法 用于创建元素,接受一个参数,即要创建元素的标签名,返回创建的元素节点
1 var div = document.createElement_x_x(“div”); //创建一个div元素
2 div.id = “myDiv”; //设置div的id
3 div.className = “box”; //设置div的class
创建元素后还要把元素添加到文档树中
2.添加元素节点
appendChild() 方法 用于向childNodes列表的末尾添加一个节点,返回要添加的元素节点
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var li = document.createElement_x_x(“li”); //创建li
3 li.innerHTML = “项目四”; //向li内添加文本
4 ul.appendChild(li); //把li 添加到ul子节点的末尾
appendChild() 方法还可以添加已经存在的元素,会将元素从原来的位置移到新的位置
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 ul.appendChild(ul.firstChild); //把ul的第一个元素节点移到ul子节点的末尾
insertBefore() 方法,如果不是在末尾插入节点,而是想放在特定的位置上,用这个方法,该方法接受2个参数,第一个是要插入的节点,第二个是参照节点,返回要添加的元素节点
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var li = document.createElement_x_x(“li”); //创建li
3 li.innerHTML= “项目四”; //向li内添加文本
4 ul.insertBefore(li,ul.firstChild); //把li添加到ul的第一个子节点前
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var li = document.createElement_x_x(“li”); //创建li
3 li.innerHTML= “项目四”; //向li内添加文本
4 ul.insertBefore(li,ul.lastChild); //把li添加到ul的子节点末尾
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var li = document.createElement_x_x(“li”); //创建li
3 li.innerHTML= “项目四”; //向li内添加文本
4 var lis = ul.getElementsByTagName_r(“li”) //获取ul中所有li的集合
5 ul.insertBefore(li,lis[1]); //把li添加到ul中的第二个li节点前
添加后:
3.移除元素节点
removeChild() 方法,用于移除节点,接受一个参数,即要移除的节点,返回被移除的节点,注意被移除的节点仍然在文档中,不过文档中已没有其位置了
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var fromFirstChild = ul.removeChild(ul.firstChild); //移除ul第一个子节点
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var lis = ul.getElementsByTagName_r(“li”) //获取ul中所有li的集合
3 ul.removeChild(lis[0]); //移除第一个li,与上面不同,要考虑浏览器之间的差异
4.替换元素节点
replaceChild() 方法,用于替换节点,接受两个参数,第一参数是要插入的节点,第二个是要替换的节点,返回被替换的节点
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var fromFirstChild = ul.replaceChild(ul.firstChild); //替换ul第一个子节点
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul;
2 var li = document.createElement_x_x(“li”); //创建li
3 li.innerHTML= “项目四”; //向li内添加文本
4 var lis = ul.getElementsByTagName_r(“li”) //获取ul中所有li的集合
5 var returnNode = ul.replaceChild(li,lis[1]); //用创建的li替换原来的第二个li
5.复制节点
cloneNode() 方法,用于复制节点, 接受一个布尔值参数, true 表示深复制(复制节点及其所有子节点), false 表示浅复制(复制节点本身,不复制子节点)
1 var ul = document.getElementByIdx_xx_x(“myList”); //获得ul
2 var deepList = ul.cloneNode(true); //深复制
3 var shallowList = ul.cloneNode(false); //浅复制
4、String与Array常用方法。
http://www.jb51.net/article/47033.htm
- Array
- new Array()
- new Array(len)
- new Array(item0, item1, item2,….)
- arr.concact(item1,item2…) ———-返回一个新数组,是将参数添加到原数组中构成的
- arr.join(separator) ———将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符
- arr.pop() ————删除原数组最后一项,并返回删除元素的值;如果数组为空则返回undefined
- arr.push(item1,item2…) ———将参数添加到原数组末尾,并返回数组的长度
- arr.reverse() ————–反序
- arr.shift() ————移去第一个元素并返回其值
- arr.slice(start, end) ———-返回数组对象的一个子集,索引从start开始(包括 start),到end结束(不包括end),原有数组不受影响. 当 start或者end为负数时,则使用他们加上length后地值. 如果end小于等于start,将返回空数组。
- arr.sort(comparefn) ——–根据comparefn定义的大小比较函数,对一个数组进行排序。函数comparefn必须接受两个参数element1,element2,如果需要需要element1排在element2之前,应该返回一个负数;如果需要element1排在element2之后,应该返回一个正数,如果两个数平等对待(即保持原有顺序)则返回0。当省略comparefn时,则元素按照字典顺序排列
- objArray.splice(start,deleteCount[,item1,item2[,…]]]) ————这是一个复杂的函数,用于完成数组元素的删除 取代和插入操作。其中,start参数表示要进行操作的索引位置,deleteCount指从start开始要删除的元素的元素个数(包括了start位置),如果deleteCount省略,则表示从start开始要删除数组的剩余部分。[,item1[,item2[,…]]]则表示可选的插入到start之前的元素列表
- objArray.unshift(item1[,item2[,…]]]) ————将参数列表插入到数组的开头,并返回数组的长度 。其性质和push方法类型,但push方法是将元素添加到数组的结尾。如: [1,2,3,4].unshift(“a”,”b”)将得到[“a”,”b”,1,2,3,4]。
http://www.jb51.net/article/29547.htm
String
- charCodeAt方法返回一个整数,代表指定位置字符的Unicode编码。
- strObj.charCodeAt(index)
- 说明: index将被处理字符的从零开始计数的编号。有效值为0到字符串长度减1的数字。 如果指定位置没有字符,将返回NaN。
- 例如:
- var str = “ABC”;
str.charCodeAt(0);
结果:65
- fromCharCode方法从一些Unicode字符串中返回一个字符串.
- String.fromCharCode([code1[,code2…]])
- 说明: code1,code2…是要转换为字符串的Unicode字符串序列。如果没有参数,结果为空字符串。
- 例如:
- String.fromCharCode(65,66,112);
- 结果:ABp
- charAt方法返回指定索引位置处的字符。如果超出有效范围的索引值返回空字符
- strObj.charAt(index)
- 说明: index想得到的字符的基于零的索引。有效值是0与字符串长度减一之间的值。
- 例如:
- var str = “ABC”;
str.charAt(1);
结果:B
- slice方法返回字符串的片段。
- strObj.slice(start[,end])
- 说明: start下标从0开始的strObj指定部分其实索引。如果start为负,将它作为length+start处理,此处length为字符串的长度。
end小标从0开始的strObj指定部分结束索引。如果end为负,将它作为length+end处理,此处length为字符串的长度。 - 例如:
012345
var str = “ABCDEF”;
str.slice(2,4);
结果:CD
substring方法返回位于String对象中指定位置的子字符串。
- strObj.substring(start,end)
- 说明: start指明子字符串的起始位置,该索引从0开始起算。
end指明子字符串的结束位置,该索引从0开始起算。
substring方法使用start和end两者中的较小值作为子字符串的起始点。如果start或end为NaN或者为负数,那么将其替换为0。 - 例如:
012345
var str = “ABCDEF”;
str.substring(2,4); // 或 str.substring(4,2);
结果:CD
substr方法返回一个从指定位置开始的指定长度的子字符串。
- strObj.substr(start[,length])
- 说明: start所需的子字符串的起始位置。字符串中的第一个字符的索引为0。 length在返回的子字符串中应包括的字符个数。
- 例如:
012345
var str = “ABCDEF”;
str.substr(2,4);
结果:CDEF
- indexOf方法放回String对象内第一次出现子字符串位置。如果没有找到子字符串,则返回-1。
- strObj.indexOf(substr[,startIndex])
- 说明: substr要在String对象中查找的子字符串。
startIndex该整数值指出在String对象内开始查找的索引。如果省略,则从字符串的开始处查找。 - 例如:
01234567
var str = “ABCDECDF”;
str.indexOf(“CD”,1); // 由1位置从左向右查找 123…
结果:2
- lastIndexOf方法返回String对象中字符串最后出现的位置。如果没有匹配到子字符串,则返回-1。
- strObj.lastIndexOf(substr[,startindex])
- 说明:
substr要在String对象内查找的子字符串。
startindex该整数值指出在String对象内进行查找的开始索引位置。如果省略,则查找从字符串的末尾开始。 - 例如:
01234567
var str = “ABCDECDF”;
str.lastIndexOf(“CD”,6); // 由6位置从右向左查找 …456
结果:5
- search方法返回与正则表达式查找内容匹配的第一个字符串的位置。
- strObj.search(reExp)
- 说明:
reExp包含正则表达式模式和可用标志的正则表达式对象。 - 例如:
var str = “ABCDECDF”;
str.search(“CD”); // 或 str.search(/CD/i);
结果:2
- concat方法返回字符串值,该值包含了两个或多个提供的字符串的连接。
- str.concat([string1[,string2…]])
- 说明:
string1,string2要和所有其他指定的字符串进行连接的String对象或文字。 - 例如:
var str = “ABCDEF”;
str.concat(“ABCDEF”,”ABC”);
结果:ABCDEFABCDEFABC
- split将一个字符串分割为子字符串,然后将结果作为字符串数组返回。
- strObj.split([separator[,limit]])
- 说明:
separator字符串或 正则表达式 对象,它标识了分隔字符串时使用的是一个还是多个字符。如果忽略该选项,返回包含整个字符串的单一元素数组。
limit该值用来限制返回数组中的元素个数。 - 例如:
var str = “AA BB CC DD EE FF”;
alert(str.split(” “,3));
结果:
AA,BB,CC
- toLowerCase方法返回一个字符串,该字符串中的字母被转换成小写。
- 例如:
var str = “ABCabc”;
str.toLowerCase();
结果:abcabc
- 例如:
- toUpperCase方法返回一个字符串,该字符串中的所有字母都被转换为大写字母。
- 例如:
var str = “ABCabc”;
str.toUpperCase();
结果:ABCABC
- 例如:
- charCodeAt方法返回一个整数,代表指定位置字符的Unicode编码。
5、设备与平台监测。
http://www.cnblogs.com/wuyuchang/p/4248514.html
//取得用户代理字符串 并全部小写。
var ua = navigator.userAgent.toLowerCase();
document.write(ua);
1、识别呈现引擎
引擎主要包含四种:IE、Gecko、WebKit、Opera
2、识别浏览器
主流浏览器包含四种:IE、Chrome、Firefox、Opera
3、识别平台
主流平台包含三类:Windows、Mac、Unix
4、识别Windows操作系统
Windows操作系统包含:Windows 98、Window NT、Window XP、Window Vista、Windows 7…
5、识别移动设备
主流的移动设备包含三类:iPhone、iPod、Anroid、Nokia
6、识别游戏系统。
主流的游戏系统包含两类:Wii、PS3。
网上发现的比较简单的区分代码:
var ua = navigator.userAgent.toLowerCase();
var isStrict = document.compatMode == "CSS1Compat"
isOpera = ua.indexOf("opera") > -1
isChrome = ua.indexOf("chrome") > -1
isSafari = !isChrome && (/webkit|khtml/).test(ua)
isSafari3 = isSafari && ua.indexOf('webkit/5') != -1
isIE = !isOpera && ua.indexOf("msie") > -1
isIE7 = !isOpera && ua.indexOf("msie 7") > -1
isIE8 = !isOpera && ua.indexOf("msie 8") > -1
isGecko = !isSafari && !isChrome && ua.indexOf("gecko") > -1
isGecko3 = isGecko && ua.indexOf("rv:1.9") > -1
isBorderBox = isIE && !isStrict
isWin7 = ua.indexOf("nt 6.1") > -1
isVista = ua.indexOf("nt 6.0") > -1
isWin2003 = ua.indexOf("nt 5.2") > -1
isWinXp = ua.indexOf("nt 5.1") > -1
isWin2000 = ua.indexOf("nt 5.0") > -1
isWindows = (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1)
isMac = (ua.indexOf("macintosh") != -1 || ua.indexOf("mac os x") != -1)
isAir = (ua.indexOf("adobeair") != -1)
isLinux = (ua.indexOf("linux") != -1)
var sys = "";
var broser = "";
if(isIE){
broser = "IE 6";
}else if(isIE7){
broser = "IE 7";
}else if(isIE8){
broser = "IE 8";
}else if(isOpera){
broser = "Opera";
}else if(isChrome){
broser = "Chrome";
}else if(isSafari){
broser = "Safari";
}else if(isSafari3){
broser = "Safari3";
}else{
broser = "Unknow";
}
if(isWin7){
sys = "Windows 7";
}else if(isVista){
sys = "Vista";
}else if(isWinXp){
sys = "Windows xp";
}else if(isWin2003){
sys = "Windows 2003";
}else if(isWin2000){
sys = "Windows 2000";
}else if(isWindows){
sys = "Windows";
}else if(isMac){
sys = "Macintosh";
}else if(isAir){
sys = "Adobeair";
}else if(isLinux){
sys = "Linux";
}else{
sys = "Unknow";
}
document.write(ua);
alert(sys + ":" + broser);
比较全面的区分代码:
var client = function(){
//呈现引擎
var engine = {
ie : 0,
gecko : 0,
webkit : 0,
khtml : 0,
opera : 0,
//完整的版本号
ver : null
};
//浏览器
var browser = {
//主要浏览器
ie : 0,
firefox : 0,
konq : 0,
opera : 0,
chrome : 0,
safari : 0,
//具体的版本号
ver : null
};
//平台、设备和操作系统
var system ={
win : false,
mac : false,
xll : false,
//移动设备
iphone : false,
ipod : false,
nokiaN : false,
winMobile : false,
macMobile : false,
//游戏设备
wii : false,
ps : false
};
//检测呈现引擎和浏览器
var ua = navigator.userAgent;
if (window.opera){
engine.ver = browser.ver = window.opera.version();
engine.opera = browser.opera = parseFloat(engine.ver);
} else if (/AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
//确定是Chrome还是Safari
if (/Chrome\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.chrome = parseFloat(browser.ver);
} else if (/Version\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.safari = parseFloat(browser.ver);
} else {
//近似地确定版本号
var safariVersion = 1;
if(engine.webkit < 100){
safariVersion = 1;
} else if (engine.webkit < 312){
safariVersion = 1.2;
} else if (engine.webkit < 412){
safariVersion = 1.3;
} else {
safariVersion = 2;
}
browser.safari = browser.ver = safariVersion;
}
} else if (/KHTML\/(\S+)/.test(ua) || /Konquersor\/([^;]+)/.test(ua)){
engine.ver = browser.ver = RegExp["$1"];
engine.khtml = browser.kong = paresFloat(engine.ver);
} else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
engine.ver = RegExp["$1"]
engine.gecko = parseFloat(engine.ver);
//确定是不是Firefox
if (/Firefox\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.firefox = pareseFloat(browser.ver);
}
} else if(/MSIE([^;]+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.firefox = parseFloat(browser.ver);
}
//检测浏览器
browser.ie = engine.ie;
browser.opera = engine.opera;
//检测平台
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
//检测Windows操作系统
if (system.win){
if (/Win(?:doms)?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){
if (RegExp["$1"] == "NT"){
switch(RegExp["$2"]){
case "5.0":
system.win = "2000";
break;
case "5.1":
system.win = "XP";
break;
case "6.0":
system.win = "Vista";
break;
default :
system.win = "NT";
break;
}
} else if (RegExp["$1"]){
system.win = "ME";
} else {
system.win = RegExp["$1"];
}
}
}
//移动设备
system.iphone = ua.indexOf("iPhone") > -1;
system.ipod = ua.indexOf("iPod") > -1;
system.nokiaN = ua.indexOf("NokiaN") > -1;
system.winMobile = (system.win == "CE");
system.macMobile = (system.iphone || system.ipod);
//游戏系统
system.wii = ua.indexOf("Wii") > -1;
system.ps = /playstation/i.test(ua);
//返回这些对象
return {
engine: engine,
browser: browser,
system: system
};
}()
http://www.uedbox.com/js-notes-checking-client-javascript/
6、DOM的默认事件、事件模型、事件委托、阻止默认事件、冒泡事件的方式等。
见DOM的默认事件、事件模型、事件委托、阻止默认事件、冒泡事件的方式等。
7、jQuery的bind、live、on、delegate的区别(考察点与上一条重叠,切入点不同)。
http://www.cnblogs.com/piercalex/archive/2013/03/30/2990679.html
http://blog.csdn.net/panfang/article/details/21705681
bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数。
.bind()是最直接的绑定方法 ,会绑定事件类型和处理函数到DOM element上, 这个方法是存在最久的,而且也很好的解决了浏览器在事件处理中的兼容问题。但是这个方法有一些performance方面的问题,看下面的代码:
$("a").bind("click",function(){alert("ok");});
优点:
- 这个方法提供了一种在各种浏览器之间对事件处理的兼容性解决方案
- 非常方便简单的绑定事件到元素上 .click(),
- .click(), .hover()…这些非常方便的事件绑定,都是bind的一种简化处理方式
- 对于利用ID选出来的元素是非常好的,不仅仅是很快的可以hook上去(因为一个页面只有一个id),而且当事件发生时,handler可以立即被执行(相对于后面的live,delegate)实现方式
缺点:
- 它会绑定事件到所有的选出来的元素上
- 它不会绑定到在它执行完后动态添加的那些元素上
- 当元素很多时,会出现效率问题
live(type,[data],fn)给所有匹配的元素附加一个事件处理函数,即使这个元素是以后再添加进来的。
.live()方法用到了事件委托的概念来处理事件的绑定。它和用.bind()来绑定事件是一样的。.live()方法会绑定相应的事件到你所选择的元素的根元素上,即是document元素上。那么所有通过冒泡上来的事件都可以用这个相同的handler来处理了。它的处理机制是这样的,一旦事件冒泡到document上,jQuery将会查找selector/event metadata,然后决定那个handler应该被调用。
$("a").live("click",function(){alert("ok");});
delegate(selector,[type],[data],fn) 指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
.delegate()有点像.live(),不同于.live()的地方在于,它不会把所有的event全部绑定到document,而是由你决定把它放在哪儿。而和.live()相同的地方在于都是用event delegation.
$("#container").delegate("a","click",function(){alert("ok");})
on(events,[selector],[data],fn) 在选择元素上绑定一个或多个事件的事件处理函数。
其实.bind(), .live(), .delegate()都是通过.on()来实现的,.unbind(), .die(), .undelegate(),也是一样的都是通过.off()来实现的
优点:
- 提供了一种统一绑定事件的方法
- 仍然提供了.delegate()的优点,当然如果需要你也可以直接用.bind()
缺点: - 也许会对你产生一些困扰,因为它隐藏了一前面我们所介绍的三种方法的细节。
差别:
- .bind()是直接绑定在元素上
- .live()则是通过冒泡的方式来绑定到元素上的。更适合列表类型的,绑定到document DOM节点上。和.bind()的优势是支持动态数据。
- .delegate()则是更精确的小范围使用事件代理,性能优于.live()
- .on()则是最新的1.7版本整合了之前的三种方式的新事件绑定机制
结论:
- 用.bind()的代价是非常大的,它会把相同的一个事件处理程序hook到所有匹配的DOM元素上
- 不要再用.live()了,它已经不再被推荐了,而且还有许多问题
- .delegate()会提供很好的方法来提高效率,同时我们可以添加一事件处理方法到动态添加的元素上。
- 我们可以用.on()来代替上述的3种方法
8、JS变量提升、匿名函数、原型继承、作用域、闭包机制等。
9、对HTTP协议的理解。
深入理解HTTP协议、HTTP协议原理分析
这篇讲的很好,多看看