Top of your head knowledge For F2E -1

Nicholas C. Zakas 博文中提到了前端工程师必须想都不用想都能知道的web开发常识


    * DOM structure - how nodes are related to one another and how to traverse from one to the next.
    * DOM manipulation - how to add, remove, move, copy, create, and find nodes.
    * Events - how to use them and the major differences between IE and the DOM event models.
    * XMLHttpRequest - what it is, how to perform a complete GET request, how to detect errors.
    * Strict vs. quirks modes - how to trigger each and why this matters.
    * The box model - how margin, padding, and border are related and how Internet Explorer < 8 does things differently.
    * Block vs. inline elements - how to manipulate using CSS, how they effect things around them and your ability to style them.
    * Floating elements - how to use them, troubles with them, and how to work around the troubles.
    * HTML vs. XHTML - how they’re different, why you might want to use one over the other.
    * JSON - what it is, why you’d want to use it, how to actually use it, implementation details.

对这些问题我自认尚不能达到完全明了,这一系列博文就对这些基础问题进行一点总结与研究。

注:部分来源于已有网络资料

 

修订日期:

2010-01-25 14:50

2010-02-02 已将整理的全部问题完整资料放入 google doc

 

前端基础分享@google doc


* DOM结构

 

两个节点之间可能存在哪些关系以及如何在节点之间任意移动。
http://www.w3.org/TR/DOM-Level-2-Core/core.html

当前节点为node
父节点:node.parentNode
子节点NodeList:node.childNodes 包括文本,注释等节点
注意IE与webkit,gecko核心浏览器区别,ie不会将标签间空白字符也算作文字节点

 

<div id="test">s
    <div></div>
    </div>
<script>
alert(document.getElementById("test").childNodes.length);
</script>

 

第一个子节点:node.firstChild
最后一个子节点: node.lastChild
同一层上一个子节点:node.nextSibling
同一层下一个子节点:node.previousSibling



* DOM操作

 

怎样添加、移除、移动、复制、创建和查找节点。


核心DOM
http://www.w3.org/TR/DOM-Level-2-Core/core.html

节点的操作:


创建节点:

 

document.createElement("div");
document.createTextNode("textnode"); 

 

创建节点碎片:

 

document.createDocumentFragment();

 

防止页面频繁Reflow

添加节点:

 

parentNode.appendChild(node);//在节点parentNode的子节点后追加node子节点
parentNode.insertBefore(newChild, oldChild);
//在 oldChild前插入newChild节点,当oldChild不填时,相当于appendChild
//注意不存在:parentNode.insertAfter() 

 

删除节点:

 

parentNode.removeChild(node) 

 

复制节点:

 

parentNode.cloneNode(deep); 
//deep为true时,则为深拷贝同时复制所有子节点,为false时,则只复制该节点//(该节点所有属性都会复制)

 

替换节点:

 

parentNode.replaceChild(newNode,oldNode)  
//将oldNode节点替换为newNode节点。
 


访问节点:


document.getElementsByTagName(name)
返回带有指定标签名的对象的集合,元素的顺序是它们在文档中的顺序。如果把特殊字符串 "*" 传递给 getElementsByTagName() 方法,它将返回文档中所有元素的列表,元素排列的顺序就是它们在文档中的顺序。
也可node.getElementsByTagName(name) 表示增加约束,只能在node的后代节点中查找。

注意上述返回都为 HTMLCollection 类型,并且是活的,当文档结构改变后,结果也随着改变,比如无限循环问题:

 

var divs=document.getElementsByTagName("div");
for(var i=0;i<divs.length;i++) {
    var div=document.createElement("div");
    document.body.appendChild(div);
}

 

注意:

标准浏览器还可以使用 dom traversal 操作,目前除了ie都基本支持

http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html

 

例如:

 

<div id="test">s 
	<div></div>
<input name="child"/>
	</div>
	<input name="child"/>
	<br/>
<script>
//文档中的所有element节点
var supported=document.implementation.hasFeature("Traversal","2.0");
if(supported){
var iter= document.createNodeIterator(document, NodeFilter.SHOW_ELEMENT, null,true); 
var n=iter.nextNode();
var loop=0;
while (n  && (++loop<10)) {
  document.writeln("nodeName :"+ n.nodeName+"<br/>");
  n=iter.nextNode();
}
}else {
	document.writeln("DOM 2 Traversal not supported");
}
</script>

  一点说明:虽然 firefox

document.implementation.hasFeature("Traversal","2.0");

为false,但是traversal api还是能用的.

 



操作节点属性:
node.getAttribute(name)
得到节点设置的name属性
Node.setAttribute(name,value)
设置节点的name属性
注意上述属性以及属性值都为字符串类型
node.removeAttribute(name)
删除节点的name属性

HTML DOM
http://www.w3.org/TR/DOM-Level-2-HTML/html.html

Document.getElementById(id)
返回对拥有指定 ID 的第一个对象的引用。(注意为第一个)

document.getElementsByName(name)
返回带有指定名称的对象的集合。

