Loading

DOM

目录


1. DOM简介

​ 文档对象模型(Document Object Model,简称DOM),是 W3C 组织推荐的处理可扩展标记语言(html或者xhtml)的标准编程接口

​ W3C 已经定义了一系列的 DOM 接口,JS中通过DOM来对HTML文档进行操作

  • 文档:表示的就是整个的HTML网页文档
  • 对象:表示将网页中的每一个部分都转换为了一个对象。
  • 模型:使用模型来表示对象之间的关系,这样方便我们获取对象。

DOM是W3C组织制定的一套处理 html和xml文档的规范,所有的浏览器都遵循了这套标准。


2. DOM树模型

graph TD A[文档] --> B[根元素-html] B --> C[元素-head] C -->E[元素-title] -->F[文本-'文档标题'] B --> D[元素-body] D -->G[元素-a] G --> I[属性-href] G --> J[文本-'我的链接'] D -->H[元素-h1] H --> K[文本-'我的标题']

DOM树 又称为文档树模型,把文档映射成树形结构,通过节点对象对其处理,处理的结果可以加入到当前的页面。

3. 节点 Node

节点Node,是构成我们网页的最基本的组成部分,网页中的每一个部分都可以称为是一个节点。比如:html标签、属性、文本、注释、整个文档等都是一个节点。

节点分类

节点的具体类型不同,其对应的属性和方法也都不尽相同,常用节点类型如下:

文档节点(document)

  • 文档节点document,代表的是整个HTML文档,网页中的所有节点都是它的子节点。

  • document对象 作为 window对象 的属性存在的,我们不用获取可以直接使用。

  • 通过该对象我们可以在整个文档访问内查找节点对象,并可以通过该对象创建各种节点对象。

元素节点(Element)

  • HTML中的各种标签 都是元素节点,这也是我们最常用的一个节点。

  • 浏览器会将页面中所有的标签都转换为一个元素节点,我们可以通过document的方法来获取元素节点。

文本节点(Text)

  • 文本节点表示的是HTML标签以外的文本内容,任意非HTML的文本都是文本节点。

  • 文本节点一般是作为元素节点的 子节点 存在的。

属性节点(Attr)

  • 属性节点表示的是标签中的一个一个的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
  • 可以通过元素节点来获取指定的属性节点

节点对象基本属性

一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

⭐文本内容包含:文字、空格、换行等


4. DOM操作

创建节点

document.wirte()

详细文档...

document.write('<div>123</div>');

element.innerHTML

详细文档...

var div = document.querySelector('div');

for(var i=0; i<=100; i++){
    //效率低
    div.innerHTML += '<a></a>';
}

var arr = [];
for (var i = 0; i <= 100; i++) {
    //效率高
     arr.push('<a href="#">百度</a>');
}
div.innerHTML = arr.join('');

document.creatElement()

详细文档...

  • 语法

    var tagName = document.createElement('tagName');
    

    document.createElement() 方法创建由tagName指定的 HTML 元素。 因为这些元素原先不存在,是根据我们的需求动态生成的, 所以我们也称为动态创建元素节点


三种动态创建元素区别

Ⅰ 三者对文档流的影响

  1. document.write 是直接将内容写入页面的内容流, 但是文档流执行完毕在执行,则它会导致页面全部重绘

    <body>
        <button>点击</button>
        <p>abc</p>
        <div class="inner"></div>
        <div class="create"></div>
    </body>
    <script>
    	 var btn = document.querySelector('button');
        /*
        事件被触发前页面文档流已经加载完毕,事件触发后执行监听器里的代码,页面重绘, 可以看到原来的节点不再存在
        */
         btn.onclick = function() {
         	document.write('<div>123</div>');
         }
    </script>
    
  2. innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘,createElement()也不会


Ⅱ 三者节点创建方式有所不同

  1. document.writeinnerHTML是创建节点后直接写入文档流
  2. createElement()只创建了节点,并没有写入文档流,还需要增添节点

