element.setAttribute(attributename,attributevalue) 两个参数都是string类型的
可以使用这个方法为指定的元素增加特定的属性并且赋指定的值(1在创建新的元素的时候为(自有)属性赋值 2 设置样式class )
var test = document.getElementById("test"); test.setAttribute("class","a"); test.setAttribute("class","b");
上面的只会应用到样式b 当设置的样式存在值的时候,setAttribute是修改的操作
element.getAttribute(attributename) 参数 字符串 属性名 返回值 字符串 相应属性的值 不存在相应的属性值 返回null
结合上面的两个方法 简单的实现了一个为元素添加样式的函数
function addClass(element,classValue) { var oldClass = element.getAttribute("class"); var newClass = null; if(oldClass !== null) { //不为空的时候 将返回的string类型值转换成数组 判断新添加的样式是否存在后在进行添加 var oldClassNums = oldClass.split(" "); var length = oldClassNums.length; for(var i = 0;i < length;i++ ) { if(oldClassNums[i] === classValue) { //indexOf判断 return; } } newClass = oldClassNums + " " + classValue; element.setAttribute("class",newClass); } else { element.setAttribute("class",classValue); //如果元素之前的样式为空 直接设置值 } } var test = document.getElementById("test"); addClass(test,"a"); addClass(test,"a"); addClass(test,"b");
2016.3.13 也可以通过element.className 属性获取元素class的值进行读取或者更新 实现方式如上
通过控制台查看 发现实现了我们的功能
nodeType
元素节点的nodeType为1 属性节点的nodeType为2 文本节点的nodeType为3
在不同的节点类型下 可以通过nodeName nodeValue 获取节点的一些属性
节点类型 | nodeName | nodeValue |
1(element) | 元素名 | null |
2(attr) | 属性名 | 属性值 |
3(text) | #text | 节点的内容 |
举一个获取属性节点的例子
<p id="a" name="haha">ssss</p> <script type="text/javascript"> var attrNode = document.getElementById('a').getAttributeNode('name'); console.log(attrNode.nodeType);//2 console.log(attrNode.nodeValue);//haha console.log(attrNode.nodeName);//name </script>
textNode.textContent 获取文本节点的内容 但在元素节点上使用textContent textContent属性会设置或者返回指定节点的文本内容以及它的所有后代
这个属性会返回节点的所有子节点的文本内容 并且在节点上设置textContent属性的时候 ,会删除所有的子节点替换为一个包含指定字符串的文本节点
target.appendChild() 在指定节点的最后一个子节点之后插入节点
insertBefore(newItem,selectItem) 在指定的子节点之前插入子节点 newItem 新插入的节点 selectItem(该节点不存在父节点中 无法完成插入) 指定的子节点
可以结合上面的两个方法 实现insertAfter(newItem,selectItem)
function insertAfter(newItem,selectItem) { selectItem.nextSibling ? selectItem.parentNode.insertBefore(newItem,selectItem.nextSibling) : selectItem.parentNode.appendChild(); }
removeChild(target) 从父元素中删除指定的子元素
replaceChild(newNode,oldNode) 用新的节点去替换元素中以后的子节点 (新节点也可以是父元素中存在的节点)
querySelector(css selectors) 返回匹配指定选择器的的第一个元素
集体的例子请看 HTML DOM querySelector 特别是其中关于两个选择器的部分
documennt.getElementById(id) 通过元素的id返回相应的元素
document.getElementByTagName(tag) 返回带有指定标签的对象名的集合(返回的这个集合并不是数组 而是NodeLIst)
nodelist的特点是时效性 也就是我们每次去使用这个nodelist的时候,它都是从页面中动态的变化的
<div id="test"> <p>sssss</p> </div> <script type="text/javascript"> var container = document.getElementById('test'); var list = document.getElementsByTagName('p'); console.log(list.length); //1 var textNode = document.createTextNode("aaa"); var ele = document.createElement('p'); ele.appendChild(textNode); container.appendChild(ele); console.log(list.length);//2
这样在重复使用这个取到的值的时候,就会不断的查找dom节点 会对性能产生影响 可以将这个nodelist转换成array
function convert(list) { var ret = []; var legnth = list.length; for(var i = 0;i < length;i++) { ret.push(list[i]); } return ret; }
/2016 3,7 刚看自己之前的blog 发现了这个 Array.prototype.slice 这个方法能把具有长度的类数组转换成数组/
例子
var num_like = {
length:2,
0:1,
1:2
}
var test = Array.prototype.slice.call(num_like);
console.log(test); //[1,2]
上面我对num_like的两个属性加了粗体 当属性之前不是连续的时候 是无法生成想要的结果的
var num_like = {
length:2,
0:1,
5:2
}
var test = Array.prototype.slice.call(num_like);
console.log(test);//[1]
document.getElementsByName() 返回带有指定名称的对象的集合(也是nodelist集合)
document.getElementsByClassName(classname) 返回文档中所有指定类名的集合(也是nodelist集合)
var aa = document.getElementsByClassName("test bb");//可以获取这种两个类名的
parentNode parentElement 这两个方法都用于获取元素的父对象 但还是存在一定的差别 (关于兼容性 parentNode parentElement 在chrome 47 中都可以运行)
parentNode用于获取文档层次的父对象 parentElement用于获取对象层次的父对象
var test = document.body.parentNode.parentNode; console.log(test); //#document var bb = document.body.parentNode.parentElement; console.log(bb);//null
也就是parentNode匹配父元素为node的 而parentElement匹配父元素为element的 上面的#document的nodeType为9 所以使用parentElement返回为null (node包含element)
children childNodes 用于获取元素的的子元素 也存在一定的差别
children 会获取指定对象直接后代html对象集合
childrenNodes 会获取指定对象直接后代的html对象集合和TextNode集合(ndoeList)
<ul> <li>111</li> <li>222</li> </ul> <script type="text/javascript"> var ul = document.getElementsByTagName('ul')[0]; var children = ul.children; console.log(children[0]); //第一个li var childNodes = ul.childNodes; console.log(childNodes[0]); //#text </script>
在上面的文档结构中ul跟第一个之间是存在空白的 也就是会有一个空白的textNode 所以使用childNodes选取第一个子元素的时候是textNode节点 使用children的时候才能正确的获取第一个元素 结合nodeType 和childNodes 可以实现children的效果
nextSibling(返回node) nextElementSibling(返回element) 都用于返回指定元素的之后紧跟的节点 他们的区分跟parentNode 和parentElement很相似
<ul> <li>111</li> <li id="last">222</li> </ul> <script type="text/javascript"> var li_last = document.getElementById('last'); var aa = li_last.nextSibling; console.log(aa); //#text var bb = li_last.nextElementSibling; console.log(bb); //null </script>
还是上面的页面结构 由于最后一个li跟ul之间存在空白 也就是存在一个textNode 通过nextSibling 会获取这个文本节点 通过nextElementSibling 返回null
previouSibling(node) previousElementSibling(element)
<ul> <li id="first">111</li> <li>222</li> </ul> <script type="text/javascript"> var li_first = document.getElementById('first'); var aa = li_first.previousSibling; console.log(aa); //#text var bb = li_first.previousElementSibling; console.log(bb);//null </script>
element.cloneNode(true/false) 创建节点的拷贝并返回该副本 true的时候 会复制后代 false的时候不会复制后代
<button id="btn" name="btn">test btn</button> <script type="text/javascript"> var btn = document.getElementById('btn'); btn.addEventListener('click',function(){console.log(1);}) var btn_new = btn.cloneNode(true); document.body.replaceChild(btn_new,btn); </script>
上面的例子在id为btn的button上绑定了匿名函数 由于外界不存在对这个函数的引用 是无法通过正常的removeEventListener去移除绑定的这个事件的 此时我们可以通过对这个元素进行clone 在clone的时候不会进行事件的拷贝 也就达到了移除绑定的匿名函数的目的了 (也就是通过cloneNode的方法实现了removeAllEventListeners的方式) 在cloneNode(tag) tag设置为true的时候,子元素绑定的事件也会被移除
document.createElement() 创建元素节点
document.createTextNode() 创建文本节点
document.creatAttribute() 创建属性节点
上面的例子中为p元素设置了属性节点
document.createDocumentFragment() 这个方法会创建一个虚拟的节点对象 使用这个方法可以更加安全的对文档进行操作并且当需要大量的对页面进行插入操作的时候,每次更改都会导致页面的重绘,通过文档碎片可以提高性能
在将文档碎片插入到页面中的时候,是将文档碎片的子节点插入到页面中