DOM
DOM:
DOM树 浏览器在渲染页面的时候 会先形成树状结构 就叫做DOM树
DOM由节点组成的
获取节点
获取节点: css选择器: css中选择器怎么写 这里就怎么写 id class tag 父子 层级 交叉...
ie8+ 静态
获取符合选择器的第一个元素: document/父元素.querySelector('css选择器')
var div = document.querySelector('div'); console.log(div); // 直接获取到第一个div var ul = document.querySelector('ul'); console.log(ul);
获取所有符合选择器的元素: 节点的集合: document/父元素.querySelectorAll('css选择器');
var lis = ul.querySelectorAll('li'); console.log(lis); // NodeList 节点列表 var boxa = ul.querySelector('.box.a'); console.log(boxa);
获取子节点
父元素.children 标准: 标签节点 常用
父元素.childNodes 标准: 标签节点+文本节点+注释+...
// 1. 获取ul var ul = document.querySelector('ul'); console.log(ul); /* 获取子节点: 父元素.children 标准: 标签节点 常用 父元素.childNodes 标准: 标签节点+文本节点+注释+... */ console.log(ul.children); console.log(ul.childNodes);
节点属性:
\1. 节点名称: 节点.nodeName 标签名大写
\2. 节点类型: 节点.nodeType 1-12 1--标签 2---属性 3---文本 8--注释 9--document
\3. 节点内容: 节点.nodeValue 只有文本节点(text)才有内容
var cls = ul.childNodes; for(var i = 0; i < cls.length; i++){ // console.log(cls[i], cls[i].nodeName, cls[i].nodeType, cls[i].nodeValue); // 获取标签的内容 if(cls[i].nodeType == 1){ console.log(cls[i].childNodes[0].nodeValue); console.log(cls[i].innerHTML); } }
获取父节点
直接父节点: 节点.parentNode
定位父节点: 节点.offsetParent
如果没有定位父节点 获取到的是body
// 1. 获取box var box = document.querySelector('.box'); console.log(box); /* 直接父节点: 节点.parentNode 定位父节点: 节点.offsetParent 如果没有定位父节点 获取到的是body */ console.log(box.parentNode); console.log(box.offsetParent);
查找兄弟节点
获取上一个兄弟节点:
标准: 节点.previousElementSibling
ie: undefined 标准: 专门提供在标准浏览器中获取上一个兄弟节点
ie: 节点.previousSibling
ie8-: 可以获取到上一个兄弟节点 标准: 换行文本节点
两个值中二选一的时候可以选择用逻辑或短路 将可能出现undefined 的这一项放在前面
兼容: 节点.previousElementSibling || 节点.previousSibling
// 1. 获取box var box = document.querySelector('.box'); console.log(box); console.log(box.previousElementSibling, box.previousSibling); console.log(box.previousElementSibling || box.previousSibling);
获取下一个兄弟节点:
标准: 节点.nextElementSibling
ie: undefined 标准: 专门提供在标准浏览器中获取上一个兄弟节点
ie: 节点.nextSibling
ie8-: 可以获取到上一个兄弟节点 标准: 换行文本节点
两个值中二选一的时候可以选择用逻辑或短路 将可能出现undefined 的这一项放在前面
兼容: 节点.nextElementSibling || 节点.nextSibling
console.log(box.nextElementSibling, box.nextSibling); console.log(box.nextElementSibling || box.nextSibling);
获取首个子节点:
ie: firstChild
标准: firstElementChild
兼容: 节点.firstElementChild || 节点.firstChild
// 获取父节点 var ul = document.querySelector('ul'); console.log(ul); /* 获取首个子节点: ie: firstChild 标准: firstElementChild 兼容: 节点.firstElementChild || 节点.firstChild */ console.log(ul.firstChild, ul.firstElementChild); console.log(ul.firstElementChild || ul.firstChild);
获取末位子节点:
ie: lastChild
标准: lastElementChild
兼容: 节点.lastElementChild || 节点.lastChild
console.log(ul.lastElementChild || ul.lastChild);
创建节点
1.1 创建标签节点: var 变量 = document.createElement('标签名');
1.2 创建文本节点: var 变量 = document.createTextNode('内容');
1.3 将文本节点添加到标签节点中: 父节点.appendChild(子节点);
创建节点为了解决innerHTML重新赋值会覆盖原来所有元素的问题
为了简化过程, 常用innerHTML代替 1.2 1.3
// 1. 创建节点: // 1.1 创建标签节点: var 变量 = document.createElement('标签名'); var li = document.createElement('li'); console.log(li); // // 1.2 创建文本节点: var 变量 = document.createTextNode('内容'); // var txt = document.createTextNode('这是新的li'); // console.log(txt); // // 1.3 将文本节点添加到标签节点中: 父节点.appendChild(子节点); // li.appendChild(txt); // console.log(li); // 创建节点为了解决innerHTML重新赋值会覆盖原来所有元素的问题 // 为了简化过程, 常用innerHTML代替 1.2 1.3 li.innerHTML = '这是新的li'; console.log(li);
追加节点
追加到父元素的末位:
父节点.appendChild(子节点);
var ul = document.querySelector('ul'); console.log(ul); ul.appendChild(li);
追加到某个节点之前:
父节点.insertBefore(新节点, 参考节点);
var li1 = document.createElement('li'); li1.innerHTML = '新的li1'; ul.insertBefore(li1, ul.children[0]); var li2 = document.createElement('li'); li2.innerHTML = '新的li2'; ul.insertBefore(li2, ul.children[0]);
删除节点
-
删除自己: 节点.remove(); ie8+
-
删除子节点: 父节点.removeChild(子节点) 会把被删除的元素返回回来
// 1. 删除自己: 节点.remove(); ie8+ // 点击div 删除整个ul var div = document.querySelector('div'); var ul = document.querySelector('ul'); div.onclick = function () { ul.remove(); } // 2. 删除子节点: 父节点.removeChild(子节点) 会把被删除的元素返回回来 // 点击btn 删除整行li var btns = document.querySelectorAll('button'); console.log(btns); for(var i = 0; i < btns.length; i++){ btns[i].onclick = function () { // 通过按钮 找到整个 li li是btn的直接父元素 console.log(this.parentNode); var a = ul.removeChild(this.parentNode); console.log(a); } }
克隆节点
节点.cloneNode(布尔);
true: 克隆节点中的内容
false/不传: 不克隆节点中的内容
var nli = this.cloneNode(true); console.log(nli); // 追加到ul中 ul.appendChild(nli);
替换节点:
父节点.replaceChild(新节点, 参考节点);
var box = document.querySelector('.box'); console.log(box); var li = document.createElement('li'); li.innerHTML = '新内容'; var ul = document.querySelector('ul'); ul.replaceChild(li, box);
操作属性
\1. 获取: var 变量 = 元素.属性名; var 变量 = 元素['属性名'];
\2. 设置: 元素.属性名 = 值; 元素['属性名'] = 值; 设置布尔值 读取到的就是布尔
[]里直接写属性名需要加引号 如果是变量不加引号
问题: 获取属性: 不能获取直接写在标签上的自定义属性 设置属性: 通过js设置的自定义属性在标签上看不到, 可以正常获取和设置操作所有属性, class直接使用
\3. 获取: 节点.getAttribute('属性名');
\4. 设置: 节点.setAttribute('属性名', '属性值');
所有的值都是字符串 设置后面的属性会覆盖前面
\5. 移除:
节点.属性名 = null/'';
节点.removeAttribute('属性名');
一般操作属性都可以直接使用以上方式, 如果只设置属性名就起作用的属性(checked\selected\loop\muted..)用点和[]
/* 操作属性: 1. 获取: var 变量 = 元素.属性名; var 变量 = 元素['属性名']; 2. 设置: 元素.属性名 = 值; 元素['属性名'] = 值; 设置布尔值 读取到的就是布尔 []里直接写属性名需要加引号 如果是变量不加引号 问题: 获取属性: 不能获取直接写在标签上的自定义属性 设置属性: 通过js设置的自定义属性在标签上看不到, 可以正常获取和设置 */ var div = document.querySelector('div'); console.log(div.id); console.log(div.className); console.log(div.tag); // undefined console.log(div['tag']); // undefined div.ttt = '1234'; /* 操作所有属性, class直接使用 3. 获取: 节点.getAttribute('属性名'); 4. 设置: 节点.setAttribute('属性名', '属性值'); 所有的值都是字符串 设置后面的属性会覆盖前面 5. 移除: 节点.属性名 = null/''; 节点.removeAttribute('属性名'); 一般操作属性都可以直接使用以上方式, 如果只设置属性名就起作用的属性(checked\selected\loop\muted\..)用点和[] */ console.log(div.getAttribute('class')); console.log(div.getAttribute('tag')); // abc123 div.setAttribute('txt', '123123'); div.setAttribute('tnt', true); div.setAttribute('class', 'wrap a b'); div.id = ''; div.removeAttribute('id');
快速获取表格
// 表格 var table = document.querySelector('table'); console.log(table); // 表格是由行组成, 行是由单元格, 表格不能直接获取单元格 console.log(table.tHead); // 表格头 console.log(table.tFoot); // 表格脚 console.log(table.tBodies); // 表格体 --> 集合 console.log(table.tBodies[0]); // 第一个表格体 console.log(table.rows); // 表格中所有的行 头体脚 集合 console.log(table.tBodies[0].rows); // 第一个表格体所有的行 console.log(table.cells); // undefined console.log(table.rows[0].cells); // 获取表格中第一个行的所有的单元格 console.log(table.tBodies[0].rows[0].cells);
快速获取表单
快速获取表单元素: form.name值
/* 1. 获取表单form */ var form = document.querySelector('form'); console.log(form); // 快速获取表单元素: form.name值 console.log(form.user); console.log(form.pass); console.log(form.sex); console.log(form.sex.value); // 当前单选按钮所选中得项 console.log(form.hobby); // 复选框由于有多个选中的项 所以不能直接通过value获取
表单事件
form表单的事件:
提交: form元素.onsubmit = 函数;
重置: form元素.onreset = 函数;
在函数中默认返回值都是 return true;
return false: 禁止提交/重置
如果你不想表单发生重置或者提交的时候 在函数中设置return false;
form.onsubmit = function () { console.log('是否提交'); // return true; return false; }; form.onreset = function () { console.log('是否重置'); // return true; return false; };
表单元素事件
输入框(常见):
onblur: 失去焦点
onfocus: 聚集焦点
onchange: 失去焦点且内容发生改变
边输入边触发: oninput(标准)/onpropertychange(ie8)
搜索提示\密码等级校验...
不建议单独使用, 一般需要结合防抖和节流来进行使用, 避免事件的频繁触发
form.user.onfocus = function () { this.style.background = 'orange'; }; form.user.onblur = function () { this.style.background = 'skyblue'; }; form.pass.onchange = function () { this.style.background = 'red'; }; // 事件可以连等 form.pass.oninput = form.onpropertychange = function () { console.log(this.value); };