三者节点创建效率有所不同

  1. 效率最高:innerHTML (采取数组形式拼接)创建多个节点效率更高,结构稍微复杂

        function fn() {
            var d1 = +new Date();
            var array = [];
            for (var i = 0; i < 1000; i++) {
                array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
            }
            document.body.innerHTML = array.join('');
            var d2 = +new Date();
            console.log(d2 - d1);
        }
        fn();
    //大约 3 毫秒 完成界面渲染
    
  2. 效率高:createElement() 创建多个节点效率稍低一点点,但是结构更清晰

    function fn() {
            var d1 = +new Date();
    
            for (var i = 0; i < 1000; i++) {
                var div = document.createElement('div');
                div.style.width = '100px';
                div.style.height = '2px';
                div.style.border = '1px solid red';
                document.body.appendChild(div);
            }
            var d2 = +new Date();
            console.log(d2 - d1);
        }
        fn();
        //大约 5 毫秒 完成界面渲染
    
  3. 效率低:

    • document.write()创建多个元素效率较低

          function fn() {
              var d1 = +new Date();
              for (var i = 0; i < 1000; i++) {
                  document.write('<div style="width: 100px; height: 2px;border: 1px solid red;"></div>')
              }
              var d2 = +new Date();
              console.log(d2 - d1);
          }
          fn();
          //大约 32 毫秒 完成界面渲染
      

      解决方案

      1. 利用空字符串

            function fn() {
                var d1 = +new Date();
                var str = '';
                for (var i = 0; i < 1000; i++) {
                    str += '<div style="width: 100px; height: 2px;border: 1px solid red;"></div>';
                }
                document.wirte(str);
                
                var d2 = +new Date();
                console.log(d2 - d1);
            }
            fn();
            //大约 2 毫秒 完成界面渲染
        
      2. 利用空数组

            function fn() {
                var d1 = +new Date();
                var arr = [];
                for (var i = 0; i < 1000; i++) {
                    arr.push('<div style="width: 100px; height: 2px;border: 1px solid red;"></div>');
                }
                var str = arr.join('');
                document.write(str);
        
                var d2 = +new Date();
                console.log(d2 - d1);
            }
            fn();
            //大约 2 毫秒 完成界面渲染
        
    • innerHTML(采取拼接字符串)创建多个元素效率太低

       function fn() {
              var d1 = +new Date();
              for (var i = 0; i < 1000; i++) {
                  document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
              }
              var d2 = +new Date();
              console.log(d2 - d1);
          }
          fn();
          //大约 800 毫秒 完成界面渲染
      	//解决方案和document.write的两种解决方案一样,也是 大约2毫秒
      
  4. 不同浏览器下, innerHTML 效率要比 creatElement 高 ,document.write()貌似一般不适用


element.insertAdjacentHTML

element.insertAdjacentHTML - Web API 接口参考 | MDN
insertAdjacentHTML() 方法将指定的文本解析为 Element 元素,并将结果节点插入到DOM树中的指定位置。

element.insertAdjacentHTML(position, text);

添增节点

父节点里添增子节点

Node.appendChild

参考文档...

  • 语法
//1.
node.appendChild(child)
  • 作用:

    将一个节点添加到指定父节点的子节点列表末尾


Node.insertBefore()

参考文档...

  • 语法
//2.
node.insertBefore(child, 指定元素)
//node为父节点,child为要添增的子节点
  • 作用:

    将一个节点添加到父节点的指定子节点前面。



删除节点

Node.removeChild

参考文档...

node.removeChild(child)

node.removeChild() 方法从 DOM 中删除一个子节点, 返回删除的节点



修改节点

主要修改dom的元素节点的属性、内容、表单的值等

修改节点属性

元素对象的属性分为:内部属性、自定义属性

这里针对内部属性的修改

element.value

element.id

nodeValue

文本节点可以通过nodeValue属性获取和设置文本节点的内容

innerText/innerHTML

element.innerHTML
HTMLElement.innerText

它们表示元素对象的内部属性(但部分元素对象是没有这个属性),通过它们可改变或获取元素对象内容

//element:元素对象
//通过 ‘元素对象.成员’访问元素对象属性
element.innerText;
element.innerHTML;

