zoukankan      html  css  js  c++  java
  • JavaScript如何获取/计算页面元素的offset?

    问题 

    通过点击一控件,在控件的下面显示一个浮动层,通常的做法是:获取此控件的offset值,再计算出浮动层的topleft等css属性的值,赋值即可。

    那么下面就看一下如何获取控件的offset值。

    纯JS的实现

    首先想到的是这样的一段js。

    document.getElementById("divFloat").style.top=document.getElementById("Button").offsetLeft+25;

    发现需要添加值单位,那么就修改成下面这样子:

    IETester和FireFox再测试下,IE6+下都可以,如以前一样,写出的纯js的方法无情地被FireFox鄙视了,获取的值不正确。

    网上再查了下,发现应该这样写,通过循环,层层向上计算,最后得到准确的offset值。

    function getOffsetLeft(o)
    {
    	var left=0;
    	var offsetParent = o;
    	while (offsetParent != null && offsetParent != document.body)
    	{
    		left += offsetParent.offsetLeft;
    		offsetParent = offsetParent.offsetParent;
    	}
    
    	return left;
    }

    jQuery的实现

    再细一步去查相关问题时发现jQuery中已经包含了实现此功能的函数:offset(),很好地兼容了各浏览器。

    $("#Button").offset().left

    还有一个函数是:position(),两者详细的对比分析在这里:深入剖析Jquery中的offset()和position()

    下载源码后发现jQuery是这样实现的

    jQuery.fn.extend({
        position: function() {
            if ( !this[0] ) {
                return null;
            }
    
            var elem = this[0],
    
            // Get *real* offsetParent
            offsetParent = this.offsetParent(),
    
            // Get correct offsets
            offset       = this.offset(),
            parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { 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  -= parseFloat( jQuery.curCSS(elem, "marginTop",  true) ) || 0;
            offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
    
            // Add offsetParent borders
            parentOffset.top  += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth",  true) ) || 0;
            parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
    
            // Subtract the two offsets
            return {
                top:  offset.top  - parentOffset.top,
                left: offset.left - parentOffset.left
            };
        },
    
        offsetParent: function() {
            return this.map(function() {
                var offsetParent = this.offsetParent || document.body;
                while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
                    offsetParent = offsetParent.offsetParent;
                }
                return offsetParent;
            });
        }
    });

    计算方式大同小异,不过有一点需注意的是:

    offset() 函数的计算 不包括margin值(但包含border值)

    延伸阅读:

    关于jQuery中的offset()和position()的用法

    jQuery入门(2)使用jQuery操作元素的属性与样式

  • 相关阅读:
    0326系统按钮添加权限的工作(jsp权限写法)
    0321菜单数据
    ztree树的递归
    前端padding margin
    解决1像素边框问题
    水平垂直居中
    移动端css公共样式
    tap方法改良this指向
    移动端常见问题
    前端笔记(兼容)
  • 原文地址:https://www.cnblogs.com/52php/p/5666389.html
Copyright © 2011-2022 走看看