元素何时可见的事件侦听器?

IT技术 javascript
2021-03-10 06:22:43

我正在构建一个将包含在页面中的工具栏。将要包含在其中的 div 将默认为display:none有没有办法可以在我的工具栏上放置一个事件侦听器来侦听它何时可见以便初始化?还是我必须从包含页面中传递一个变量?

谢谢

6个回答

展望未来,您正在寻找新的 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:

function 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);
}

在行动:https : //jsfiddle.net/elmarj/u35tez5n/5/

@PeterMoore 一旦您停止尝试支持它。只是不要。
2021-04-27 06:22:43
IE 对这种酷炫的东西缺乏支持何时才能停止破坏我们的生活?
2021-05-03 06:22:43
哈哈。有时这不是我们的决定。
2021-05-03 06:22:43
请注意,InteractionObserver 目前不适用于 Safari。caniuse.com/#feat=intersectionobserver看起来有一个补丁正在进行中。bugs.webkit.org/show_bug.cgi?id=159475
2021-05-12 06:22:43
> Intersection Observer API 允许您配置一个回调,只要一个元素(称为目标)与设备视口或指定元素相交,就会调用该回调;
2021-05-15 06:22:43
var targetNode = document.getElementById('elementId');
var observer = new MutationObserver(function(){
    if(targetNode.style.display != 'none'){
        // doSomething
    }
});
observer.observe(targetNode, { attributes: true, childList: true });

我可能有点晚了,但您可以使用 MutationObserver 来观察所需元素的任何变化。如果发生任何更改,您只需检查元素是否显示。

点赞!我在另一个 stackoverflow 答案中使用了这个:stackoverflow.com/questions/48792245/...
2021-04-25 06:22:43
实际上,在这里使用的正确观察者是IntersectionObserver- stackoverflow.com/a/52627221/2803743
2021-04-26 06:22:43
不幸的是,这只适用于在元素上使用内联样式时,而不是当更改是 CSS 类更改的结果时(这是更有可能的情况,因为在前一种情况下您可能已经拥有完整的程序控制)。显示问题的小提琴:jsfiddle.net/elmarj/uye62Lxc/4有关如何观察样式更改的更完整讨论,请参见此处:dev.to/oleggromov/observing-style-changes---d4f
2021-04-27 06:22:43
这在 targetNode 未显示时不起作用,因为祖先未显示但随后被显示。
2021-04-30 06:22:43
当您想要打开和关闭元素,并且无法直接控制该元素,并且想要对显示值更改做出反应时,此解决方案很有用
2021-05-14 06:22:43

至少有一种方法,但不是很好的方法。您可以轮询元素以进行如下更改:

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);

DOM 标准还指定了mutation events,但我从来没有机会使用它们,我不确定它们的支持程度。你会像这样使用它们:

target.addEventListener('DOMAttrModified', function()
{
    if (e.attrName == 'style') {
        alert('style changed');
    }
}, false);

这段代码不在我的脑海中,所以我不确定它是否有效。

最好的,最简单的解决办法是在显示你的目标功能的回调。

MutationObserver是新的。
2021-04-18 06:22:43
有意思,谢谢。几年后,DOMAttrModified 的状态发生了变化:“已弃用。此功能已从 Web 标准中删除。尽管某些浏览器可能仍支持它,但正在被删除。” (Mozilla)
2021-04-22 06:22:43

我遇到了同样的问题,并为我们的网站创建了一个 jQuery 插件来解决它。

https://github.com/shaunbowe/jquery.visibilityChanged

根据您的示例,您将如何使用它:

$('#contentDiv').visibilityChanged(function(element, visible) {
    alert("do something");
});
此解决方案.is(':visible')setTimeout.
2021-04-23 06:22:43

正如@figha 所说,如果这是您自己的网页,那么您应该在使元素可见后运行您需要运行的任何内容。

然而,为了回答这个问题(以及任何制作 Chrome 或 Firefox Extensions 的人,这是一个常见的用例),Mutation SummaryMutation 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);

react包括addedremovedvalueChanged和更多valueChanged包括所有属性,包括display等。

@AlexHolsgrove 我从链接中添加了一个示例。由于海报谈到向页面添加工具栏,看起来他们可能正在向第三方页面添加工具栏并等待将元素添加到 DOM,在这种情况下,Mutations 是最好的 API。
2021-04-15 06:22:43
请注意,这仍然没有涵盖解释“可见性”在突变观察过程中的位置的那部分。
2021-04-15 06:22:43
可能是因为他想知道它什么时候真正出现在屏幕上。我是的,我只能假设downvoter 有同样的原因。
2021-04-21 06:22:43
不回答问题,不建议只发布链接。
2021-05-15 06:22:43