innerText和innerHTML的区别

  • 获取内容时的区别:

​ innerText会去除空格和换行,而innerHTML会保留空格和换行

  • 设置内容时的区别:

​ innerText不会识别html,而innerHTML会识别


表单节点的属性操作

利用 DOM 可以操作如下表单元素对象的内部属性

type、 value、 checked、 selected、 disabled、...

表单元素对象不能通过innerHTML/innerText设置或获取内容,比如input,可通过value


节点 style样式属性操作

可以通过 JS 修改元素的大小、颜色、位置等样式。

  • 直接通过元素对象访问它的样式属性

    element.style.样式;
    
    <body>
        <div></div>
        <script>
            var div = document.querySelector('div');
            div.style.backgroundColor = 'purple';
            div.style.width = '250px';
            }
        </script>
    </body>
    

    通过元素对象操作它的style会改变它的行内样式,权重比较高

    <div style="..."></div>
    

  • 通过修改元素对象的className属性改变元素的样式

    Element.className表示标签内部的class属性

    element.className;
    

    案例代码

    <style>
        .change {
            backgroundColor = 'purple';
            color = '#fff';
            marginTop = '100px';
        }
    </style>
    
    <body>
        <div class="first">文本</div>  
    </body>
    
    <script>
            var test = document.querySelector('div');
            test.onclick = function() {
                this.className = 'first change';
            }
    </script>  
    

    事件触发后

    <!-- 点击过后 -->
    <div class="first change">文本</div>
    

    注意

    1. 如果样式修改较多,可以采取操作类名方式更改元素样式。
    2. class因为是个保留字,因此使用className来操作元素类名属性
    3. className会直接更改元素的类名,会覆盖原先的类名

classList 属性

Element.classList属性是HTML5新增的一个属性, 返回一个包含元素的类名的对象。但是ie10以上版本支持。

 <button class="one two three">btn</button>
 <script>
        var btn = document.querySelector('button');
        console.log(btn.classList);
 </script>

请添加图片描述
该属性用于在元素中添加,移除及切换 CSS 类。有以下方法:

添加类

element.classList.add( '类名');

移除类

element.classList.remove('类名') ;  

切换类:

element.classList.toggle( '类名');

注意以上方法里面,所有类名都不带点

除了上述属性,还有

  • src
  • title
  • href
  • disabled(表单)
  • ...

替换节点

Element.replaceChildren()

Element.replaceChildren() - Web API 接口参考 | MDN (mozilla.org)


复制节点

Node.cloneNode

参考文档..

node.cloneNode()

node.cloneNode() 方法返回调用该方法的节点的一个副本
注意:

  1. 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身, 不克隆里面的子节点。
  2. 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点。


查询节点

DOM提供的API 方法

document.getElementById()

参考文档..

  • 语法:

    element.getElementById('id');
    
  • 作用:获取带有 ID 的元素对象。

  • 参数:id值,区分大小写的字符串

  • 返回值:元素对象 或 null

使用console.dir()可以打印我们获取的元素对象,更好的查看对象里面的属性和方法。

<body>
    <div id="time">2019-9-9</div>
    <script>
        // 因为我们文档页面从上往下加载,所以先得有标签 所以我们script写到标签的下面
        var timer = document.getElementById('time');
        console.log(timer);
        console.log(typeof timer);
        // console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法
        console.dir(timer);
    </script>
</body>

document.getElementsByTagName()

参考文档..

  • 语法:

    element.getElementsByTagName('标签名');
    
  • 作用:返回带有指定标签名的元素对象的集合

    集合:以伪数组的形式存储的数据结构

  • 参数:标签名

  • 返回值:元素对象集合

注意

  • 因为得到的是一个对象的集合, 所以想要操作里面的元素就需要遍历

  • 得到元素对象是动态的

    getElementsByTagName()获取到是动态集合,即:当页面增加了标签,这个集合中也就增加了元素。

  • 如果获取不到元素节点对象,则返回为空的伪数组;

  • 父元素节点可以通过getElementsByTagName获取内部所有指定标签名的子元素节点,父元素必须是单个对象(必须指明是哪一个元素对象)

