首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自定义jQuery事件仅触发一次

自定义jQuery事件仅触发一次
EN

Stack Overflow用户
提问于 2012-10-18 23:51:56
回答 1查看 583关注 0票数 2

我使用下面的代码来创建一个onshow事件:

代码语言:javascript
运行
复制
(function($){
  $.fn.extend({ 
    onShow: function(callback, unbind){
      return this.each(function(){
        var obj = this;
        var bindopt = (unbind==undefined)?true:unbind; 
        if($.isFunction(callback)){
          if($(this).is(':hidden')){
            var checkVis = function(){
              if($(obj).is(':visible')){
                callback.call();
                if(bindopt){
                  $('body').unbind('click keyup keydown', checkVis);
                }
              }                         
            }
            $('body').bind('click keyup keydown', checkVis);
          }
          else{
            callback.call();
          }
        }
      });
    }
  });
})(jQuery);

那我就叫它:

代码语言:javascript
运行
复制
$(document).ready(function(){

    $('.mydiv').onShow(function(){
        alert('myDiv is now showing');

    });

});

我还切换了触发div显示和隐藏的链接:

代码语言:javascript
运行
复制
$('.myLink').click(function(){
        $(".mydiv").slideToggle();
});

最后是html:

代码语言:javascript
运行
复制
<a href="#" class="myLink">Step 1</a>
        <div class="myDiv">content here</div>

问题是,在页面加载后,当我单击链接时,警报只显示一次。如果我再次点击它,我将不会显示。

你知道为什么吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-19 00:53:20

我认为这是对javascript中事件工作原理的误解。您的自定义扩展所做的就是运行一次。$('body').bind('click keyup keydown', checkVis);行侦听click keyup和keydown事件,但此侦听器仅应用于隐藏且已通过if($(this).is(':hidden')){检查的元素。

因此,如果有问题的元素开始隐藏,它将在“click keyup and keydown”上返回checkVis,但这是在onShow扩展第一次运行完成后运行的唯一实例。

默认情况下,.slideToggle();不会触发任何事件,因此您的扩展无法侦听要触发的此类事件。

最接近侦听元素可见性变化的方法是使用类似dom突变事件的方法,但该方法已被弃用,并且不支持跨浏览器。

如果您确实需要在元素被jQuery“显示”时运行扩展,我能想到的最好的方法就是扩展您希望用来触发自定义事件的jQuery函数,如下所示:

代码语言:javascript
运行
复制
    var existingSlideToggle = $.fn.slideToggle;

    $.fn.slideToggle = function(){
         var returner = existingSlideToggle(this, arguments);
         $(this).trigger('customOnShowEvent');
         return returner;
    }

然后你可以这样做:

代码语言:javascript
运行
复制
    $('#foo').on('customOnShowEvent', function(){  
       // do stuff 
    });

或者继续你的扩展策略:

代码语言:javascript
运行
复制
(function($){
  $.fn.extend({ 
    onShow: function(callback, unbind){
      return this.each(function(){
        var obj = this;
        var bindopt = (unbind==undefined)?true:unbind; 

        var localRun = function(){
          if($(obj).is(':hidden')){
            var checkVis = function(){
              if($(obj).is(':visible')){
                callback.call();
                if(bindopt){
                  $('body').unbind('click keyup keydown', checkVis);
                }
              }                         
            }
            $('body').bind('click keyup keydown', checkVis);
          }
          else{
            callback.call();
          }
        }

        if($.isFunction(callback)){
            localRun();
            $(obj).on('customOnShowEvent', localRun);
        }

      });
    }
  });
})(jQuery);

这样,它将在第一次运行,然后在新的“customOnShowEvent”被触发(“触发”)时重新运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12958653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档