欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

jQuery之位置 关于jQuery中的offset()和position()

shiping1 的头像

在jQuery中有两个获取元素位置的方法offset()和position()。position()方法是在1.2.6版本之后加入的,为什么要引 入这个方法呢?这两个方法之间有什么异同?使用的时候应该注意哪些问题?什么时候使用offset(),什么时候又使用position()呢? 
先看看API对这这两个方法的定义:
offset():
获取匹配元素在当前视口的相对偏移。
返回的对象包含两个整形属性:top 和 left。此方法只对可见元素有效。
position():
获取匹配元素相对父元素的偏移。
返回的对象包含两个整形属性:top 和 left。为精确计算结果,请在补白、边框和填充属性上使用像素单位。此方法只对可见元素有效。
真的就这么简单吗?实践出真知。
先来看看在jQuery框架源码里面,是怎么获得position()的: 
//Get *real* offsetParent
var offsetParent = this.offsetParent(),
//Get correct offsets
offset       = this.offset(),
parentOffset = /^body|html$/i.test(offsetParent[0].tagName)
? { top: 0, left: 0 }
: offsetParent.offset();
//Subtract element margins
//note: when an element has margin: auto the offsetLeft and marginLeft
//are the same in Safari causing offset.left to incorrectly be 0
offset.top  -= num( this, 'marginTop'  );
offset.left -= num( this, 'marginLeft' );
//Add offsetParent borders
parentOffset.top  += num( offsetParent, 'borderTopWidth'  );
parentOffset.left += num( offsetParent, 'borderLeftWidth' );
//Subtract the two offsets
results = {
top:  offset.top  - parentOffset.top,
left: offset.left - parentOffset.left
};
注意最后那段 代码: results = {
top:  offset.top  - parentOffset.top,
left: offset.left - parentOffset.left
};代码的意思就是获取本身元素距离它的父元素的距离。
用图如下所示:

也就是元素B距离元素A的距离。
在没有position()方法之前,计算B到A的距离 只有通过 先计算B距浏览器左边距 减去 A的。
有了position()方法之后,就可以快速计算出来。不过在使用position()之前,你需要了解一
下它们的定位方式。

可以看一下测试例子1: 点击这里浏览例子l

通过例子1页面测试的结果可以得出这个结论: 

1,使用position()方法时事实上是把该元素当绝对定位来处理,获取的是该元素相当于最近的一个拥有绝对或者相对定位的父元素的偏移位置。
2,使用position()方法时如果其所有的父元素都为默认定位(static)方式,则其处理方式和offset()一样,是当前窗口的相对偏移。
3,使用offset()方法不管该元素如何定位,也不管其父元素如何定位,都是获取的该元素相对于当前视口的偏移。

知道了这些特点后,相信你对它们已经熟悉了。进一步那么我们应该如何来合理的使用position()和offset()呢? 


就我个人的经验,通常获取一个元素A的位置是为了让另外的一个元素B正好出现在A元素的附近。通常有2种情况:

1,要显示的元素B存放在DOM的最顶端或者最底端(即其父元素就是body)。这个时候用offset()是最好的。
示例验证:
用offset 正常显示的例子 : 点击查看例子2
用position无法正常显示的例子 : 点击查看例子3
在以上两个例子中,元素B都存放在Dom 结构的最下面,由于其父元素就是BODY,所以,不管元素A如何定位,只要找的A相当与整个窗口的偏移位置,就可以解决问题。

2,若要显示的元素B存放在元素A的同一父元素下(即B为A的兄弟节点),这个时候使用position() 是最合适的。
用position正常显示的例子 :点击查看例子4
用offset五法正常显示的例子:点击查看例子5

那么我现在问你,如果我打算做一个跟随屏幕滚动的层,使用哪个方法呢?
如果你答得是:offset(),那么恭喜你。
如果我打算做一个类似于幻灯片的效果,你会使用哪个方法呢?

综上所述,使用position()还是offset()取决于你被控制的元素B DOM所在的位置。

来自 http://kb.cnblogs.com/page/48103/

