DOM(文档对象模型)
- 文档:一个页面就是一个文档,DOM中用 document 表示
- 元素:页面中的所有标签都是元素,DOM中用 element 表示
- 节点:网页中所有内容都是节点(标签、属性、文本、注释等),DOM中用 node 表示
获取元素
(1)根据 ID 获取
-
document.getElementById('元素id名'),获取带有 ID 的元素对象 -
使用
console.dir(),可以打印我们获取的元素对象,查看对象里面的属性和方法var div = document.getElementById('box'); console.dir(div);
(2)根据标签名获取
-
document.getElementsByTagName('标签名'),返回带有指定标签名的对象的集合,以伪数组形式存储- 得到的是一个对象的集合,要想操作里面元素就要遍历
- 得到的元素对象是动态的
- 如果获取不到元素,就返回空的伪数组
-
element.getElementsByTagName('标签名'),获取某个元素内部所有指定标签名的子元素-
父元素必须的单个对象(指明是哪个元素对象),获取的时候不包括父元素
var lis = document.getElementsByTagName('li'); var ol = document.getElementsById('ol'); console.log(ol.getElementsByTagName('li')); // 打印 ol 下的 li 元素
-
(3)通过H5新增方法获取
-
document.getElementsByClassName('类名'),根据类名返回元素对象集合var div = document.getElementsByClassName('box'); -
document.querySelector('选择器'),根据指定选择器* 返回第一个元素对象*var div = document.querySelector('#nav'); -
document.querySelectorAll('选择器'),根据指定选择器返回所有元素对象集合var div = document.querySelectorAll('li'); -
注意:第二个、第三个方法里的选择符需要加符号,如 #nav、.box
(4)特殊元素获取
-
document.documentElement,获取 html 元素对象 -
document.body,获取 body 元素对象 -
document.head -
document.title,获取页面的标题,也可以修改标题var htmlEle = document.documentElement; var bodyEle = document.body; var headEle = document.head; var titleEle = document.title;
操作元素
(1)改变元素内容
element.innerText,从起始位置到结束位置的内容,会去除 html 标签,空格和换行也会去掉。 非标准element.innerHTML,从起始位置到结束位置的内容,包括 html 标签,保留空格和换行。 W3C标准
(2)常用元素属性操作
-
element.src,src可以换成 href、id、alt、titleimg.src = './bg2.png'; // 修改图片路径 img.title = '背景2'; // 修改鼠标悬停显示的结果
(3)表单元素属性操作
-
type、value、checked、selected、disabled
btn.disabled = true; // 表示按钮被禁用 input.value = 'clicked'; // 修改 input 里的文字内容
(4)样式属性操作
-
element.style,行内样式操作div.style.backgroundColor = 'skyblue'; -
element.className,类名样式操作div.className = 'div' -
注意:
- JS 里的样式采取驼峰命名法,如 fontSize、backgroundColor
- JS 修改 style样式操作,产生的是行内样式,CSS权重高,为 1000
排他思想(算法)
-
1、所有元素全部清除样式
-
2、给当前元素设置样式
var btns = document.getElementByTagName('button'); // btns 得到的是伪数组,里面的每一个元素 btns[i] for(var i = 0; i < btns.length; i++){ // (1) 先把所有按钮背景颜色去掉 btns[i].onclick = function(){ for(var i = 0; i < btns.length; i++){ btns[i].style.backgroundColor = ''; } // (2) 再让背景颜色为 skyblue this.style.backgroundColor = 'skyblue'; } }
自定义属性操作
(1)获取元素
-
①
element.属性console.log(div.id); -
②
element.getAttribute('属性'),程序员之间添加的属性,如 indexconsole.log(div.getAttribute('id')); console.log(div.getAttribute('index'));
(2)设置元素属性值
-
①
element.属性 = '值'div.id = 'test'; div.className = 'navs'; -
②
element.setAttribute('属性','值'),主要针对自定义属性div.setAttribute('index',2); div.setAttribute('class','footer'); // class 特殊
(3)移除属性
-
removeAttribute(属性)div.removeAttribute('index');
H5自定义属性
-
H5 新增获取自定义属性的方法,只能获取 data- 开头的,ie11 以上使用
-
dataset 是一个集合,里面存放了所有以 data 开头的自定义属性
console.log(div.dataset); console.log(div.dataset.index); console.log(div.dataset['index']); -
如果自定义属性里面有多个 - 相连的单词,获取时要采取驼峰命名法
console.log(div.dataset.listName); // 在 div 中是 data-list-name console.log(div.dataset['listName']);
节点概述
- 节点至少拥有 nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)
- 元素节点 nodeType 为 1,属性节点 nodeType 为 2,文本节点 nodeType 为 3(文本节点包括文字、空格、换行等)
- 实际开发中,节点操作主要操作的是 元素节点
(1)节点操作之父节点
-
element.parentNode,得到的是里元素最近的父节点,找不到父节点就返回 nullconsole.log(div.parentNode);
(2)节点操作之子节点
-
①
element.childNodes,获取所有的子节点,包括 元素节点、文本节点等console.log(ul.childNodes); -
②
element.children,获取所有的子元素节点,实际开发使用的console.log(ul.children); -
③
element.firstChild,获取第一个子节点,包括 元素节点、文本节点等console.log(ul.firstChild); console.log(ul.lastChild); // 获取最后一个子节点 -
④
element.firstElementChild,获取第一个子元素节点console.log(ul.firstElementChild); console.log(ul.lastElementChild); // 有兼容性问题:ie9 以上支持 // 实际开发写法,既没有兼容性问题又返回第一个子元素 console.log(ol.children[ol.children[0]); console.log(ol.children[ol.chileren.length-1]); // 最后一个子元素
(3)节点操作之兄弟节点
-
①
element.nextSibling,下一个兄弟节点,包含元素节点、文本节点等console.log(ul.nextSibling); console.log(ul.previousSibling); // 上一个兄弟节点 -
②
element.nextElementSibling,下一个兄弟元素节点console.log(ul.nextElementSibling); console.log(ul.previousElementSibling); // 上一个兄弟元素节点
(4)节点操作创建和添加节点
-
①
document.createElement,创建元素节点var li = document.createElement('li'); -
②
node.appendChild(child),将一个节点添加到指定父节点的子节点列表末尾var li = document.createElement('li'); ul.appendChild(li); -
③
node.insertBefore(child,指定元素),将一个节点添加到父节点的指定子节点前面var lili = document.createElement('li'); ul.insertBefore(lili, ul.childeren[0]);
(5)节点操作之删除节点
-
node.removeChild(child),删除父节点下的一个子节点,返回删除的节点ul.removeChild(ul.children[0]);
(6)节点操作之克隆节点
-
node.conleNode(参数)- 参数为空 或 false,则是浅拷贝,即只复制标签,不复制里面的内容
- 参数为 true,则是深拷贝,复制所有内容
事件
事件基础
-
事件三要素,由下面三部分组成
- 事件源:绑定事件的页面元素
- 事件类型:触发的什么事件
- 事件处理程序(函数):事件触发后要执行的函数
-
执行事件步骤
-
获取事件源
-
注册事件(绑定事件)
-
语法: 页面元素.on+事件类型 = 函数
btn.onclick = function () {}
-
-
添加事件处理程序(采取函数赋值形式)
-
注册事件
-
(1)传统注册事件
btn.onclick = function () { }- function 叫监听器
- 特点:注册事件的唯一性,同一元素同一事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
-
(2)方法监听注册事件
btn.addEventListener('click', function () { })- 里面的事件类型是字符串,必须加引号,且不带 on
- 同一元素同一事件可以添加多个监听器(事件处理程序)
删除事件
-
(1)传统方式删除
div.onclick = function () { console.log(110); // 在点击之后就会将该事件删除 btn.onclick = null; } -
(2)removeEventListener 删除事件
div.addEventListener('click', fn); // fn b function fn(){ console.log(110); // 在点击之后就会将该事件删除 btn.removeEventListener('click', fn); }
DOM事件流三个阶段
-
捕获阶段、当前目标阶段、冒泡阶段
-
JS 代码中只能执行捕获或冒泡其中一个阶段,onclick 只能得到冒泡阶段
-
addEventListener 第三个参数为 true,处于捕获阶段,document -> html -> body -> father -> son
<div class="father"> <div class="son">子盒子</div> </div> <script> var son = document.querySelector('.son'); son.addEventListener('click', function () { alert('son'); }); var father = document.querySelector('.father'); father.addEventListener('click', function () { alert('father'); }); // 先弹出 father,再弹出 son </script> -
addEventListener 第三个参数为 false 或 省略,处于冒泡阶段,son-> father -> body -> html -> document
<div class="father"> <div class="son">子盒子</div> </div> <script> var son = document.querySelector('.son'); son.addEventListener('click', function () { alert('son'); }, false); var father = document.querySelector('.father'); father.addEventListener('click', function () { alert('father'); }, false); // 先弹出 son,再弹出 father </script>
事件对象
-
event 就是一个事件对象,写到监听函数的小括号里,当形参来看
-
事件对象只有事件存在才会存在
-
(1)
e.target,返回的是触发事件的对象ul.addEventListener('click', function (e) { // e.target 返回的是触发事件的对象(元素) console.log(e.target); // 点击 li,e.target 就指向 li // this 哪个元素绑定了这个事件,就返回谁 console.log(this); // 给 ul 绑定了事件,this 就指向 ul }) -
(2)
e.type,返回事件类型div.addEventListener('mouseover', function (e) { console.log(e.type); // mouseover }) -
(3)
e.preventDefault(),阻止默认行为(事件),让链接不跳转 或 让提交按钮不提交a.addEventListener('click', function (e) { e.preventDefault(); // DOM 标准写法 }) -
(4)
e.stopPropagation()阻止事件冒泡<div class="father"> <div class="son">子盒子</div> </div> <script> var son = document.querySelector('.son'); son.addEventListener('click', function (e) { alert('son'); e.stopPropagation(); // DOM 标准 e.cancelBubble = true; // 非标准 }, false); var father = document.querySelector('.father'); father.addEventListener('click', function () { alert('father'); }, false); // 点击 son 就只弹出 son,因为停止冒泡了 </script>
事件委托
-
核心原理:给父节点添加监听器,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { e.target.style.backgroundColor = 'skyblue'; })
鼠标事件
-
(1)
contextmenu,禁用右键菜单document.addEventListener('contextmenu', function (e) { e.preventDeafult(); }) -
(2)
selectstart,禁止选中文字document.addEventListener('selectstart', function (e) { e.preventDefault(); })
鼠标事件对象 MouseEvent
document.addEventListener('click', function (e) {
// 1、client,鼠标在可视区的 x 和 y 坐标,与 页面滚动无关
console.log(e.clientX);
console.log(e.clientY);
// 2、page,鼠标在页面文档的 x 和 y 坐标
console.log(e.pageX);
console.log(e.pageY);
// 3、screen,鼠标在电脑屏幕的 x 和 y 坐标
console.log(e.screenX);
console.log(e.screenY);
})
键盘事件
-
(1)
keyup,按键弹起时触发document.addEventListener('keyup', function () { console.log('弹起'); }) -
(2)
keydown,按键按下时触发,能识别功能键,如 ctrl、shift、左右箭头document.addEventListener('keydown', function () { console.log('我按下了down'); }) -
(3)
keypress,按键按下时触发,不能识别功能键document.addEventListener('keypress', function () { console.log('我按下了press'); }) -
执行顺序: keydown 、keypress 、keyup
键盘事件对象 KeyBoardEvent
-
keyCode,得到相应键的ASCII码值document.addEventListener('keyup', function () { console.log(e.keyCode); }) -
keyup和keypress事件不区分字母大小写,a 和 A 得到的都是 65 -
keypress事件区分字母大小写