HTML DOM 提供了 HTML DOM对象 ,简化了一些操作:
比如:
Select 对象集合
options[]
返回包含下拉列表中的所有选项的一个数组。
add(option)
向下拉列表添加一个选项。
Remove(index)
从下拉列表中删除一个选项。

比如:
Img 为图片DOM节点
Img.width 与 img. getAttribute(“width”) 当节点有width属性时结果一样
但是 img.width 为数字类型,而img. getAttribute(“width”)为字符串类型
当节点没有设置width设置时,img.width可以取得图片本身的值,而img. getAttribute(“width”)为空,可见点取得属性时会动态的得到节点真实的值。

 

比如:
一些方便的表格属性以及方法:
tr.cells
返回 tr元素中的所有单元格
table.rows
表格中所有行的集合
table.insertRow(position)
用于在表格中的指定位置插入一个新行。返回一个 TableRow,表示新插入的行
table.deleteRow(position)
删除表格指定位置的一行
insertCell(position)
用于在 HTML 表的一行的指定位置插入一个空的 <td> 元素。返回一个 TableCell 对象,表示新创建并被插入的 <td> 元素。请注意,该方法只能插入 <td> 数据表元。若需要给行添加头表元,必须用 Document.createElement() 方法和 Node.insertBefore() 方法(或相关的方法)创建并插入一个 <th> 元素。
deleteCell(position)
删除表格行中的单元格(<td> 元素)。


* 事件

 

怎样使用事件以及IE和DOM事件模型之间存在哪些主要差别。


冒泡与捕获
事件有两种触发方式, Bubbling(冒泡) 与Capturing(捕获)。,冒泡是当一个DOM节点的某事件例如click事件被触发时,它的父节点的click事件也被触发,一直传递到最顶层的body元素,然后再触发 document 的相应事件。而捕获的触发方式正好相反,当某个元素的click事件被触发时,先触发 document 的相应事件,然后再从最顶层的body元素click事件被触发开始,一直传递到真正被触发的元素为止。


建议采用 DOM-2 事件模型,可以同一元素同一事件绑定多个事件处理器,分为 w3c 标准模型与 IE 模型
http://www.quirksmode.org/dom/w3c_events.html

W3c 标准模型:
http://www.w3.org/TR/DOM-Level-2-Events/events.html

注册事件:
使用addEventListener和removeEventListener,例如


window.addEventListener(‘load’,function(evt){…},false);
document.body.addEventListener(‘keypress’,function(evt){…},false);
obj.addEventListener(‘mouseover’,MV,true);
function MV(evt){…} 

 

addEventListener带有三个参数,第一个参数是事件类型,就是我们熟知的那些事件名字去掉前面的’on’,第二个参数是处理函数,可以直接 给函数字面量或者函数名,第三个参数是boolean值,表示事件是否支持Capturing。
W3C的事件模型优点是Bubbling和Capturing都支持,并且可以在一个DOM元素上绑定多个事件处理器,各自并不会冲突。并且在处理函数内 部,this关键字仍然可以使用只想被绑定的DOM元素。另外function参数列表的第一个位置(不管是否显示调用),都永远是event对象的引 用。


注意:
阻止浏览器的默认行为:event.preventDefault()
阻止事件冒泡:event.stopPropagation()
一些事件属性,event.target 表示事件触发源等细节。

自定义事件与触发:
使用createEvent(参数分别为Events,MouseEvents,UIEvents) 与 initEvent 系列函数,(initMouseEvent ,initUIEvent),使用dispatchEvent 来程序触发事件,注意模拟事件的相应属性在对应的init函数中指定。
例如模拟触发el上的click事件:

 

var c=document.createEvent("MouseEvents");
//参数一定要和文档一致
c.initMouseEvent("click",true,true,window,1,1,1,1,1,true,
true,true,true,1,null);
el.dispatchEvent(c);
 


IE 事件模型:
注册事件:
使用attachEvent和detachEvent两个函数,例如

 

window.attachEvent(‘onload’,function(){…});
document.body.attachEvent(‘onkeypress’,myKeyHandler); 

 

与W3C的区别是没有第三个参数,而且第一个表示事件类型的参数也必须把’on’给加上。IE 事件模型只支持Bubbling不支持Capturing;在事件处理器的function 内部this等于 window 全局对象。要想得到event对象必须通过window.event方式。


注意:

阻止浏览器的默认行为: window.event.returnValue=false
阻止事件冒泡: window.event.cancelBubble=true
一些事件属性,event.srcElement 表示事件触发源等细节。

自定义事件与触发:
使用 createEventObject 与 fireEvent 触发,注意模拟事件的属性通过eventObject直接添加,
例如模拟click事件:

 

var evt = document.createEventObject();
el.data="data";
el.fireEvent("onclick",evt);

 

同样事件要以on为前缀。

 

20110427 note :

 

ie9 对于 mousemove 自定义事件的触发有 bug ,无论是 createEventObject 还是 createEvent 对于 clientX,clientY 的理解都有误。

你可能感兴趣的:(html,浏览器,IE,Google,webkit)