我正在构建一个要包含在页面中的工具栏。将要包含的div将默认为display:none。有什么方法可以在我的工具栏上放置一个事件侦听器,以便在它可见时进行侦听,以便可以初始化?还是我必须将其从包含页面传递给变量?
谢谢
我正在构建一个要包含在页面中的工具栏。将要包含的div将默认为display:none。有什么方法可以在我的工具栏上放置一个事件侦听器,以便在它可见时进行侦听,以便可以初始化?还是我必须将其从包含页面传递给变量?
谢谢
Answers:
Javascript事件处理用户交互,如果您的代码组织得足够好,则应该可以在可见性发生变化的同一位置调用初始化函数(即,您不应该myElement.style.display在很多地方进行更改,而是调用执行该功能的方法/方法)这个以及您可能想要的其他任何东西)。
展望未来,您正在寻找新的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);
}
var targetNode = document.getElementById('elementId');
var observer = new MutationObserver(function(){
if(targetNode.style.display != 'none'){
// doSomething
}
});
observer.observe(targetNode, { attributes: true, childList: true });
我可能会晚一点,但是您可以使用MutationObserver观察所需元素的任何更改。如果发生任何更改,则只需检查是否显示了该元素。
IntersectionObserver- stackoverflow.com/a/52627221/2803743
至少有一种方法,但这不是一个很好的方法。您可以只轮询元素以进行如下更改:
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标准还指定了突变事件,但是我从来没有机会使用它们,而且我不确定它们的支持程度。您将像这样使用它们:
target.addEventListener('DOMAttrModified', function()
{
if (e.attrName == 'style') {
alert('style changed');
}
}, false);
这段代码是我的头等大事,所以我不确定它是否有效。
将最好的,最简单的解决办法是在显示你的目标功能的回调。
我遇到了同样的问题,并创建了一个jQuery插件来解决我们网站的问题。
https://github.com/shaunbowe/jquery.visibilityChanged
根据示例,使用方法如下:
$('#contentDiv').visibilityChanged(function(element, visible) {
alert("do something");
});
.is(':visible')与一起使用setTimeout。
如@figha所说,如果这是您自己的网页,则在使元素可见后,只需运行需要运行的任何内容。
但是,出于回答问题(以及任何使用Chrome或Firefox扩展程序的人,这是一个常见的用例)的目的,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);
反应包括added,removed,valueChanged和更多。valueChanged包括所有属性,包括display等。
您也可以尝试以下jQuery插件:https : //github.com/morr/jquery.appear
仅在评论DOMAttrModified事件侦听器浏览器支持时:
跨浏览器支持
在不同的浏览器中,这些事件的实现方式不一致,例如:
版本9之前的IE根本不支持突变事件,并且在版本9中无法正确实现其中的某些事件(例如DOMNodeInserted)
WebKit不支持DOMAttrModified(请参阅webkit错误8191和解决方法)
Firefox(自版本11起)不支持“突变名称事件”,即DOMElementNameChanged和DOMAttributeNameChanged,并且在其他浏览器中也不受支持。
来源:https : //developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
我的解决方案:
; (function ($) {
$.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = $.fn[ name ];
$.fn[ name ] = function( speed, easing, callback ) {
if(speed == null || typeof speed === "boolean"){
var ret=cssFn.apply( this, arguments )
$.fn.triggerVisibleEvent.apply(this,arguments)
return ret
}else{
var that=this
var new_callback=function(){
callback.call(this)
$.fn.triggerVisibleEvent.apply(that,arguments)
}
var ret=this.animate( genFx( name, true ), speed, easing, new_callback )
return ret
}
};
});
$.fn.triggerVisibleEvent=function(){
this.each(function(){
if($(this).is(':visible')){
$(this).trigger('visible')
$(this).find('[data-trigger-visible-event]').triggerVisibleEvent()
}
})
}
})(jQuery);
例如:
if(!$info_center.is(':visible')){
$info_center.attr('data-trigger-visible-event','true').one('visible',processMoreLessButton)
}else{
processMoreLessButton()
}
function processMoreLessButton(){
//some logic
}