一、js 中的 dom 操作
dom:document object model 文档对象模型,提供系列的属性和方法,让我们能在 js 中操作页面中的元素
1. 获取元素的属性和方法
document.getElementById([ID])[context].getElementsByTagName([TAG-NAME])[context].getElementsByClassName([CLASS-NAME])// 在 IE6~8 中不兼容document.getElementsByName([NAME])// 在 IE 浏览器中只对表单元素的 NAME 有作用[context].querySelector([SELECTOR])[context].querySelectorAll([SELECTOR])// 在 IE6~8 中不兼容//---------------------documentdocument.documentElementdocument.headdocument.bodychildNodes // 所有子节点children // 所有元素子节点// IE6~8 中会把注释节点当做元素节点获取到parentNodefirstChild / firstElementChildlastChild / lastElementChildpreviousSibling / previousElementSiblingnextSibling / nextElementSibling// 所有带 Element 的,在 IE6~8 中不兼容
2. dom 的增删改操作
document.createElement([TAG-NAME])document.createTextNode([TEXT CONTENT])字符串拼接(模板字符串),基于 innerHTML / innerText 存放到容器中[PARENT].appendChild([NEW-ELEMENT])[PARENT].insertBefore([NEW-ELEMENT],[ELEMENT])[ELEMENT].cloneNode([TRUE/FALSE])[PARENT].removeChild([ELEMENT])// 设置自定义属性[ELEMENT].xxx = xxx;console.log([ELEMENT].xxx);delete [ELEMENT].xxx;[ELEMENT].setAttribute('xxx',xxx);console.log([ELEMENT].getAttribute('xxx'));[ELEMENT].removeAttribute('xxx');
3. 获取元素样式和操作样式
// 修改元素样式[ELEMENT].style.xxx = xxx; // 修改和设置它的行内样式[ELEMENT].className = xxx; // 设置样式类// 获取元素的样式console.log([ELEMENT].style.xxx); // 获取的是当前元素写在行内上的样式,如果有这个样式,但是没有写在行内上,则获取不到

二、js盒子模型属性
基于一些属性和方法,让我们能够获取到当前元素的样式信息,例如:clintWidth 、 offsetWidth 等 client
- width / height
- top / left
offset
- width / height
- top / left
- parent
scroll
- width / height
- top / left
方法:window.getComputedStyle([element],[伪类]) / [element].currentStyle 获取当前元素所有经过浏览器计算过的样式
- 只要元素在页面中呈现出来,那么所有的样式都是经过浏览器计算的,哪怕你没有设置和见过的样式也都计算了,不管你写或者不写,也不论写在哪儿,样式都在这,可以直接获取
- 在 IE6~8 浏览器中不兼容,需要基于 currentStyle 来获取
// 第一个参数是操作的元素 第二个参数是元素的伪类:after/:before// 获取的结果是 CSSStyleDeclaration 这个类的实例(对象),包含了当前元素所有的样式信息let styleObj = window.getComputedStyle([element],null);styleObj["backgroundColor"]styleObj.display// IE6~8styleObj = [element].currentStyle;
1. client
let box = document.getElementById('box');// 获取盒子可视区域的宽高(内容宽度+左右PADDING)// 1.内容溢出与否对他无影响// 2.获取的结果是没有单位的(其余的盒模型属性也是)// 3.获取的结果是整数,它会自己进行四舍五入(其余的盒模型属性也是)box.clientWidthbox.clientHeight// 获取当前页面一屏幕(可视化)区域的宽高let winW = document.documentElement.clientWidth || document.body.clientWidth;let winH = document.documentElement.clientHeight || document.body.clientHeight;// 获取盒子左边框和上边框的大小box.clientLeftbox.clientTop
2. offset
let box = document.getElementById('box');// 在CLIENT的基础上加上 BORDER == 盒子本身的宽高box.offsetWidthbox.offsetHeight// 在没有内容溢出的情况下,获取的结果和 CLIENT 是一样的// 在有内容溢出的情况下,获取的结果约等于真实内容的宽高(上/左PADDING + 真实内容的高度/宽度)// 1.不同浏览器获取的结果不尽相同// 2.设置 overflow 属性值对最后的结果也会产生一定的影响box.scrollWidthbox.scrollHeight// 获取整个页面真实的高度document.documentElement.scrollHeight || document.body.scrollHeight
3. scroll
let box = document.getElementById('box');// 竖向滚动条卷去的高度// 横向滚动条卷去的宽度// 1.边界值// min = 0// max = 整个的高度 scrollHeight - 一屏幕高度 clientHeightbox.scrollTopbox.scrollLeft// 13个盒子模型属性,只有这两个是“可读写”的属性(既可以获取也可以设置对应的值),其余的都是“只读”属性(不能设置值,只能获取)box.scrollTop = 0;
// offsetParent:获取它的父参照物(不一定是父元素)// 父参照物和它的父元素没有必然的联系,父参照物查找:同一个平面中,最外层元素是所有后代元素的父参照物,而基于 position:relative / absolute / fixed 可以让元素脱离文档流(一个新的平面),从而改变元素的父参照物document.body.offsetParent === null;// offsetTop:距离其父参照物的上偏移// offsetLeft:距离其父参照物的左偏移(当前元素的外边框到父参照物的里边框)
三、获取当前元素距body的左/上偏移值
/** offset:获取当前元素距离 BODY 的左/上偏移(不论其父参照物是谁)* @params* curEle:current element当前要操作的元素* @return* [object]包含上/左偏移的信息 => {top:xxx,left:xxx}*/function offset(curEle) {let par = curEle.offsetParent,l = curEle.offsetLeft,t = curEle.offsetTop;// 存在父参照物,而且还没有找到 BODYwhile (par && par.tagName !== "BODY") {//在原有偏移的基础上累加:父参照物的边框、父参照物的偏移if (!/MSIE 8\.0/.test(navigator.userAgent)) {// IE8 中偏移值自已就算了边框了,不需要我们在加边框的值 navigator.userAgent 获取当前浏览器的版本信息l += par.clientLeft;t += par.clientTop;}l += par.offsetLeft;t += par.offsetTop;// 继续获取上级参照物par = par.offsetParent;}return {top: t,left: l};}

