DOM

目录


1. DOM简介

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

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

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

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


2. DOM树模型

文档

根元素-html

元素-head

元素-title

文本-'文档标题'

元素-body

元素-a

属性-href

文本-'我的链接'

元素-h1

文本-'我的标题'

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 获得

作者:Hong•Guo

出处:https://www.cnblogs.com/ghnb1/p/15845096.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Hong•Guo  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示