前端获取元素定位位置的法宝

在前端开发中,我们经常需要定位一个元素。如tooltip、popover或者modal等,或许是我们需要将它们定位在依赖元素的周围或屏幕滚动屏幕中心位置。这对于前端开发的码农来说并不是难事。算出和依赖元素的offset,设置元素的left、right。对于稍复杂的场景我们可能需要考虑被positioned的祖先元素。

但往往不是所有的事情都是这么简单的。笔者最新在项目开发中就遇见这样一个问题:这里的HTML是嵌入的,其来自jpedal商业软件从PDF文件自动生成的;为了展示的样式,jpedal统一使用了 position:absolute和relative来定位PDF元素。然而由于业务的需求,我们需要操作这类HTML。其中一个需求就是需要在每段文字附近显示操作工具条。

对于这类未知的DOM定位,那么我们就需要遍历它的DOM树来计算它的相对位置了。行为下面的这段代码:

    function isStaticPositioned(element) {
      return (getStyle(element, 'position') || 'static' ) === 'static';
    }

    var parentOffsetEl = function(element) {
      var docDomEl = $document[0];
      var offsetParent = element.offsetParent || docDomEl;
      while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
        offsetParent = offsetParent.offsetParent;
      }
      return offsetParent || docDomEl;
    };

在这里,我们会根据元素递归查询它所在的的DOM树中被positioned的最接近的祖先元素,然后才计算它们的相对位置。

这是一段来自Angular-UI bootstrap的$position服务的源码。这也是本文将要提到的获取定位元素位置的法宝。其源码位置在https://github.com/angular-ui/bootstrap/blob/master/src/position/position.js

在$position服务中为我们提供了3个有用的位置服务:position、offset和positionElements。position是计算具体元素的定位位置,返回一个带有width、height、top、left的对象;positionElements则是返回某元素相对于其依赖容器元素的定位位置,一个带有top、left的对象。

笔者为了测试这写API,在jsbin中写了一个特定的指令:

JavaScript:

angular.module("com.ngbook.demo", ['ui.bootstrap.position'])
.directive('position', ['$position', function($position){
    return {
        restrict: 'EA',
        templateUrl: '/position.html',
        scope:{
            title:"@"
        },
        link:function(scope, elm, iAttrs){
        scope.data =  $position.position(elm);
       }
    };
}]);

HTML:

<script type="text/ng-template" id="/position.html">
   <table class="table">
       <thead>
           <th colspan="2">{{title}}</th>
       </thead>
    <tbody>
       <tr ng-repeat="field in ['width', 'height', 'left', 'top']">
       <td>{{field}}</td>
       <td>{{data[field]}}</td>
     </tr>
    </tbody>
   </table>
 </script>

所以我们可以如下测试这类API:

<position title ="no positioned parent"></position>

<div style="position: relative;padding:50px;">
    <position title ="relative parent"></position>

     <div style="position: absolute;top:250px; padding:50px;">
         <position title="relative->absolute parent"></position>
     </div>
 </div>

 <div style="position: absolute;top:0px;left:250px; padding:50px;">
         <position title="absolute parent"></position>
 </div>

其效果可以在jsbin demo:

同样你也可以在官方的文档中看见对它的测试: https://github.com/angular-ui/bootstrap/blob/master/src/position/test/test.html

简单的说:如果我们需要获取某个元素的定位信息,则我们可以用 $position.position(element);获取相对于固定元素的定位,则可以使用$position.positionElements(hostEl, targetEl, positionStr, appendToBody)。其中positionStr是一个横向和纵向的字符串,如:”top-left”、”bottom-left”。其默认值为center。如笔者项目所期望的在某文字段落的左上角显示工具条:

$position.after($toolbar);
var elPosition = $position.positionElements($paragraph, $toolbar, “top-left”);
$toolbar.css({left: elPosition.left + 'px', top: elPosition.top + 'px'});

当然也不要忘记为toolbar元素设置position: absolute;

作者:破  狼 
出处:http://www.cnblogs.com/whitewolf/ 
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼。http://www.cnblogs.com/whitewolf/p/4792360.html

时间: 2024-12-01 14:19:54

前端获取元素定位位置的法宝的相关文章

