javascript 通过jQuery检测元素是否具有位置:固定(可能由父元素)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19474320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 15:42:29  来源:igfitidea点击:

Detect whether an element has position:fixed (possibly by parent element) via jQuery

javascriptjqueryhtmlcsscss-position

提问by pppggg

UpdateI'd like to avoid walking back through all the element's parents, testing each in turn, but that is the best solution I've managed to find so far, as in this answer.

更新我想避免遍历所有元素的父元素,依次测试每个元素,但这是我迄今为止设法找到的最佳解决方案,如本答案所示



Inside an event handler, I would like to detect whether the target element's position is relative to the viewport (fixed) or the document (static, relative or absolute).

在事件处理程序中,我想检测目标元素的位置是相对于视口(固定)还是文档(静态、相对或绝对)。

Given that an element's position might be fixed because it has "position:fixed", or because one of its parents is "position:fixed", what is an efficient way of detecting fixed positioning for the element?

鉴于元素的位置可能是固定的,因为它具有“位置:固定”,或者因为它的父元素之一是“位置:固定”,那么检测元素固定位置的有效方法是什么?

For example:

例如:

CSS

CSS

#one {position:relative; height:10px; width:10px}

#two-wrapper {position:fixed; bottom:0; height:10px; width:10px}
#two {height:10px; width:10px}

HTML

HTML

<div id="one" class="trigger-event">element one</div>

<div id="two-wrapper">
    <div id="two" class="trigger-event">element two</div>
</div>

JS

JS

$(document).ready(function(){
    $('.trigger-event').on('mouseenter', function(event){
        var isFixed = .... ????

        if (isFixed) {
            $(event.target).css('background','red'); 
        } else {
            $(event.target).css('background','green'); 
        }
    });
});

回答by pppggg

Here is a solution based on walking through the element's parents, checking the CSS position value for each in turn.

这是一个基于遍历元素的父元素的解决方案,依次检查每个元素的 CSS 位置值。

Is this the most efficient way, or is there a way to detect the effective positioning by only examining the element itself?

这是最有效的方法,还是有一种方法可以通过仅检查元素本身来检测有效定位?

http://jsfiddle.net/Q4mSJ/

http://jsfiddle.net/Q4mSJ/

CSS

CSS

.trigger-event {background:#ccc}

#one {position:relative; height:50px; width:50px}

#two-wrapper {position:fixed; bottom:0; height:50px; width:50px}
#two {height:50px; width:50px}

HTML

HTML

<div id="one" class="trigger-event">element one</div>

<div id="two-wrapper">
    <div id="two" class="trigger-event">element two</div>
</div>

JS

JS

function elementOrParentIsFixed(element) {
    var $element = $(element);
    var $checkElements = $element.add($element.parents());
    var isFixed = false;
    $checkElements.each(function(){
        if ($(this).css("position") === "fixed") {
            isFixed = true;
            return false;
        }
    });
    return isFixed;
}

$(document).ready(function(){
    $('.trigger-event').on('mouseenter', function(event){
        var isFixed = elementOrParentIsFixed(event.target);

        if (isFixed) {
            $(event.target).css('background','red'); 
        } else {
            $(event.target).css('background','green'); 
        }
    });
});

回答by mathius1

Using $(selector).offsetParent()you can search through the ancestors of the selector without having to load all the elements parents. It will still have to walk through the elements parents but will stop once it finds the closest element with the chosen position (relative, absolute, or fixed).

使用$(selector).offsetParent()您可以搜索选择器的祖先,而无需加载所有元素的父元素。它仍然必须遍历元素的父元素,但一旦找到具有所选位置(相对、绝对或固定)的最近元素,它就会停止。

http://jsfiddle.net/89y1buz9/11/

http://jsfiddle.net/89y1buz9/11/

CSS:

CSS:

div {
border: 1px solid #ccc;
}
#outer {
    height: 200px;
    width: 120px;
    position: fixed;
    padding-top: 20px;
}
#inner {
        width: 95px;
    height: 150px;
    margin: 0px auto;
    position: relative;
}
#clickme {
    width: 70px;
    height: 50px;
    cursor: pointer;
    text-align: center;
    line-height: 40px;
    margin: 20px auto;
}

HTML:

HTML:

<div id="outer">
    <div id="inner">
        <div id="clickme">ClickMe</div>
    </div>
</div>

Javascript:

Javascript:

function isFixed(ele, posType) {
    var eleCheck = ele.offsetParent(),
        returnVal;
    posType = posType || "fixed";
    if (eleCheck.prop("tagName") === 'HTML') {
        return false;
    }
    returnVal = (eleCheck.css("position") !== posType) ? isFixed(eleCheck): posType;
    return returnVal;
}

Usage:Call it with or without the second argument it defaults to search for a fixed element

用法:使用或不使用第二个参数调用它默认搜索固定元素

$(function () {
    $("#clickme").on("click", function () {
        if (isFixed($(this), "fixed") === "fixed") {
            $(this).css("background", "red");
        } else {
            $(this).css("background", "green");
        }
    });
});