案例

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <ol id="nav">
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
    </ol>
    <script>
		//获取li元素节点集合
        var lis = document.getElementsByTagName('li');
        console.log(lis); //HTMLCollection(8)
        console.log(lis[0]); //<li>...<li>
        
		//遍历li元素节点集合
        for (var i = 0; i < lis.length; i++) {
            console.log(lis[i]);//<li>...<li> *8
        }

        var nav = document.getElementById('nav'); 
        // var ol = document.getElementsByTagName('ol'); // [ol]
        // console.log(ol[0].getElementsByTagName('li'));// 父元素必须是指定的单个元素
        var navLis = nav.getElementsByTagName('li');
        console.log(navLis);//HTMLCollection(4)
    </script>
</body>

document.getElementsByName()

通过name属性获取一组元素节点对象

Document.getElementsByName() - Web API 接口参考 | MDN (mozilla.org)


H5提供的新方法

先得考虑兼容性问题,移动端可优先使用

document.getElementsByClassName()

参考文档..

  • 语法

    element.getElementsByClassName('className');
    
  • 作用:根据元素类名返回元素对象集合

  • 参数:标签的类名


document.querySelector()

文档..

  • 语法

    element.querySelected('选择器');
    
  • 作用:返回指定选择器的第一个元素对象, 注意❕ 里面的选择器需要加符号,比如 .box #nav

  • 参数:选择器


document.querySelectorAll()

文档..

  • 语法

    element.querySelectedAll('选择器');
    
  • 作用: 返回指定选择器的所有元素对象集合

  • 参数:选择器


特殊节点的查询

document.body

文档..

  • 语法

    var bodyEle = document.body;
    
  • 返回body元素对象

document.documentElement

文档..

  • 语法

    var htmlEle = document.documentElement;
    
  • 返回html元素对象


利用节点层级关系操作查询节点

节点层级:利用 DOM 树可以把节点划分为不同的层级关系。

Ⅰ 查询父级节点

Node.parentNode

文档..

  • 语法

    node.parentNode;
    //node : 一个节点,元素对象
    
  • parentNode 属性可返回某节点的父节点, 注意是最近的一个父节点

  • 如果指定的节点没有父节点则返回null


Ⅱ 查询子节点

Node.childNodes

文档..

  • 语法

    //(标准)
    parentNode.childNodes;
    
  • 返回包含指定节点的 所有子节点的集合,该集合为即时更新的集合

注意: 返回值里面包含了所有的子节点,包括元素节点,文本节点等。如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes

var ul = document. querySelector(‘ul’);
for(var i = 0; i < ul.childNodes.length;i++) {
	if (ul.childNodes[i].nodeType == 1) {
		// ul.childNodes[i] 是元素节点
		console.log(ul.childNodes[i]);
	}
}

Element.children

文档..

  • 语法

    //(非标准)
    parentNode.children;
    
  • children 是一个只读属性

  • 作用:返回 所有的子元素节点。它只返回子元素节点,其余节点不返回 (比较实用)。

  • 虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用


Node.firstChild

文档..

  • 语法

    parentNode.firstChild;
    
  • 作用: 返回 第一个子节点, 找不到则返回null, 注意 包含所有的子节点


Node.lastChild

文档..

  • 语法

    parentNode.lastChild;
    
  • 作用: 返回 最后一个子节点, 找不到则返回null, 注意 包含所有的子节点


Element.firstElementChild

文档..

  • 语法

    parentNode.firstElementChild;
    
  • firstElementChild 返回 第一个子元素节点, 找不到则返回null


Element.lastElementChild

文档..

  • 语法

    parentNode.lastElementChild
    
  • lastElementChild 返回 最后一个子元素节点, 找不到则返回null。

  • 注意:firstElementChildlastElementChild 这两个方法有兼容性问题, IE9 以上才支持


实际开发中, firstChildlastChild 包含其他节点,操作不方便,而 firstElementChildlastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?
解决方案:

  1. 如果想要第一个子元素节点, 可以使用 parentNode.chilren[0];
  2. 如果想要最后一个子元素节点, 可以使用 parentNode.chilren[parentNode.chilren.length - 1];