1、offset()获取匹配元素在相对浏览器窗口的偏移量  返回一个对象,包括两个属性。left:相对浏览器窗口左边的距离。top:相对浏览器顶部的距离。

   $("#div1").offset().left;  //返回id为div1相对于浏览器窗口最左边的距离

   $("#div1").offset().top;  //返回id为div1相对于浏览器窗口最顶部的距离

  以下例子展示了,当点击文本框时,在下方显示一个日期div。紧紧贴住上面的文本框。并且不需要调div的css位置,无论上面的文本框位置如果变化,都能够紧紧且住上面的文本框,记得在前几天搞爱的车轮战报名系统的js模拟下拉列表的时候是调CSS贴住上面的文本框的,这样一旦改变了文本框的位置,模拟的下拉列表的div的css也要跟住调,其实这是很SB的。下面这个方法好。

复制代码
function showDiv(obj) {
  jQuery("#divShow").css("left", jQuery(obj).offset().left);  //设置#divShow与浏览器的左距离为文本框距离浏览器左边的距离。
  jQuery("#divShow").css("top", jQuery(obj).offset().top + jQuery(obj).outerHeight());  //设置#divShow距离顶部的距离为文本框距离顶部的距离加上自                                                 身高度。
  jQuery("#divShow").show();
}

<input type="text" value="ok" onclick="showDiv(this);" style="margin-left:100px;" />
<div id="divShow" style="display:none;position:absolute;">2010-03-22</div>
复制代码

2、position()获取匹配元素在相对父元素的偏移量  返回一个对象,包括两个属性。left:相对父元素最左边的距离。top:相对父元素最右边的距离。只对可见元素有效。

复制代码
<head>
    <title></title>
    <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn1").click(function () {
                var left = $("#div2").position().left;  //21.11111
                var top = $("#div2").position().top;    //33.33333
                alert("距离父元素顶部的距离是:" + left + "; 距离父元素左边的距离是:" + top);
            })
        })
    </script>
</head>
<body>
    <div id="div1" style="width:200px;height:400px;border:10px solid #000; padding:20px 20px; margin:30px 30px; position:relative;">
        <div id="div2" style="width:100px;height:200px; background-color:Green; position:absolute; left:22px; top:34px;">我是一个div元素</div>
        <input id="btn1" type="button" value="查看" />
    </div>
</body>
复制代码

    以上代码相当于javascript中的:

        function fun1() {
            var left = document.getElementById("div2").offsetLeft;  //21
            var top = document.getElementById("div2").offsetTop;   //33
            alert("距离父元素顶部的距离是:" + left + "; 距离父元素左边的距离是:" + top);
        }

    javascript比jQuery不同一点的地方就是它输出的是整数21,33,但是跟CSS设置的却差了一个像素,jQuery还能够用Math里的方法来还原,但是javascript就不知道怎么搞了。

 

3、scrollTop()    获取匹配元素距离滚动条顶部的距离,说白了就是边框的最顶部与当前显示出来的最顶部的距离。

   scrollTop(val)  设置匹配元素距离滚动条顶部的距离

  该属性常常配合scroll()事件一起使用,能够实现元素随滚动条的滚动而滚动,类似于漂浮广告效果。

  $(this).scroll(function(){

$("#div1").css("top", $(document).scrollTop());  //注意id为div1的div要设置为绝对定位。如果是底部漂浮,只需要$(document).scrollTop()加上相应的垂直距离就可以了。

  })

4、scrollLeft()     获取匹配元素距离滚动条顶部的距离,说白了就是边框的最左边与当前显示出来的最左边的距离。

   scrollLeft(val)  设置匹配元素距离滚动条顶部的距离

复制代码
<head>
    <title></title>
    <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn1").click(function () {
                var scrollTop = $("#div1").scrollTop();
                var scrollLeft = $("#div1").scrollLeft();
                alert("显示的最顶部距离真正的顶部的距离是:" + scrollTop + "; 显示的最左边距离真正的左边的距离是:" + scrollLeft);
            })
        })
    </script>
</head>
<body>
    <div id="div1" style="width:200px;height:400px;border:10px solid #000; padding:20px 20px; margin:30px 30px; overflow:scroll;">
        <div style="width:400px;height:800px;/*撑出滚动条*/">我是一个div元素</div>
        <input id="btn1" type="button" value="查看" />
    </div>
</body>
复制代码

5、height()    获取匹配元素的高度值  //不包括padding,不包括边框 val可以是字符串"300px"、也可以是数字300,还可以是一个函数,返回值作为参数

   height(val)    设置匹配元素的高度值  