多浏览器兼容的获取元素和鼠标的位置的js代码_javascript技巧

复制代码 代码如下: //获取元素的位置 function getLeft(obj) { if (obj == null) return null; var mendingObj = obj; var mendingLeft = mendingObj.offsetLeft; while (mendingObj != null && mendingObj.offsetParent != null && mendingObj.offsetParent.tagName != &q

js获取元素相对窗口位置的实现代码_javascript技巧

JS获取元素的offsetTop,offsetLeft等属性 obj.clientWidth //获取元素的宽度 obj.clientHeight //元素的高度 obj.offsetLeft //元素相对于父元素的left obj.offsetTop //元素相对于父元素的top obj.offsetWidth //元素的宽度 obj.offsetHeight //元素的高度 区别: clientWidth = width + padding clientHeight = height + p

用Javascript 获取页面元素的位置的代码_javascript技巧

下面的教程总结了Javascript在网页定位方面的相关知识. 一.网页的绝对大小和相对大小 首先,要明确两个基本概念. 一张网页的全部面积,就是它的绝对大小.通常情况下,网页的绝对大小由内容和CSS样式表决定. 网页的相对大小则是指在浏览器窗口中看到的那部分网页,也就是浏览器窗口的大小,又叫做viewport(视口). 下图中央的方框就代表浏览器窗口,每次只能显示一部分网页. (图一 网页的绝对大小和相对大小) 很显然,如果网页的内容能够在浏览器窗口中全部显示(也就是不出现滚动条),那么网页的

用Javascript获取页面元素的位置

制作网页的过程中,你有时候需要知道某个元素在网页上的确切位置. 下面的教程总结了Javascript在网页定位方面的相关知识. 一.网页的大小和浏览器窗口的大小 首先,要明确两个基本概念. 一张网页的全部面积,就是它的大小.通常情况下,网页的大小由内容和CSS样式表决定. 浏览器窗口的大小,则是指在浏览器窗口中看到的那部分网页面积,又叫做viewport(视口). 很显然,如果网页的内容能够在浏览器窗口中全部显示(也就是不出现滚动条),那么网页的大小和浏览器窗口的大小是相等的.如果不能全部显示,

JQuery获取元素文档大小、偏移和位置和滚动条位置的方法集合_jquery

因为浏览器的兼容问题,如果使用javascript获取这些数值是一个相当痛苦的过程.好在JQuery提供了简单优雅,并且兼容的解决方法. 获取浏览器和页面文档的宽度和高度 复制代码 代码如下: //获取浏览器显示区域的高度 $(window).height(); //获取浏览器显示区域的宽度 $(window).width(); //获取页面的文档高度 $(document.body).height(); //获取页面的文档宽度 $(document.body).width(); 获取滚动条的位

Java 获取元素在数组中的位置

在Java 中如何获取元素在数组中的位置呢? (1) Java代码   /***       * Get location of element in a array       * @param arr : a array       * @param value2 : element of array       * @return       */       public static int indexOfArr(String[] arr,String value2){        

js getBoundingClientRect() 来获取页面元素的位置_javascript技巧

document.documentElement.getBoundingClientRect 下面这是MSDN的解释: Syntax oRect = object.getBoundingClientRect() Return Value Returns a TextRectangle object. Each rectangle has four integer properties (top, left, right, and bottom) that represent a coordina

js获取元素在浏览器中的绝对位置_javascript技巧

JavaScript中提供获取HTML元素位置的属性: HTMLElement.offsetLeft HTMLElement.offsetHeight 但 是需要注意的是,这两个属性所储存的数值并不是该元素相对整个浏览器画布的绝对位置,而是相对于其父元素位置的相对位置,也就是说这两个数值得到的是以其 父元素左上角为(0,0)点从而计算出的数值.那么如何得到一个HTML元素的绝对位置呢,可以用以下函数: 复制代码 代码如下: //获取元素的纵坐标 function getTop(e){ var o

javascript获取元素位置/窗口高度代码

document元素的clientHeight和clientWidth属性,就代表了网页的大小.  代码如下 复制代码 function getViewport(){ if (document.compatMode == "BackCompat"){ return { width: document.body.clientWidth, height: document.body.clientHeight } } else { return { width: document.docum