当 div 可见时触发动作的 jQuery 事件

IT技术 javascript jquery
2021-01-27 15:33:34

我在我的网站中使用 jQuery,我想在某个 div 可见时触发某些操作。

是否可以将某种“可见”事件处理程序附加到任意 div 并在使 div 可见时运行某些代码?

我想要类似以下伪代码的东西:

$(function() {
  $('#contentDiv').isvisible(function() {
    alert("do something");
  });
});

alert("do something") 代码在 contentDiv 实际可见之前不应触发。

谢谢。

6个回答

您始终可以添加到原始.show()方法中,这样您就不必在每次显示某些内容或需要它来处理遗留代码时触发事件:

jQuery 扩展:

jQuery(function($) {

  var _oldShow = $.fn.show;

  $.fn.show = function(speed, oldCallback) {
    return $(this).each(function() {
      var obj         = $(this),
          newCallback = function() {
            if ($.isFunction(oldCallback)) {
              oldCallback.apply(obj);
            }
            obj.trigger('afterShow');
          };

      // you can trigger a before show if you want
      obj.trigger('beforeShow');

      // now use the old function to show the element passing the new callback
      _oldShow.apply(obj, [speed, newCallback]);
    });
  }
});

用法示例:

jQuery(function($) {
  $('#test')
    .bind('beforeShow', function() {
      alert('beforeShow');
    }) 
    .bind('afterShow', function() {
      alert('afterShow');
    })
    .show(1000, function() {
      alert('in show callback');
    })
    .show();
});

这有效地让您在执行 beforeShow 和 afterShow 的同时仍然执行原始 .show() 方法的正常行为。

您还可以创建另一个方法,这样您就不必覆盖原来的 .show() 方法。

无法让该代码与 ajax 响应触发的 div 可见性一起使用。
2021-03-17 15:33:34
好的,唯一的问题是fadeTo实现这个功能后功能不能正常工作
2021-03-19 15:33:34
新手来了 我不明白为什么可以在函数()声明之外引用 obj(和 newCallback),正如在 apply() 中看到的那样。我被告知用 var 声明会使变量成为局部变量,但删除“var”会使它们自动成为全局变量。
2021-03-19 15:33:34
编辑:此方法只有一个缺点:您必须为所有显示元素的方法重复相同的“扩展”:show()、slideDown() 等。需要更通用的方法来一次性解决此问题所有,因为不可能为 delegate() 或 live() 设置“就绪”事件。
2021-03-20 15:33:34
您的代码似乎不适用于最新的 jQuery(在此评论日期为 1.7.1)。我稍微修改了这个解决方案以使用最新的 jQuery:stackoverflow.com/a/9422207/135968
2021-04-03 15:33:34

DOM 突变观察者正在解决这个问题它们允许您将观察者(一个函数)绑定到更改 dom 元素的内容、文本或属性的事件。

随着IE11的发布,各大浏览器都支持这个功能,查看http://caniuse.com/mutationobserver

示例代码如下:

$(function() {
  $('#show').click(function() {
    $('#testdiv').show();
  });

  var observer = new MutationObserver(function(mutations) {
    alert('Attributes changed!');
  });
  var target = document.querySelector('#testdiv');
  observer.observe(target, {
    attributes: true
  });

});
<div id="testdiv" style="display:none;">hidden</div>
<button id="show">Show hidden div</button>

<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script>

可惜IE还不支持。caniuse.com/mutationobserver -> 查看支持它的浏览器。
2021-03-18 15:33:34
这在 Chrome 51 中似乎不起作用,不知道为什么。运行上面的代码并按下按钮,没有警报。
2021-03-22 15:33:34
在 chrome 中运行良好,但在黑莓 10 级联 webview 中不起作用(如果其他人在乎;))
2021-04-04 15:33:34
这确实有效,而且我不需要支持旧版浏览器,所以非常完美!我在这里添加了答案的 JSFiddle 证明:jsfiddle.net/DanAtkinson/26URF
2021-04-05 15:33:34
如果可见性更改是由被监视的祖先的属性更改引起的,则这似乎不起作用。
2021-04-06 15:33:34

没有您可以为此挂钩的本机事件,但是您可以在使用 . 触发功能

例如

//declare event to run when div is visible
function isVisible(){
   //do something

}

//hookup the event
$('#someDivId').bind('isVisible', isVisible);

//show div and trigger custom event in callback when div is visible
$('#someDivId').show('slow', function(){
    $(this).trigger('isVisible');
});
我在这里的限制是我不一定有权访问 show() 是我的 div 的代码。所以我将无法实际调用 trigger() 方法。
2021-03-21 15:33:34
@redsquare:如果show()从上面讨论的代码块以外的多个地方调用怎么办?
2021-03-26 15:33:34
对于此示例,您应该将函数名称更改为,onIsVisible因为现在“isVisible”的使用有点不明确。
2021-04-07 15:33:34
你总是可以用你自己的实现来标记他们的 js 函数。然而听起来很严峻!
2021-04-08 15:33:34
JS 是由我组织外的一个开发团队提供的。它也是一个“黑匣子”,因此我们不想尽可能修改该代码。不过,这可能是我们唯一的选择。
2021-04-10 15:33:34

您可以使用 jQuery 的Live Query 插件并编写代码如下:

$('#contentDiv:visible').livequery(function() {
    alert("do something");
});

然后每次 contentDiv 可见时,“做某事”都会被提醒!

没有为我工作。我收到错误“livequery 不是函数”。尝试了“jquery-1.12.4.min.js”和“jquery-3.1.1.min.js”
2021-03-23 15:33:34
好吧,那行得通。我考虑过它并拒绝了它,因为它不太可能起作用,没有尝试过。应该试过的。:)
2021-03-24 15:33:34
这可能会大大降低您的网站速度!livequery 插件对属性执行快速轮询,而不是使用现代高效的方法,例如 DOM 突变观察者。所以我更喜欢@hegemon 的解决方案:stackoverflow.com/a/16462443/19163(并且仅使用轮询作为旧 IE 版本的后备)– vog 1 小时前
2021-03-25 15:33:34
@Paul:这是一个插件
2021-03-26 15:33:34

redsquare 的解决方案是正确的答案。

但是作为一个理论中的解决方案,您可以编写一个函数来选择由.visibilityCheck不是所有可见元素分类的元素并检查它们的visibility属性值;如果true然后做某事。

之后,应定期使用该setInterval()功能执行该功能。您可以使用clearInterval()成功呼出后停止计时器

下面是一个例子:

function foo() {
    $('.visibilityCheck').each(function() {
        if ($(this).is(':visible')){
            // do something
        }
    });
}

window.setInterval(foo, 100);

您还可以对其进行一些性能改进,但是,该解决方案在实际中使用起来基本上是荒谬的。所以...

或者display:none
2021-03-14 15:33:34
我必须把它交给你,这很有创意,虽然很讨厌。而且它足够快速和肮脏,足以以符合 IE8 的方式为我解决问题。谢谢!
2021-03-22 15:33:34
在 setTimeout/setInterval 中使用隐含 func 的形式不是很好。使用 setTimeout(foo, 100)
2021-04-08 15:33:34