6、 width()     获取匹配元素的宽度值  //不包括padding,不包括边框

  width(val)     设置匹配元素的宽度值

复制代码
<head>
    <title></title>
    <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn1").click(function () {
                var Width = $("#div1").width();   //200 css的width属性,不包括内边距、边框和外边距
                var Height = $("#div1").height(); //400 css的height属性,不包括内边距、边框和外边距
                alert("div1的宽度是:" + Width + "; div1的高度是:" + Height);
            })
        })
    </script>
</head>
<body>
    <div id="div1" style="width:200px;height:400px;border:10px solid #000; padding:20px 20px; margin:30px 30px;">
        我是一个div元素
        <input id="btn1" type="button" value="查看" />
    </div>
</body> 
复制代码

7、innerHeight()    获取匹配元素的高度值   //包括padding但不包括border

   innerHenght(val)  设置匹配元素的高度值

8、innerWidth()     获取匹配元素的宽度值  //包括padding但不包括border

   innerWidth(val)     设置匹配元素的宽度值

复制代码
<head>
    <title></title>
    <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn1").click(function () {
                var innerWidth = $("#div1").innerWidth();   //240 包括边框和内边距
                var innerHeight = $("#div1").innerHeight(); //440 包括边框和内边距
                alert("div1的宽度是:" + innerWidth + "; div1的高度是:" + innerHeight);
            })
        })
    </script>
</head>
<body>
    <div id="div1" style="width:200px;height:400px;border:10px solid #000; padding:20px 20px; margin:30px 30px;">
        我是一个div元素
        <input id="btn1" type="button" value="查看" />
    </div>
</body>
复制代码

以上的主jQuery相当于代码(javascript版):

function fun1() {
  var innerWidth = document.getElementById("div1").clientWidth;
  var innerHeight = document.getElementById("div1").clientHeight;
  alert("div1的宽度是:" + innerWidth + "div1的高度是:" + innerHeight);
}

9、 outerHeight()    获取元素的高度值  //包括padding和border

  outerHeight(val)    设置元素的高度值  

   还可以接受一个参数,该参数代表是否计算外边距,如果为true则表示计算外边距。

10、outerWidth()    获取匹配元素的宽度值  //(包括padding和border)

     outerWidth()     设置匹配元素的宽度值

  还可以接受一个参数,该参数代表是否计算外边距,如果为true则表示计算外边距。

复制代码
<head>
    <title></title>
    <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#btn1").click(function () {
                var outerWidth = $("#div1").outerWidth();   //260包括边框和内边距
                var outerHeight = $("#div1").outerHeight(); //460 包括边框和内边距
                alert("div1的宽度是:" + outerWidth + "; div1的高度是:" + outerHeight);

                var outerWidth1 = $("#div1").outerWidth(true);   //320 包括边框、外边距和内边距(也就是元素实际占用的大小)
                var outerHeight1 = $("#div1").outerHeight(true); //520 包括边框、外边距和内边距(也就是元素实际占用的大小)
                alert("div1的宽度是:" + outerWidth1 + "; div1的高度是:" + outerHeight1);
            })
        })
    </script>
</head>
<body>
    <div id="div1" style="width:200px;height:400px;border:10px solid #000; padding:20px 20px; margin:30px 30px;">
        我是一个div元素
        <input id="btn1" type="button" value="查看" />
    </div>
</body>
复制代码

     在jQuery的参数不为真的情况下,以上jQuery的主代码相当于:

        function fun1() {
            var outerWidth = document.getElementById("div1").offsetWidth;
            var outerHeight = document.getElementById("div1").offsetHeight;
            alert("div1的宽度是:" + outerWidth + "; div1的高度是:" + outerHeight);
        }

     如果参数为真的情况下,就相当于javascript:

        function fun1() {
            var div1 = document.getElementById("div1");
            var outerWidth1 = div1.offsetWidth + parseInt(div1.style.marginLeft) + parseInt(div1.style.marginRight);
            var outerHeight1 = div1.offsetHeight + parseInt(div1.style.marginTop) + parseInt(div1.style.marginBottom);
            alert("div1的宽度是:" + outerWidth1 + "; div1的高度是:" + outerHeight1);
        }

    此处可能写的不是很好,应该有更好的办法,本人javascript还在初学当中。


来自 http://www.cnblogs.com/kissdodog/archive/2012/12/09/2809770.html
普通分类: