js判断某元素是否真的可见(以人的视角的可见)

代码如下:

function isElementVisible(el) {
        var rect = el.getBoundingClientRect(),
            vWidth = window.innerWidth || document.documentElement.clientWidth,
            vHeight = window.innerHeight || document.documentElement.clientHeight,
            efp = function (p, x, y) {
                var els = document.elementsFromPoint(x, y); // 获取某点的所有元素, 最顶层的元素在最前面
                for (var index = 0; index < els.length; index++) {
                    var style = getComputedStyle(els[index]);
                    // 如果此前的元素是半透明的,并且不是当前元素,则跳过当前元素
                    if (p != els[index] && (style.opacity < 1 || style.display == 'none' || ['collapse', 'hidden'].indexOf(el.style.visibility) == -1)) {
                        continue;
                    } else return els[index];
                }
                return els[0];
            };

        // Return false if it's not in the viewport
        if (rect.right < 0 || rect.bottom < 0
            || rect.left > vWidth || rect.top > vHeight)
            return false;
  
        return (
            el.contains(efp(el, rect.left, rect.top))
            || el.contains(efp(el, rect.right, rect.top))
            || el.contains(efp(el, rect.right, rect.bottom))
            || el.contains(efp(el, rect.left, rect.bottom)))
            || el.contains(efp(el, rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2));
    }

大致思路:

  1. 先判断元素是否在视窗区域内(视窗指浏览器窗口,webview的窗口)
  2. 在判断元素的四角和中心点是否在最顶层,如果有遮罩则去掉遮罩的影响(遮罩比如是透明或者半透明的元素)