回答by ddlab

UPDATED, see below...

更新,见下文...

I dropped by here while searching a pure javascript solution for this... But I hope that somebody will like my jquery version.

我在为此搜索纯 javascript 解决方案时顺便到这里...但我希望有人会喜欢我的 jquery 版本。

Here are two functions, which work slightly different, but the performance differences are minimal. I did not measure it, but according this test on jsperf "each vs filter"the .each()version is slightly faster.

这里有两个函数,它们的工作方式略有不同,但性能差异很小。我没有测量它,但根据对jsperf“每个 vs 过滤器”的测试,该.each()版本稍微快一些。

Nevertheless, I like the .filter()version because it's so short and clear.

尽管如此,我还是喜欢这个.filter()版本,因为它非常简短明了。

$.fn.isfixed = function(){
    var el = $(this);
    var all = el.add(el.parents());
    return all.filter(function(){
        return $(this).css("position") === "fixed";
    }).length > 0;
};

$.fn.isfixed = function(){
    var el = $(this);
    var all = el.add(el.parents());
    var ret = false;
    all.each(function(){
        if ($(this).css("position") === "fixed") {
            ret = true;
            return false;
        }
    });
    return ret;
};

Usage is $('path > to > your > element').isfixed()and returns trueor false

用法是$('path > to > your > element').isfixed()并返回truefalse

UPDATE

更新

And here's the pure javascript version. It turned out, that to detect el.style.position(fixed/absolute/relative) does not work, don't know why, but window.getComputedStyle(el)...does.

这是纯 javascript 版本。事实证明,检测el.style.position(固定/绝对/相对)不起作用,不知道为什么,但window.getComputedStyle(el)...确实如此。

var isfixed = function(elm) {
    var el;
    if (typeof elm === 'object') el = elm[0] || elm;
    else if (typeof elm === 'string') el = document.querySelector(elm);
    while (typeof el === 'object' && el.nodeName.toLowerCase() !== 'body') {
        if (window.getComputedStyle(el).getPropertyValue('position').toLowerCase() === 'fixed') return true;
        el = el.parentElement;
    }
    return false;
};

It accepts three kind of element parameters:
as javascript object:
var obj = document.querySelector('div#myID > span');
or
var obj = document.getElementById('span#someID');

它接受三种元素参数:
作为 javascript 对象:
var obj = document.querySelector('div#myID > span');

var obj = document.getElementById('span#someID');

as jquery object:
var obj = $('div#myID > span');

作为 jquery 对象:
var obj = $('div#myID > span');

or as selector only:
var obj = 'div#myID > span';

或仅作为选择器:
var obj = 'div#myID > span';

Usage is simply isfixed(obj);and delivers boolean trueor false

用法很简单,isfixed(obj);并提供布尔值truefalse

And here's finally the mixed solution (pure javascript as jquery plugin)

最后是混合解决方案(纯 javascript 作为 jquery 插件)

$.fn.isfixed = function(){
    var el = this[0];
    while (typeof el === 'object' && el.nodeName.toLowerCase() !== 'body') {
        if (window.getComputedStyle(el).getPropertyValue('position').toLowerCase() === 'fixed') return true;
        el = el.parentElement;
    }
    return false;
};

Usage: $('div#myID > span').isfixed()as in examples above.
Hope you'll like it.

用法:$('div#myID > span').isfixed()如上面的例子。
希望你会喜欢。

回答by talsibony

I took some of the above examples and made simple js vanilla code to get position of element, so you can use it in jQuery and also without jQuery.

我采用了上面的一些示例并制作了简单的 js vanilla 代码来获取元素的位置,因此您可以在 jQuery 中使用它,也可以在没有 jQuery 的情况下使用它。

function getStylePosition(element){
  return window.getComputedStyle(element).getPropertyValue('position');
}

// use it like this
var element = document.getElementsByTagName('div')[0];
// js only
alert(getStylePosition(element));

// jQuery
alert(getStylePosition($('div')[0]));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:fixed;"></div>

回答by Robin Stewart

Here is what I am now using to detect elements that may be nested inside a position:fixedparent. (Based on another answerwhich had issues with nullvalues.)

这是我现在用来检测可能嵌套在position:fixed父级中的元素的方法。(基于另一个存在null价值问题的答案。)

// Returns true if `node` uses css position:fixed or has a parent that does so.
function isFixedPosition(node) {
    while (node && node.nodeName.toLowerCase() !== 'body') {
        if (window.getComputedStyle(node).getPropertyValue('position').toLowerCase() === 'fixed')
            { return true; }
        node = node.parentNode;
    }
    return false; // if got this far
}

回答by Mohsen Safari

$(document).ready(function(){
    $('.trigger-element').on('mouseenter', function(event){
        var position= $(this).css("position");

        if (position=="fixed") {
            $(event.target).css('background','red'); 
        } else {
            $(event.target).css('background','green'); 
        }
    });
});

jsFiddle

js小提琴