[英]Detect whether an element has position:fixed (possibly by parent element) via jQuery
更新我想避免遍歷所有元素的父元素,依次測試每個元素,但這是我迄今為止設法找到的最佳解決方案,如本答案所示。
在事件處理程序中,我想檢測目標元素的位置是相對於視口(固定)還是文檔(靜態、相對或絕對)。
鑒於元素的位置可能是固定的,因為它具有“位置:固定”,或者因為它的父元素之一是“位置:固定”,那么檢測元素固定位置的有效方法是什么?
例如:
CSS
#one {position:relative; height:10px; width:10px}
#two-wrapper {position:fixed; bottom:0; height:10px; width:10px}
#two {height:10px; width:10px}
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
$(document).ready(function(){
$('.trigger-event').on('mouseenter', function(event){
var isFixed = .... ????
if (isFixed) {
$(event.target).css('background','red');
} else {
$(event.target).css('background','green');
}
});
});
這是一個基於遍歷元素的父元素的解決方案,依次檢查每個元素的 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
<div id="one" class="trigger-event">element one</div>
<div id="two-wrapper">
<div id="two" class="trigger-event">element two</div>
</div>
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');
}
});
});
使用$(selector).offsetParent()您可以搜索選擇器的祖先,而無需加載所有元素的父元素。 它仍然必須遍歷元素的父元素,但一旦找到具有所選位置(相對、絕對或固定)的最近元素,它就會停止。
http://jsfiddle.net/89y1buz9/11/
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:
<div id="outer">
<div id="inner">
<div id="clickme">ClickMe</div>
</div>
</div>
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;
}
用法:使用或不使用第二個參數調用它默認搜索固定元素
$(function () {
$("#clickme").on("click", function () {
if (isFixed($(this), "fixed") === "fixed") {
$(this).css("background", "red");
} else {
$(this).css("background", "green");
}
});
});
更新,見下文...
我在為此搜索純 javascript 解決方案時順便過來了……但我希望有人會喜歡我的 jquery 版本。
這里有兩個函數,它們的工作方式略有不同,但性能差異很小。 我沒有測量它,但根據對jsperf“每個 vs 過濾器”的測試, .each()
版本稍微快一些。
盡管如此,我還是喜歡.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;
};
用法是$('path > to > your > element').isfixed()
並返回true
或false
更新
這是純 javascript 版本。 事實證明,檢測el.style.position
(fixed/absolute/relative) 不起作用,不知道為什么,但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;
};
它接受三種元素參數:
作為 javascript 對象:
var obj = document.querySelector('div#myID > span');
或var obj = document.getElementById('span#someID');
作為 jquery 對象:
var obj = $('div#myID > span');
或僅作為選擇器:
var obj = 'div#myID > span';
用法很簡單isfixed(obj);
並提供布爾值true
或false
最后是混合解決方案(純 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;
};
用法: $('div#myID > span').isfixed()
如上面的例子。
希望你會喜歡。
這是我現在用來檢測可能嵌套在position:fixed
parent 中的元素的內容。 (基於另一個存在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
}
我采用了上面的一些示例並制作了簡單的 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>
$(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');
}
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.