javascript DOM、事件、事件流、节点操作、元素属性(笔记) 文章目录1. 认识DOM2. 获取元素2.1 通过标签名获取2.2 通过ID获取2.3 通过类名获取2.4 H5新增的获取方式2.5 特殊元素的获取3. 事件3.1 事件三要素3.2 事件类型3.3 注册事件3.4 派发事件3.5 删除事件3.6 事件流3.7 鼠标事件对象3.8 键盘事件对象3.9 触摸事件对象3.10 事件委托(事件代理)4. 元素自定义属性4.1 默认的自定义属性4.2 h5新增的自定义属性5. 节点操作5.1 节点类型5.2 节点自身的信息5.3 获取父元素5.4 获取子元素5.5 获取兄弟元素5.6 添加节点对象5.7 删除节点5.8 克隆节点5.9 替换节点5.10 移动节点6. 获取元素属性6.1 偏移量 offset6.2 offset 与 style 区别6.2.1 offset6.2.2 style6.3 元素可视区 client6.4 元素滚动 scroll7. 操作css7.1 类名与ID7.2 行内样式7.3 全部样式1. 认识DOM文档对象模型(Document Object Model)文档一个页面就是一个文档DOM中使用document表示节点页面中的所有内容在文档树中都是节点(标签、属性、文本、注释等)使用node表示标签节点网页中所有的标签通常称为元素节点有简称为元素使用element表示2. 获取元素2.1 通过标签名获取// get方式获取一组元素的都是伪数组// 返回HTMLCollection它是即时更新的当其所包含的文档结构发生改变时它会自动更新。letlisdocument.getElementsByTagName(tag)2.2 通过ID获取// 选择第一个匹配的元素letdivdocument.getElementById(id)2.3 通过类名获取// 也是实时更新letlisdocument.getElementsByClassName(class)2.4 H5新增的获取方式// 选择第一个匹配的元素(css怎么获取它就怎么获取)letdivdocument.querySelector(css选择器)// 选择一组元素(类数组)// 返回NodeList(静态的不会实时更新)它是H5以后新增的可以使用forEach去遍历// 通过这种方式获取的才是静态的但是通过实时更新的父元素点出来的孩子们即使是NodeList也是实时的letdivdocument.querySelectorAll(css选择器)2.5 特殊元素的获取// 获取 html 文档对象document.documentElement// 获取页面 titledocument.title// 获取 head 标签document.head// 获取 body 标签document.body3. 事件3.1 事件三要素事件源(谁要触发事件)触发事件的元素事件类型(触发什么事件)例如 click 点击事件事件处理程序(触发对应事件后要干什么)触发事件后执行的函数3.2 事件类型鼠标事件// 1.鼠标左键按下(点击事件)btn.onclickfunction(){}// 2.鼠标右键点击(在右键菜单显示前触发)contextmenu// 3.鼠标双击事件dblclick// 4.鼠标按下事件mousedown// 5.鼠标抬起事件mouseup// 6.鼠标移入事件mouseover// 7.鼠标移入事件(不冒泡目标元素不冒给自己其他元素的相同事件不会触发自己)mouseenter// 8.鼠标移动触发mousemove// 9.鼠标移出事件mouseout// 10.鼠标移出事件(不冒泡)mouseleave// 11.在鼠标上触发任意按钮触发mouseup// 12.鼠标滚轮事件wheel// 15.文档视图或者一个元素在滚动时触发鼠标键盘都可以scroll表单事件// 1.元素获得焦点focus// 2.元素失去焦点blur// 3.输入事件(每次输入都会触发)input// 4.当用户更改表单并提交时触发change// 5.剪切cut// 6.拷贝copy// 7.粘贴paste键盘事件// 键盘按下keyCode不区分字母大小写keydown// 键盘按下(它不识别功能键 ctrlshift等)keypress// 键盘抬起keyup// 三个事件的执行顺序keydown--keypress--keyup移动端事件// 手指触摸到一个DOM元素时触发(按下)touchstart// 手指在一个DOM元素上滑动时触发touchmove// 手指从一个DOM元素上移开时触发(抬起)touchend全局事件// document开头的事件3.3 注册事件传统注册方式利用 on 开头的事件 onclick注册事件具有唯一性同一个元素设置重复的事件只会执行最后面的事件监听注册方式w3c 标准推荐方式addEventListener() 它是一个方法不需要加 onIE9 之前的IE不支持此方法可以使用attachEvent() 代替需要加 on同一个元素可以注册多个监听器按注册顺序依次执行element.addEventListener(click,funcion,事件流)3.4 派发事件EventTarget.dispatchEvent(event)手动去派发事件可以派发自定义事件也可以派发原有事件(原有事件还可以正常使用)必须要传入一个事件对象可以通过 new Event(事件类型)创造一个自定义事件3.5 删除事件传统方式element.onclick null监听方式element.removeEventListener(“click”,function)兼容性的删除方式detachEvent(“onclick”,function)这里的function必须和添加事件的function是同一个3.6 事件流在触发事件时会经历三个阶段注意事件流是元素父子关系元素嵌套关系而不是层叠关系捕获阶段document—Element html—Element body—Element div目标对象Element div冒泡阶段Element div—Element body—Element html—document注意捕获阶段不会触发事件获取到目标对象后向上冒泡才会触发父元素的事件默认事件为冒泡事件(从内向外)// addEventListener 一共有三个参数element.addEventListener(click,funcion,事件流)// 事件流默认为false为事件冒泡(先执行自己的在执行父元素的)// 如果为true那么就为事件捕获(先执行父元素的在执行自己的)3.7 鼠标事件对象在使用事件方法时可以传入一个参数event(事件对象)event.type返回事件类型event.target返回目标对象event.currentTarget返回注册事件的对象不一定是目标事件可能是冒泡的等同于thisevent.preventDefault()阻止默认事件比如a元素的跳转event.stopPropagation()阻止事件冒泡(都是给目标对象添加)this与event.target的区别this是函数调用者event.target是目标对象(比如给ul添加事件使用this改变样式的话只能改变ul的样式用target的话点哪个li就只改变哪个li)鼠标事件属性说明event.clientX返回鼠标相对于浏览器窗口可视区域的 X 坐标(浏览器窗口)event.clientY返回鼠标相对于浏览器窗口可视区域的 Y 坐标event.pageX返回鼠标相对于文档页面 X 坐标IE9支持(文档内容)event.pageY返回鼠标相对于文档页面 Y 坐标IE9支持event.screenX返回鼠标相对于电脑屏幕的 X 坐标(电脑屏幕)event.screenY返回鼠标相对于电脑屏幕的 Y 坐标3.8 键盘事件对象keydown不区分大小写keypress区分大小写( keyCode编码 )也可以通过 key 去判断按的什么键( key字符串 )3.9 触摸事件对象触摸列表说明touches正在触摸屏幕的所有手指的一个列表targetTouches正在触摸当前DOM元素上的手指的一个列表changedTouches手指状态发生了改变的列表从无到有从有到无变化3.10 事件委托(事件代理)事件委托是利用了事件冒泡的特征还拿ul举例子比如我想给ul下面很多个li标签添加事件可以只给ul添加事件就相当于利用冒泡的特性给每一个li都加了事件(这里要注意目标对象的事件不一定是自己的事件也可以是父元素给委托的事件)4. 元素自定义属性4.1 默认的自定义属性// 获取标签结构中的自定义属性值也可以获取标签自身的属性值element.getAttribute(自定义属性名)// 为标签添加(修改)自定义的属性名和属性值有就修改没有就添加element.setAttribute(自定义属性名,自定义属性值)// 删除标签中的自定义属性element.removeAttribute(自定义属性名)4.2 h5新增的自定义属性// 注意设置的时候必须以>// 所有以data-开头的属性都可以使用dataset去增删改查// 获取element.dataset.xxx// 修改(添加)element.dataset.xxxvalue// 删除deleteelement.dataset.xxx5. 节点操作5.1 节点类型元素节点nodeType 为 1属性节点nodeType 为 2文本节点nodeType 为 3注释节点nodeType 为 8Document 节点nodeType 为 9DocumentFragment 节点nodeType 为 115.2 节点自身的信息nodeType当前节点类型nodeValue节点文本内容nodeNameele节点标签会返回大写的5.3 获取父元素parentElement父元素parentNode父元素节点Element.closest(selectors)返回离当前元素最近的祖先元素5.4 获取子元素children子元素(元素)childNodes子元素节点(包括元素、属性、文本、注释等)firstChild获取第一个子元素节点firstElementChild获取第一个子元素lastChild获取最后一个子元素节点lastElementChild获取最后一个子元素5.5 获取兄弟元素nextSibling获取下一个兄弟节点previousSibling获取上一个兄弟节点nextElementSibling获取下一个兄弟元素(H5新增)previousElementSibling获取上一个兄弟元素(H5新增)5.6 添加节点对象创建(三种方式)// 创建节点对象(这个时候还没上树)document.createELement(标签名)// 创建文档片段会创建一个空白的文档可以用来装载元素document.createDocumentFragment()// 会覆盖node中原有的内容// innerText和innerHTML差不多只是innerText不能识别标签// textContent和outerHTML和上面两个都是差不多的textContent兼容性好一些node.innerHTML标签内容// 对整个页面进行重绘document.write(标签内容)追加// 追加节点对象(上树)parentNode.append(元素对象或字符串)// 如果是字符串就是添加文本节点parentNode.appendChild(元素对象)// 只能是元素对象parentNode.prepend()// 和 append 一样不过是添加到最前面插入// 第一种// 插入指定元素之前(上树)parentNode.insertBefore(ele,指定元素)// 第二种// 这个方法不会覆盖之前的html内容// position有四个参数// beforebegin元素自身的前面。// afterbegin插入元素内部的第一个子节点之前。// beforeend插入元素内部的最后一个子节点之后。// afterend元素自身的后面。// text要插入的HTML元素// 这三个的插入方法都是差不多的// 使用 insertAdjacentHTML 插入用户输入的HTML内容的时候需要转义之后才能使用element.insertAdjacentHTML(position,text);// 插入的元素element.insertAdjacentElement(position,element);// 插入的文本element.insertAdjacentText(position,text);!-- 这里的p标签是目标元素 --!-- beforebegin --p!-- afterbegin --foo!-- beforeend --/p!-- afterend --// 第三种// 插入当前目标元素之前或之后element.before(元素对象或字符串)element.after(元素对象或字符串)5.7 删除节点parentNode.removeChild(“指定元素”)返回被删除的节点node.remove()删除当前元素不会返回5.8 克隆节点// 当为true时为深层克隆克隆当前节点和子节点并返回克隆的节点node.cloneNode(true)// 当为false时为浅层克隆只克隆当前节点(标签、属性和类名)node.cloneNode(false)5.9 替换节点Node.replaceChild(newChild,oldChild)5.10 移动节点// externalNode需要提取的节点// 然后把 node 插入到新的位置nodedocument.adoptNode(externalNode);6. 获取元素属性6.1 偏移量 offsetoffset 翻译过来就是偏移量 我们使用 offset系列相关属性可以动态的得到该元素的位置( 偏移 )、大小等。获得元素距离带有定位父元素的位置获得元素自身的大小宽度高度注意返回的数值都不带单位offset系列属性作用ele.offsetParent返回具有定位元素的父级元素如果上层一直没有则返回bodyele.offsetTop返回元素相对带有定位父元素上方的偏移子border到父borderele.offsetLeft返回元素相对带有定位父元素左方的偏移如果没有就是bodyele.offsetWidth返回自身contentpaddingborder的宽度返回值不带单位ele.offsetHeight返回自身contentpaddingborder的高度返回值不带单位6.2 offset 与 style 区别6.2.1 offsetoffset 可以得到任意样式表中的样式值offset 系列获得的数值是没有单位的offsetWidth 包含paddingborderwidthoffsetWidth 等属性是只读属性只能获取不能赋值所以我们想要获取元素大小位置用offset更合适6.2.2 stylestyle 只能得到行内样式表中的样式值style.width 获得的是带有单位的字符串style.width 获得不包含padding和border 的值style.width 是可读写属性可以获取也可以赋值所以我们想要给元素更改值则需要用style改变6.3 元素可视区 clientclient 翻译过来就是客户端我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。client系列属性作用ele.clientTop返回该元素上边框的大小ele.clientLeft返回该元素左边框的大小ele.clientWidth返回自身contentpadding的宽度返回值不带单位ele.clientHeight返回自身contentpadding的宽度返回值不带单位6.4 元素滚动 scrollscroll 翻译过来就是滚动的我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。scroll系列属性作用ele.scrollTop返回自身被卷去上侧的距离ele.scrollLeft返回自身被卷去左侧的距离ele.scrollWidth返回自身content的宽度包含溢出不可见的内容ele.scrollHeight返回自身content的高度包含溢出不可见的内容ele.scrollTo(x,y)手动滚动dom元素7. 操作css7.1 类名与ID// 像类名与ID直接元素点就可以使用一般其他的样式要style点才可以// 类名className// 返回类名可读可写classList// 将属性作为列表来返回/* classList 可以使用 add(class)添加类名 remove(class)删除类名 toggle(class)切换类名如果有类名删除没有就添加 contains(class)判断是否存在类名返回布尔值 */// IDid// 返回id可读可写7.2 行内样式// 1. 通过属性修改// 上面说到 DOM 提供的有很多获取元素宽高等一些属性// 但是 style 可以获取行内样式也可以添加行内样式// background-color像这种样式需要转为大驼峰element.style.backgroundColorred// 可读可写// 2. 通过 API 修改/* propertyName需要添加或修改的属性有则修改无则添加和 css 一样写法 value(可选)需要修改或填的属性值如果不填为空 priority(可选)设置 css 优先级 important css 变量通过 js 去设置需要使用这种方式直接 style 点不行 */element.style.setProperty(propertyName,[value],[priority]);7.3 全部样式divclassbox/divscript// 获取box元素letboxdocument.querySelector(.box)// 获取box的全部样式计算后的样式letboxStylewindow.getComputedStyle(box)// 获取box伪元素的全部样式letafterStylewindow.getComputedStyle(box,::after)// 这种方式是只读的/script