zoukankan      html  css  js  c++  java
  • JS获取元素的宽高以及offsetTop,offsetLeft等的属性值

    基本介绍

    $(obj).width()与$(obj).height()

    $(obj).width()与$(obj).height() :jquery方式获取元素的宽高,不包括滚动条与工具条

    $(obj).width() = width
    $(obj).height() = height

    $(window).width()$(window).height():获得的是屏幕可视区域的宽高,不包括滚动条与工具条。

    $(window).width() = width + padding
    $(window).height() = height + padding

    document.documentElement.clientWidth与document.documentElement.clientHeight

    document.documentElement.clientWidthdocument.documentElement.clientHeight获得的是屏幕可视区域的宽高,不包括滚动条与工具条,跟jquery的(window).width()与(window).height()获得的结果是一样的。

    document.documentElement.clientWidth = width + padding
    document.documentElement.clientHeight = height + padding

    window.innerWidth与window.innerHeight

    window.innerWidthwindow.innerHeight获得的是可视区域的宽高,但是window.innerWidth宽度包含了纵向滚动条的宽度,window.innerHeight高度包含了横向滚动条的高度(IE8以及低版本浏览器不支持)。

    window.innerWidth = width + padding + border + 纵向滚动条宽度
    window.innerHeight = height + padding + border + 横向滚动条高度

    window.outerWidth与window.outerHeight

    window.outerWidthwindow.outerHeight:获得的是加上工具条与滚动条窗口的宽度与高度。

    window.outerWidth = width + padding + border + 纵向滚动条宽度
    window.outerHeight = height + padding + border + 横向滚动条高度 + 工具条高度

    document.body.clientWidth与document.body.clientHeight

    document.body.clientWidthdocument.body.clientHeight:document.body.clientWidth获得的也是可视区域的宽度,但是document.body.clientHeight获得的是body内容的高度,如果内容只有200px,那么这个高度也是200px,如果想通过它得到屏幕可视区域的宽高,需要样式设置,如下:

    body {
    height: 100%;
    overflow: hidden;
    }
    body, div, p, ul {
    margin: 0;
    padding: 0;
    }

    最关键的是:body的height:100%影响document.body.clientHeight的值。body的margin:0,padding:0影响document.body.clientWidth的值。

    offsetWidth & offsetHeight

    返回本身的宽高 + padding + border + 滚动条

    offsetLeft & offsetTop

    所有HTML元素拥有offsetLeft和offsetTop属性来返回元素的X和Y坐标

    1.相对于已定位元素的后代元素和一些其他元素(表格单元),这些属性返回的坐标是相对于祖先元素

    2.一般元素,则是相对于文档,返回的是文档坐标

    //获取元素的纵坐标(相对于窗口)
    function getTop(e){
        var offset=e.offsetTop;
        if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
        return offset;
    }
    //获取元素的横坐标(相对于窗口)
    function getLeft(e){
        var offset=e.offsetLeft;
        if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
        return offset;
    }

    当然上面的代码是在反复调用自身方法,也可以下面这个方法来实现,主要使用while语句:

        function getPoint(obj) { //获取某元素以浏览器左上角为原点的坐标  
            var t = obj.offsetTop; //获取该元素对应父容器的上边距  
            var l = obj.offsetLeft; //对应父容器的上边距  
            //判断是否有父容器,如果存在则累加其边距  
            while (obj = obj.offsetParent) {//等效 obj = obj.offsetParent;while (obj != undefined)  
                t += obj.offsetTop; //叠加父容器的上边距  
                l += obj.offsetLeft; //叠加父容器的左边距  
            }  
            alert("top: " + t + " left: " + l);  
        }  

    怎样理解offsetParent,人们并没有把offsetParent翻译为偏移父级,而是翻译成定位父级,很大原因是offsetParent与定位有关定位父级offsetParent的定义是:与当前元素最近的经过定位(position不等于static)的父级元素,主要分为下列几种情况 :

    【1】元素自身有fixed定位,offsetParent的结果为null

      当元素自身有fixed固定定位时,我们知道固定定位的元素相对于视口进行定位,此时没有定位父级,offsetParent的结果为null

      [注意]firefox浏览器有兼容性问题

    <div id="test" style="position:fixed"></div>    
    <script>
    //firefox并没有考虑固定定位的问题,返回<body>,其他浏览器都返回null
    console.log(test.offsetParent);
    </script>

     【2】元素自身无fixed定位,且父级元素都未经过定位,offsetParent的结果为<body>

    <div id="test"></div>    
    <script>
    console.log(test.offsetParent);//<body>
    </script>

    【3】元素自身无fixed定位,且父级元素存在经过定位的元素,offsetParent的结果为离自身元素最近的经过定位的父级元素

    <div id="div0" style="position:absolute;">
        <div id="div1" style="position:absolute;">
            <div id='test'></div>    
        </div>    
    </div>
    <script>
    console.log(test.offsetParent);    //<div id="div1">
    </script>

    【4】<body>元素的parentNode是null

    console.log(document.body.offsetParent);//null

    scrollWidth & scrollHeight

    这两个属性是元素的内容区域加上内边距,在加上任何溢出内容的尺寸.

    因此,如果没有溢出时,这些属性与clientWidth和clientHeight是相等的。

    scrollLeft & scrollTop

    指定的是元素的滚动条的位置

    scrollLeft和scrollTop都是可写的属性,通过设置它们来让元素中的内容滚动。

    实例1:获取当前页面滚动条纵坐标的位置

    获取当前页面滚动条纵坐标的位置:document.body.scrollTop与document.documentElement.scrollTop
    获取当前页面滚动条横坐标的位置:document.body.scrollLeft与document.documentElement.scrollLeft

    各浏览器下获取scrollTop的差异:

    • IE6/7/8:可以使用 document.documentElement.scrollTop; 
    • IE9及以上:可以使用window.pageYOffset或者document.documentElement.scrollTop 
    • Safari:window.pageYOffset 与document.body.scrollTop都可以; 
    • Firefox::火狐等等相对标准些的浏览器就省心多了,直接用window.pageYOffset 或者 document.documentElement.scrollTop
    • Chrome:谷歌浏览器只认识document.body.scrollTop;

    注:标准浏览器是只认识documentElement.scrollTop的,但chrome虽然我感觉比firefox还标准,但却不认识这个,在有文档声明时,chrome也只认识document.body.scrollTop.


    由于在不同情况下,document.body.scrollTop与document.documentElement.scrollTop都有可能取不到值,那到底网页的scrollTop值怎么得到呢?难道又要用JavaScript进行判断?

    其实不必。因为document.body.scrollTop与document.documentElement.scrollTop两者有个特点,就是同时只会有一个值生效。比如document.body.scrollTop能取到值的时候,document.documentElement.scrollTop就会始终为0;反之亦然。所以,如果要得到网页的真正的scrollTop值,如果不考虑safari,可以这样:
    var sTop=document.body.scrollTop+document.documentElement.scrollTop;(但是一般都不这样做的)
    这两个值总会有一个恒为0,所以不用担心会对真正的scrollTop造成影响。一点小技巧,但很实用。

    获取scrollTop的值

    可以使用window.pageYoffset
    Window pageXOffset 和 pageYOffset 属性其定义:pageXOffset 设置或返回当前页面相对于窗口显示区左上角的 X 位置。pageYOffset 设置或返回当前页面相对于窗口显示区左上角的 Y 位置。所有主流浏览器都支持 pageXOffset 和 pageYOffset 属性。

    注意: IE 8 及 更早 IE 版本不支持该属性,但可以使用 "document.documentElement.scrollLeft" 和 "document.documentElement.scrollTop" 属性 。

    由于谷歌兼容问题,可以使用document.body.scrollLeftdocument.body.scrollTop 或者window.pageXoffset与window.pageYoffset。

    最终兼容做法:

    var heightTop = document.documentElement.scrollTop || document.body.scrollTop;
    console.log(heightTop);

    实例2:获取某个元素距离文档区域的距离

    jQuery实现方式:

    var top = $('.btn').offset().top;
    console.log(top); //2080

    JS实现方式:

    function getPoint(obj) { //获取某元素以浏览器左上角为原点的坐标  
        var t = obj.offsetTop; //获取该元素对应父容器的上边距  
        var l = obj.offsetLeft; //对应父容器的上边距  
        //判断是否有父容器,如果存在则累加其边距  
        while (obj = obj.offsetParent) {
            t += obj.offsetTop; //叠加父容器的上边距  
            l += obj.offsetLeft; //叠加父容器的左边距  
        }  
        return {
            x:l,
            y:t
        }
    }  
    
    var top2 = getPoint(document.getElementsByClassName('btn')[0]);
    console.log(top2.y); //2080

    实例3:监听某个元素是否已经在可视区域

    实现思路:获取当前监听元素距离文档的左上角的top距离;根据这个距离和当前可视区域的高度+文档滚动距离进行比较,即scrollTop <= top <=  document.documentElement.clientHeight + scrollTop

    jquery实现方式:

    $(function(){
        var top = $("#btn").offset().top; //距离文档顶部的距离
        var windowHeight = document.documentElement.clientHeight; //可视区域的高度
        $(window).scroll(function(){
            var scrollTop = $(window).scrollTop();
            if(top >= scrollTop && top <= windowHeight + scrollTop){
                console.log('在可视区域了');
            }
        });
    })

    JS实现方式:

    function getPoint(obj) { //获取某元素以浏览器左上角为原点的坐标  
        var t = obj.offsetTop; //获取该元素对应父容器的上边距  
        var l = obj.offsetLeft; //对应父容器的上边距  
        //判断是否有父容器,如果存在则累加其边距  
        while (obj = obj.offsetParent) {
            t += obj.offsetTop; //叠加父容器的上边距  
            l += obj.offsetLeft; //叠加父容器的左边距  
        }  
        return {
            x:l,
            y:t
        }
    }
    
    window.onload = function(){
        var top = getPoint(document.getElementById('btn')).y; //距离文档顶部的距离
        var windowHeight = document.documentElement.clientHeight; //可视区域的高度
        window.onscroll = function(){
            var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            if(top >= scrollTop && top <= windowHeight + scrollTop){
                console.log('在可视区域了');
            }    
        }
    }

    兼容性

    1.window innerWidth 和 innerHeight 属性与outerWidth和outerHeight属性IE8以及以下不支持。

    2.测试浏览器IE,火狐,谷歌,360浏览器,Safari都支持document.documentElement.clientWidth与document.documentElement.clientHeight。

    结论

    获取屏幕的可视区域的宽高可使用jquery的方式获得,也可以使用原生js获得,即:

    document.documentElement.clientWidth与document.documentElement.clientHeight

     
  • 相关阅读:
    EOJ二月月赛补题
    cf401d
    cf628d
    cf55d
    HDU 6148 Valley Number
    洛谷 P3413 SAC#1
    洛谷 P4127[AHOI2009]同类分布
    洛谷 P2602 [ZJOI2010]数字计数
    bzoj 3679
    函数和循环闭包的理解
  • 原文地址:https://www.cnblogs.com/moqiutao/p/6639792.html
Copyright © 2011-2022 走看看