Ⅲ 查询兄弟节点

Node.nextSibling

文档..

node.nextSibling

作用:返回当前元素的下一个兄弟元素节点, 找不到则返回null。 同样,也是包含所有的节点


Node.previousSibling

文档..

node.previousSibling

previousSibling 返回当前元素上一个兄弟元素节点, 找不到则返回null。 同样,也是包含所有的节点


NonDocumentTypeChildNode.nextElementSibling

文档..

//3.
 node.nextElementSibling

nextElementSibling 返回当前元素下一个兄弟元素节点, 找不到则返回null。


NonDocumentTypeChildNode.previousElementSibling

文档..

//4.
node.previousElementSibling

previousElementSibling 返回当前元素上一个兄弟元素节点, 找不到则返回null。

注意: nextElementSibling/previousElementSibling这两个方法有兼容性问题,IE9 以上才支持


通过自定义函数可解决兼容性问题

function getNextElementSibling(element) {
	var el = element;
	while (el = el.nextSibling) {
		if (el.nodeType === 1) {
			return el;
		}
	}
	return null;
}


节点自定义属性操作

这里主要针对自定义属性的操作

Ⅰ 自定义属性写法

可以自定义元素的属性,比如

<div getTime="20" data-index="2" data-list-name="andy">hello</div>

有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。H5新增了自定义属性 ,规定自定义属性data-开头做为属性名并且赋值。

自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中



Ⅱ 获取属性值

element.属性名

//1.
element.属性
  • 主要用来获取内部属性值;但不能获取到自定义属性,且获取结果为 undefined

Element.getAttribute()

文档..

//2.
element.getAttribute('属性名');
  • 主要用来获取外部属性(自定义属性)的值

HTMLElement.dataset

文档..

//3.
element.dataset.index;
element.dataset['index'];
  • h5新增的获取自定义属性的方法 它只能获取data-开头的
    dataset 是一个集合(对象),里面存放了所有以data开头的自定义属性
var div = document.querySelector('div');
div.innerHTML;//hello
div.getTime;//undefined

div.getAttribute('getTime');//'20'
div.getAttribute('data-list-name');//'andy'
div.getAttribute('innerHTML');//null

console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);


Ⅲ 设置属性值

element.属性名

//1.
element.属性 = "值";
  • 同样,适用于内部属性,对于自定义属性无效

Element.setAttribute()

文档..

element.setAttribute('属性名', '值');
  • 主要用来设置自定义属性值
div.innerHTML = 'world';
div.getTime = '30';//无效

div.setAttribute('getTime', 30); console.log(typeof(div.getAttribute('getTime')));//string
div.setAttribute('data-list-name', 12)//data-list-name="12"
div.setAttribute('innerHTML', 'usb');//无效
disetAttribute('class', 'footer'); // class 特殊  这里面写的就是


Ⅳ 移除属性值

Element.removeAttribute()

文档..

element.removeAttribute('属性');
div.removeAttribute('data-index');



5. 元素节点的offset、client、scroll三大系列属性

1. 节点偏移量 offset 系列

offset译为偏移量,使用 offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。这属于节点操作的范畴。

  1. 获得元素距离带有定位父元素的位置
  2. 获得元素自身的大小(宽度高度)
  3. 注意:返回的数值都不带单位

请添加图片描述

offset系列节点属性 作用
element.offsetParent 返回作为该元素带有定位的并且是最近的父级元素
element.offsetTop 返回元素相对带有定位的并且是最近的父级元素上边框的偏移
element.offsetLeft 返回元素相对带有定位的并且是最近的父级元素左边框的偏移
element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.offsetHeight 返回自身包括padding、边框、内容区的高度,返回数值不带单位
  • 子节点调用offsetParent、offsetTop、offsetLeft时,若它们的父节点没有定位,则以整个body为准。
  • element.offsetParent 与 element.parentNode() 的异同点
    • offsetParent:返回带有定位的父节点,或整个body
    • parentNode():返回最近的父级节点,无需考虑定位
  • offset 与 style 区别
    • offset
      1. offset 可以得到任意样式表中的样式值(行内,内部,外部样式都可)
      2. offset 系列获得的数值是没有单位的
      3. offsetWidth 包含padding+border+width
      4. offsetWidth 等属性是只读属性只能获取不能赋值;所以,比如获取元素大小用offset更合适
    • style
      1. style 只能得到行内样式表中的样式值
      2. style.width 获得的是带有单位的字符串
      3. style.width 获得不包含padding和border 的值
      4. style.width 等属性是可读写属性可以获取也可以赋值;所以,想要给元素更改值,则需要用style改变


