一、自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不保存到数据库中。
自定义属性获得是通过getAttribute('属性')获得,但有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
h5新增了自定义属性:规定自定义属性data-开头作为属性名并赋值。
比如<div data-index='1'></div>
或者通过js设计 element.setAttribute('data-index',2)
获取元素 element.dataset
<body>
<div getTime="20" data-index="2" data-list-name="code"></div>
<script>
var div = document.querySelector('div');
// console.log(div.date-index); //自定义属性不能通过element.属性获取
console.log(div.getAttribute('data-index')); //2 开发多用这种方法
div.setAttribute('data-time',20)
console.log(div.getAttribute('data-time')); //20
// H5新增的获得自定义属性的方法(有兼容性) 只能获取data-开头的属性
//dataset是一个集合里面存放了所有以data开头的自定义属性
console.log(div.dataset); //index: "2" listName: "code" time: "20"
console.log(div.dataset.index); //2
console.log(div.dataset['index']); //2
// 如果自定义属性里面有多个-连接的单词,获取要采用驼峰命名法
console.log(div.dataset.listName); //code
console.log(div.dataset['listName']); //code
</script>
</body>
二、节点操作(元素节点 文本节点 属性节点......)
获取元素可以通过DOM提供的方法:(缺点逻辑性不强)
document.getElementById()
document.getElementsByTagName()
document.querySelector() 等.....
还可以利用节点层级关系获取元素 (缺点兼容性差)
一般的节点至少拥有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)基本属性
元素节点 nodeType 为 1 实际开发中,节点操作主要操作的是元素节点
属性节点 nodeType 为 2
文本节点 nodeType 为 3(文本节点包含 文字、空格、换行....)
节点层次:常见父子兄层级关系
2.1、父级节点 node.parentNode
parentNode属性可返回某节点的父节点,是最近的一个父节点
如果没有指定的节点没有父节点则返回null
<div class="box">
<span class="erweima"></span>
</div>
<script>
var erweima = document.querySelector('.erweima');
console.log(erweima.parentNode);//获取父元素
</script>
2.2 、子节点parentNode.children是一个只读属性,返回所有的子元素节点,它只返回子元素节点
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
var ul = document.querySelector('ul');
console.log(ul.children); //获取全部子元素
parentNode.firstElementChild获取第一个子节。找不到返回null (id9以上才支持)
parentNode.lastElementChild获取第一个子节点 。找不到返回null (id9以上才支持)
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
console.log(ul.firstElementChild) //获取第一个li
console.log(ul.lastElementChild) //获取最后一个li
实际开发的写法 :没有兼容性问题 :
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
console.log(ul.children[0]) //获取第一个li
console.log(ul.Children[ul.children.length]-1) //获取最后一个li
2.3、兄弟节点:(比较少用)
node.nextElementSibling 返回当前元素下一个兄弟节点 找不到返回null
node.previousElementSibling返回当前元素上一个兄弟节点,找不到返回null
<body>
<p>一哥</p>
<div>二哥</div>
<span>三哥</span>
<script>
var div=document.querySelector('div')
console.log(div.nextElementSibling)//<span>三哥</span>
console.log(div.previousElementSibling) // <p>一哥</p>
</script>
</body>
兄弟节点也存在兼容性问题 解决方法:自己封装一个兼容性函数
function getNextElementSibling (element){
var el = element;
while(el = el.nextSibling){
if(el.nodeType ===1){
return el;
}
}
return null;
}
2.4、创建和添加节点 :给页面添加一个新的元素:先创建然后添加
document.createElement创建节点
node.appendChild(child)添加节点 node 父级 child是子级 在后面追加元素
node.insertBefore(child,指定元素) 添加节点
<ul>
<li>2</li>
</ul>
var li = document.createElement('li'); //创建一个li元素
var ul = document.querySelector('ul');
ul.appendChild(li);//添加节点 后面追加
var lili = document.createElement('li');
ul.insertBefore(lili,ul.children[0])//前面追加
留言案例:
<body>
<button>发布</button>
<textarea name="" id="" cols="30" rows="10"></textarea>
<ul>
<li>11</li>
</ul>
<script>
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
btn.onclick = function () {
if (text.value === '') {
alert('请输入你的留言')
} else {
//创建元素
var li = document.createElement('li');
li.innerHTML = text.value;
//添加元素
ul.insertBefore(li, ul.children[0]);
}
}
</script>
</body>
2.5、删除节点:node.removeChild(child)
<body>
<button>删除</button>
<ul>
<li>嘻嘻</li>
<li>憨憨</li>
<li>哈哈</li>
</ul>
<script>
var btn = document.querySelector('button');
var ul = document.querySelector('ul');
btn.onclick = function(){
if(ul.children.length == 0){
this.disabled = true;
}else{
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
</html>
2.6、复制节点(克隆节点)node.cloneNode()
注:如果括号参数为空或为false,则浅拷贝,及克隆复制节点本身,不克隆复制里面的子节点
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
// var lili = ul.children[0].cloneNode()//克隆第一个li ()空值不克隆里面的内容 浅拷贝
var lili = ul.children[0].cloneNode(true)
ul.appendChild(lili);//深拷贝
</script>
</body>
</html>
案例:动态表格
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
var datas = [
{
name: '李虎',
subject: 'math',
score: 96
},
{
name: '李华',
subject: 'math',
score: 98
},
{
name: '张三',
subject: 'math',
score: 95
},
{
name: '李一',
subject: 'math',
score: 92
}
]
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {//根据数组元素个数动态创建行
//创建行
var tr = document.createElement('tr');
//添加行
tbody.appendChild(tr);
for (var k in datas[i]) { //遍历对象,根据对象属性个数创建单元格
//创建单元格
var td = document.createElement('td');
//每行添加单元格个数为遍历对象的属性数
tr.appendChild(td);
//datas[i][k]为当前对象i里面的对象值
td.innerHTML = datas[i][k];
}
//跳出内层循环,独立设计操作中的单元格
var td = document.createElement('td');//创建单元格
tr.appendChild(td);
td.innerHTML = "<a href='javascript:;'>删除</a>";
}
var as = document.querySelectorAll('a')
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
tbody.removeChild(this.parentNode.parentNode);
}
}
</script>