我正在构建一个将包含在页面中的工具栏.它将被包括在内的div将默认为display:none.有没有办法我可以在我的工具栏上放置一个事件监听器,以便在它变得可见时进行监听,以便初始化?或者我是否必须从包含页面传递变量?
谢谢
Elm*_*sen 46
展望未来,新的HTML Intersection Observer API是您正在寻找的东西.它允许您配置一个称为目标的元素与设备视口或指定元素相交时调用的回调.它可用于最新版本的Chrome,Firefox和Edge.有关详细信息,请参阅https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API.
观察显示的简单代码示例:无切换:
// Start observing visbility of element. On change, the
// the callback is called with Boolean visibility as
// argument:
respondToVisibility(element, callback) {
var options = {
root: document.documentElement
}
var observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
callback(entry.intersectionRatio > 0);
});
}, options);
observer.observe(element);
}
Run Code Online (Sandbox Code Playgroud)
在行动:https://jsfiddle.net/elmarj/u35tez5n/5/
joe*_*joe 43
如果您只想在元素在视口中可见时运行一些代码:
function onVisible(element, callback) {
new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.intersectionRatio > 0) {
callback(element);
observer.disconnect();
}
});
}).observe(element);
if(!callback) return new Promise(r => callback=r);
}
Run Code Online (Sandbox Code Playgroud)
当元素变得可见(轻微事件)时,交集观察者会调用callback
并用 销毁自身.disconnect()
。
像这样使用它:
onVisible(document.querySelector("#myElement"), () => console.log("it's visible"));
Run Code Online (Sandbox Code Playgroud)
或者像这样:
await onVisible(document.querySelector("#myElement"));
console.log("it's visible");
Run Code Online (Sandbox Code Playgroud)
如果您希望在元素完全可见时触发回调,那么您应该更改entry.intersectionRatio > 0
为entry.intersectionRatio === 1
.
如果在调用 时该元素已经可见onVisible
,则回调将立即触发。
相关:如果您想立即获取true
或来了解该元素当前false
是否可见,请使用此代码(更改以满足您的要求)。intersectionRatio
小智 34
var targetNode = document.getElementById('elementId');
var observer = new MutationObserver(function(){
if(targetNode.style.display != 'none'){
// doSomething
}
});
observer.observe(targetNode, { attributes: true, childList: true });
Run Code Online (Sandbox Code Playgroud)
我可能有点晚了,但您可以使用MutationObserver观察所需元素的任何变化.如果发生任何更改,您只需检查元素是否显示.
sli*_*kts 14
至少有一种方法,但它不是一个很好的方法.您可以只轮询元素以进行更改,如下所示:
var previous_style,
poll = window.setInterval(function()
{
var current_style = document.getElementById('target').style.display;
if (previous_style != current_style) {
alert('style changed');
window.clearInterval(poll);
} else {
previous_style = current_style;
}
}, 100);
Run Code Online (Sandbox Code Playgroud)
DOM标准还指定了突变事件,但我从未有机会使用它们,我不确定它们的支持程度如何.你会像这样使用它们:
target.addEventListener('DOMAttrModified', function()
{
if (e.attrName == 'style') {
alert('style changed');
}
}, false);
Run Code Online (Sandbox Code Playgroud)
这段代码不在我的脑海中,所以我不确定它是否有效.
将最好的,最简单的解决办法是在显示你的目标功能的回调.
Sha*_*owe 14
我有同样的问题,并创建了一个jQuery插件来解决我们的网站.
https://github.com/shaunbowe/jquery.visibilityChanged
以下是根据您的示例使用它的方法:
$('#contentDiv').visibilityChanged(function(element, visible) {
alert("do something");
});
Run Code Online (Sandbox Code Playgroud)
mal*_*lef 12
Javascript事件处理用户交互,如果你的代码足够有条理,你应该能够在可见性发生变化的同一个地方调用初始化函数(即你不应该myElement.style.display
在很多地方改变,而是调用一个函数/方法这和你可能想要的任何其他东西).
正如@figha所说,如果这是你自己的网页,你应该在你使元素可见之后运行你需要运行的任何东西.
但是,为了回答问题(以及任何制作Chrome或Firefox Extensions的人,这是一个常见的用例),Mutation Summary和Mutation Observer将允许DOM更改来触发事件.
例如,为具有data-widget
添加到DOM的属性的元素触发事件.借用David Walsh的博客中的这个优秀例子:
var observer = new MutationObserver(function(mutations) {
// For the sake of...observation...let's output the mutation to console to see how this all works
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// Notify me of everything!
var observerConfig = {
attributes: true,
childList: true,
characterData: true
};
// Node, config
// In this case we'll listen to all changes to body and child nodes
var targetNode = document.body;
observer.observe(targetNode, observerConfig);
Run Code Online (Sandbox Code Playgroud)
反应包括added
,removed
,valueChanged
和更多.valueChanged
包括所有属性,包括display
等.
一个简单的解决方案(甚至适用于嵌套元素)是使用 ResizeObserver。
它应该适用于所有现代浏览器(https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API)。
当一个元素display: none
应用了 css 规则(无论是直接还是通过祖先元素)时,它的所有尺寸都将为零。因此,为了检测变得可见,我们只需要一个可见时尺寸非零的元素。
const element = document.querySelector("#element");
const resizeWatcher = new ResizeObserver(entries => {
for (const entry of entries) {
console.log("Element", entry.target,
(entry.contentRect.width === 0) ?
"is now hidden" :
"is now visible"
)
}
});
resizeWatcher.observe(element)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
113037 次 |
最近记录: |