你所不了解的javascript操作DOM的细节知识点

一:Node类型DOM1级定义了一个Node接口,该接口是由DOM中的所有节点类型实现。每个节点都有一个nodeType属性,用于表明节点的类型,节点类型在Node类型中有以下几种:Node.ELEMENT_NODE(1);元素节点Node.ATTRIBUTE_NODE(2);属性节点Node.TEXT_NODE(3);文本节点Node.DOCUMENT_NODE(9);文档节点其实还有很多种,但是那些都不是很常用,所以就来理解这其中4种就可以了,我们先来看看节点类型,比如如下代码:HTML代码如下:

JS代码如下:var list = document.getElementById("list");var arrs = [];for(var i = 0, ilen = list.childNodes.length; i < ilen; i++) {var curElement = list.childNodes[i];if(curElement.nodeType === 1){arrs.push(curElement);}}console.log(arrs); console.log(arrs.length); // 3如上代码在所有的浏览器都支持,通过判断该元素是不是元素节点,然后在执行后续操作;不是元素节点都会过滤掉,因此返回的长度都为3;理解Text类型Text节点具有以下特征:nodeType的值为3;nodeName的值为”#text”;nodeValue的值为节点所包含的文本;parentNode是一个Element;没有子节点;创建文本节点;可以使用document.createTextNode()创建新文本节点,这个方法需要一个参数,即要插入的文本,如下代码:var element = document.createElement("div");var text = document.createTextNode("aa");element.appendChild(text); document.body.appendChild(element);2. 分割文本节点splitText(offset);从offset指定的位置将当前的文本节点分成2个文本节点;如下代码:var element = document.createElement("div");var text = document.createTextNode("aabbbccc");element.appendChild(text);document.body.appendChild(element);var newNode = element.firstChild.splitText(5);console.log(element.firstChild.nodeValue); // aabbbconsole.log(newNode.nodeValue); // ccc console.log(element.childNodes.length); // 2浏览器支持的程度有IE,firefox,chrome都支持;理解DOM操作—动态插入脚本我们动态插入JS脚本,常见的写法有如下代码即可插入:var script = document.createElement("script");script.type ="text/javascript";script.src = 'a.js';document.body.appendChild(script);即可在body最后面动态插如a.js,此动态插入不会堵塞浏览器加载;我们为了更加扩张性,我们也可以封装一个函数,如下代码:function loadScript(url) {var script = document.createElement("script");script.type = "text/javascript";script.src = url;document.body.appendChild(script);}loadScript("a.js");当页面有多个js需要动态插入的话,可以依次调用loadScript函数即可;但是假如我们现在有这么一个需求,动态加载JS完后,我想在这后面做点事情,我们都知道,动态加载也可以理解为异步加载,不会堵塞浏览器,但是我们需要如何知道动态JS已经加载完了呢?我们之前讲过一篇文章是 “Javascript事件总结”中有判断JS动态加载完后使用load事件来监听js是否动态加载完,现在我们再来复习下load事件;Javascript中最常用的一个事件是load,当页面加载完后(包括所有的图片,javascript文件,css文件等外部资源)。就会触发window上面的load事件;目前可以有2种触发load事件,一种是直接放在body上面触发;比如如下代码:第二种是通过JS来触发,如下代码:EventUtil.addHandler(window,’load’,function(event){alert(1);});上面的EventUtil.addHandler 是我们之前在javascript事件总结中封装的JS函数,现在我们直接拿过来使用,如下代码:var EventUtil = {addHandler: function(element,type,handler) {if(element.addEventListener) {element.addEventListener(type,handler,false);}else if(element.attachEvent) {element.attachEvent("on"+type,handler);}else {element["on" +type] = handler;}},removeHandler: function(element,type,handler){if(element.removeEventListener) {element.removeEventListener(type,handler,false);}else if(element.detachEvent) {element.detachEvent("on"+type,handler);}else {element["on" +type] = null;}},getEvent: function(event) {return event ? event : window.event;},getTarget: function(event) {return event.target || event.srcElement;},preventDefault: function(event){if(event.preventDefault) {event.preventDefault();}else {event.returnValue = false;}},stopPropagation: function(event) {if(event.stopPropagation) {event.stopPropagation();}else {event.cancelBubble = true;}}};下面我们来看看如何使用JS事件来判断JS是否加载完成的代码,我们可以使用load事件来监听,如下代码:EventUtil.addHandler(window,'load',function(){var script = document.createElement("script");EventUtil.addHandler(script,'load',function(event){console.log(script.src);});script.src = 'a.js';document.body.appendChild(script);});如上代码,script元素也会触发load事件,以便可以确定动态加载jS是否加载完成,上面的代码指定src属性和指定的事件处理程序的事件可以调换位置,先后顺序不重要,如上代码,我们也可以这样写,如下代码:EventUtil.addHandler(window,'load',function(){var script = document.createElement("script");script.src = 'a.js';document.body.appendChild(script);EventUtil.addHandler(script,'load',function(event){console.log(script.src);}); });目前只有IE9+,Firefox,opera,chrome和safari3+支持,IE8及以下不支持该load事件,因此我们需要针对IE8及以下做处理;理解readystatechange事件IE为DOM文档中的某些部分提供了readystatechange事件,这个事件的目的提供与文档或元素的加载的状态有关信息,此事件提供了下面5个值中的一个;uninitialized(未初始化):对象存在但尚未初始化;loading(正在加载):对象正在加载数据;loaded(加载完毕):对象加载数据完成;interactive(交互):可以操作对象了,但没有完全加载;complete(完成):对象已经加载完成;(在IE和opera)中和(仅IE中)元素也会触发readystatechange事件,可以用来确定外部的javascript和css文件是否已经加载完成,基于元素触发的readystatechange事件,即readyState属性无论等于”loaded”还是”complete”都可以表示资源已经可用;如下针对IE的判断javascript是否已经加载完成的方案:EventUtil.addHandler(window,'load',function(){var script = document.createElement("script");EventUtil.addHandler(script,'readystatechange',function(event){event = EventUtil.getEvent(event);var target = EventUtil.getTarget(event);if (target.readyState == "loaded" || target.readyState == "complete"){EventUtil.removeHandler(target, "readystatechange", arguments. callee);alert(script.src);}});script.src = 'a.js';document.body.appendChild(script); });下面我们可以使用javascript客户端检测技术来判断是否是IE和其他标准浏览器做一个简单的封装;如下代码:var ua = navigator.userAgent.toLowerCase();EventUtil.addHandler(window,'load',function(){var script = document.createElement("script");if(/msie ([^;]+)/.test(ua) || "ActiveXObject" in window) {// IE 浏览器EventUtil.addHandler(script,'readystatechange',function(event){event = EventUtil.getEvent(event);var target = EventUtil.getTarget(event);if (target.readyState == "loaded" || target.readyState == "complete"){EventUtil.removeHandler(target, "readystatechange", arguments. callee);console.log("javascript已经加载完成");}});}else {// 除IE之外的标准浏览器EventUtil.addHandler(script,'load',function(event){console.log("javascript已经加载完成");});}script.src = 'a.js';document.body.appendChild(script);});上面的是针对所有的主要的浏览器进行封装来判断动态加载的JS是否已经加载完成!理解动态加载行内JS方式另一种加载javascript代码的方式是行内方式,如下代码:function sayHi(){alert(1);}从理论来讲,下面的代码应该是有效的;var script = document.createElement('script');script.type = 'text/javascript';script.appendChild(document.createTextNode("function sayHi(){alert(1);} sayHi()"));document.body.appendChild(script);

推荐阅读更多精彩内容