JavaScript 获取元素的坐标详解(4)

1 var Position = {};
2 (function () {
3    Position.getAbsolute = function (reference, target) {
4        var result = {
5            left: -target.clientLeft,
6            top: -target.clientTop
7         }
8        var node = target;
9        while(node != reference && node != document){
10            result.left = result.left + node.offsetLeft + node.clientLeft;
11            result.top = result.top + node.offsetTop + node.clientTop;
12            node = node.parentNode;
13         }
14        if(isNaN(reference.scrollLeft)){
15            result.right = document.documentElement.scrollWidth - result.left;
16            result.bottom = document.documentElement.scrollHeight - result.top;
17        }else {
18            result.right = reference.scrollWidth - result.left;
19            result.bottom = reference.scrollHeight - result.top;
20         }
21        return result;
22     }
23    Position.getViewport = function (target) {
24        var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
25        var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
26        var windowHeight = window.innerHeight || document.documentElement.offsetHeight;
27        var windowWidth = window.innerWidth || document.documentElement.offsetWidth;
28        var absolutePosi = this.getAbsolute(document, target);
29        var Viewport = {
30            left: absolutePosi.left - scrollLeft,
31            top: absolutePosi.top - scrollTop,
32            right: windowWidth - (absolutePosi.left - scrollLeft),
33            bottom: windowHeight - (absolutePosi.top - scrollTop)
34         }
35        return Viewport;
36     }
37 })();

  现在我们使用 Position.getViewport(targetNode) 方法可以获取元素左上角相对于窗口4个方向的定位:

1 Position.getViewport(targetNode); //{left: left, top: top, right: right, bottom: bottom}

  有了这个方法,现在就可以真正的判断元素是否在可视区域内了:

1 var Position = {};
2 (function () {
3    Position.getAbsolute = function (reference, target) {
4        //因为我们会将目标元素的边框纳入递归公式中,这里先减去对应的值
5        var result = {
6            left: -target.clientLeft,
7            top: -target.clientTop
8         }
9        var node = target;
10        while(node != reference && node != document){
11            result.left = result.left + node.offsetLeft + node.clientLeft;
12            result.top = result.top + node.offsetTop + node.clientTop;
13            node = node.parentNode;
14         }
15        if(isNaN(reference.scrollLeft)){
16            result.right = document.documentElement.scrollWidth - result.left;
17            result.bottom = document.documentElement.scrollHeight - result.top;
18        }else {
19            result.right = reference.scrollWidth - result.left;
20            result.bottom = reference.scrollHeight - result.top;
21         }
22        return result;
23     }
24    Position.getViewport = function (target) {
25        var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
26        var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
27        var windowHeight = window.innerHeight || document.documentElement.offsetHeight;
28        var windowWidth = window.innerWidth || document.documentElement.offsetWidth;
29        var absolutePosi = this.getAbsolute(document, target);
30        var Viewport = {
31            left: absolutePosi.left - scrollLeft,
32            top: absolutePosi.top - scrollTop,
33            right: windowWidth - (absolutePosi.left - scrollLeft),
34            bottom: windowHeight - (absolutePosi.top - scrollTop)
35         }
36        return Viewport;
37     }
38    Position.isViewport = function (target) {
39        var position = this.getViewport(target);
40        //这里需要加上元素自身的宽高,因为定位点是元素的左上角
41        if(position.left + target.offsetWidth < 0 || position.top + target.offsetHeight < 0){
42            return false;
43         }
44        if(position.bottom < 0 || position.right < 0){
45            return false;
46         }
47        return true;
48     }
49 })();

  判断理由很简单,如果有一边的定位是负值,那么元素就不在视窗内。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/7725245ec6fa33d3720f7762721443bb.html