关于获取控件的offset

简介: 问题 通过点击一控件,在控件的下面显示一个浮动层,通常的做法是:获取此控件的offset值,再计算出浮动层的top,left等css属性的值,赋值即可。 那么下面就看一下如何获取控件的offset值。

问题

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

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

纯JS的实现

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

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

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

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

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;
        });
    }
});

没有太理解,先贴在这里了!


作者:Parry
出处:http://www.cnblogs.com/parry/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

相关文章
|
6月前
|
前端开发 JavaScript
设置控件不能点击(pointer-events)
设置控件不能点击(pointer-events)
35 0
|
6月前
|
JavaScript
element-UI el-table动态显示隐藏列造成固定一侧的列(fixed=“left/right“)错误显示
问题原因:多个tabs共用一个实体,动态显示隐藏列 出现了固定在右侧的列(fixed="right")错位 【解决方案】 表格的重新布局,只要table数据发生变化的时候就重新渲染表格 ```js this.$nextTick(() => { this.$refs.formname.doLayout() }) ``` 参考element官方文档 ![请在此添加图片描述](https://developer-private-1258344699.cos.ap-guangzhou.myqcloud.com/column/article/5877188/20231030-e40
83 0
element-UI el-table动态显示隐藏列造成固定一侧的列(fixed=“left/right“)错误显示
页面中的位置:client、page、screen、offset、以及元素视图位置的区别和方法
页面中的位置:client、page、screen、offset、以及元素视图位置的区别和方法
|
6月前
Cocos Creator3.8 项目实战(三)去除scrollview背景色和label 对齐方式设置无效问题解决
Cocos Creator3.8 项目实战(三)去除scrollview背景色和label 对齐方式设置无效问题解决
|
9月前
offset、client、scroll三大系列
offset、client、scroll三大系列
45 0
|
10月前
|
JavaScript
BOM ------ offset (元素偏移量)
BOM ------ offset (元素偏移量)
使用bootstrap-table-fixed-columns固定表格列时底部滑动出现BUG
使用bootstrap-table时数据列过多,又想某列特殊显示?推荐你使用bootstrap-table-fixed-columns来解决吧!使用时需要注意 bootstrap-table和bootstrap-table-fixed-columns尽量保持一致,以防奇怪问题出现
515 0
使用bootstrap-table-fixed-columns固定表格列时底部滑动出现BUG
ViewPager2实现内部Item的动态滚动
最近接到了一个需求,大概类似如下图所示的一个样式(省略了部分细节,不影响大概)。
274 0
【Flutter】GridView 网格布局 ( GridView.count 构造函数 | crossAxisCount 参数指定每行元素个数 )
【Flutter】GridView 网格布局 ( GridView.count 构造函数 | crossAxisCount 参数指定每行元素个数 )
460 0
【Flutter】GridView 网格布局 ( GridView.count 构造函数 | crossAxisCount 参数指定每行元素个数 )