2. 节点可视区 client 系列

client 翻译过来就是客户端,使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

client系列属性 作用
element.clientTop 返回元素上边框的大小
element.clientLeft 返回元素左边框的大小
element.clientWidth 返回自身包括padding,内容区域的宽度,不含边框,返回数值不带单位
element.clientHeight 返回自身包括padding,内容区域的高度,不含边框,返回数值不带单位

请添加图片描述



3. 节点 scroll 系列属性

常见属性

scroll 译为"滚动的",使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

scroll系列属性 作用
element.scrollTop 返回被卷去的上侧距离,返回数值不带单位
element.scrolLeft 返回被卷去的左侧距离,返回数值不带单位
element.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位
element.scrollHeight 返回自身实际的高度,不含边框,返回数值不带单位

案例

<style>
     div {
            width: 200px;
            height: 200px;
            border: 10px solid red;
            padding: 10px;
            overflow: auto;
     }
</style>
<body>
    <div>
        文本内容多到盒子装不下...
    </div>
    <script>
        // scroll 系列
        var div = document.querySelector('div');
        console.log(div.scrollHeight);//311
        console.log(div.clientHeight);//220
        // scroll滚动事件当我们滚动条发生变化会触发的事件
        div.addEventListener('scroll', function() {
            console.log(this.scrollTop);
        })
    </script>
</body>

请添加图片描述


document与element的scroll有区别

如若节点对象为document(整个页面),应该通过window.pageYOffset/window.pageXOffset来获取节点滚动的垂直或平距离。document访问不到scroll系列属性。

如若节点对象为element(页面内的某个元素),应该通过element.scrollTop/element.scrollLeft返回被滚动的上侧或左侧距离,而页面却不行。如下案例

<style>
        body {
            height: 4000px;
            width: 2000px;
        }
</style>
<body>
    <script>
        document.addEventListener('scroll', function() {
            /*
            console.log(document.scrollTop);//undefined
            console.log(document.scrollLeft);//undefined
            
            */
            
            //解决方案
            console.log(window.pageYOffset);
            console.log(window.pageXOffset);
            //最终实现效果:随着页面的滚动,控制台输出相应的数值。
        })
    </script>
</body>

window.scroll(x,y)

Window.scroll() - Web API 接口参考 | MDN (mozilla.org)

滚动窗口至文档中的特定位置。
注意,里面的x和y 不跟单位,直接写数字


兼容性问题解决方案

在旧版本浏览器或页面为声明<!DOCTYPE html>(简称“DTD”)的情况下无法通过scrollTop/scrollLeft直接获取节点滚动的距离。

解决方案:

比如页面被卷去的头部常有以下几种写法

  • 声明了 DTD,使用 document.documentElement.scrollTop
  • 未声明 DTD,使用 document.body.scrollTop
  • 新方法 window.pageYOffset 和 window.pageXOffset, IE9 开始支持

封装自定义功能函数

function getScroll() {
	return {
		left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
		top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
	};
}

使用的时候 getScroll().left

4. 三大系列总结

  1. offset系列 经常用于获得元素位置 offsetLeft offsetTop
  2. client 经常用于获取元素大小 clientWidth clientHeight
  3. scroll 经常用于获取滚动距离 scrollTop scrollLeft
  4. 注意页面滚动的距离通过 window.pageXOffset 获得

posted @ 2022-01-25 23:57  Hong•Guo  阅读(80)  评论(0)    收藏  举报