【问题标题】:Multiple events fired in jquery function在 jquery 函数中触发多个事件
【发布时间】:2016-01-26 17:16:30
【问题描述】:

我有一个由每一行中的评论链接组成的html网格表。点击任何一个都会打开一个带有文本框和保存按钮的引导模式。所以我编写了一个包含与该评论系统相关的函数的库。下面是基本代码。

HTML:

        <td><a class="addComment"  data-notedate="somevalue" data-toggle='modal'  href='#addnotesdiv' data-oprid="somevalue" data-soid="somevalue"  data-type="1"><i class="fa fa-comments-o fa-2"></i></a></td> ..... n

JS:

    var Inventory={};

Inventory.notes={
defaults:{
                        type:'1',
                        soid:0,
                        operator_id:0,
                        date:'',
                        target:'div#addnotesdiv',
                  },
init:function()
{
   var self=this;

   $('div#addnotesdiv').on('show.bs.modal',function(e){
            self.getandsetdefaults(e);
            self.setmodalelements(e);
            self.getNotes();
            self.addnote();
            self.activaterefresh();
   });


},
getandsetdefaults:function(e)
{
     this.defaults.soid = $(e.relatedTarget).data('soid');
     this.defaults.operator_id=$(e.relatedTarget).data('oprid');
     this.defaults.type=$(e.relatedTarget).data('type');
     this.defaults.date=$(e.relatedTarget).data('notedate');

},
setmodalelements:function(e)
{
    $(e.currentTarget).find('#notesthread').empty();
    $(e.currentTarget).find('input#inpnotesoid').val(this.defaults.soid);
    $(e.currentTarget).find('input#inpnoteoprid').val(this.defaults.operator_id);
    $(e.currentTarget).find('input#inpnotetype').val(this.defaults.type);
},
addnote:function()
{
         var self=this;

        $('button#btnaddnote').on('click',function(){

            var message=$(self.defaults.target).find('textarea#addnotemsg').val();
            var soid=$(self.defaults.target).find('input[type=hidden][id=inpnotesoid]').val();
            var note_date=$(self.defaults.target).find('input#addnotedate').val();
            var oprid=$(self.defaults.target).find('input[type=hidden][id=inpnoteoprid]').val();
            var type=$(self.defaults.target).find('input[type=hidden][id=inpnotetype]').val();


               if(message=="" || soid=="" || note_date=="")
                    {
                        alert("Fill all details");
                        return;
                    }

              var savenote=$.post(HOST+'notes/save',{message:message,soid:soid,note_date:note_date,type:type,operator_id:oprid});

                savenote.done(function(res){

                res=$.parseJSON(res);

                if(res.status && res.error){
                    alert(res.message);
                    return;
                }
                if(res.status && res.type)
                {
                  $('div#addnotemsg').showSuccess("Done").done(function(){self.getNotes();});
                  $('div#addnotesdiv').find('textarea#addnotemsg').val('');
                }
                else
                {
                $('div#addnotemsg').showFailure("Error");
                }
                });

        });


},
getNotes:function()
{
      $('button#btnrefreshcomments i').addClass('glyphicon-refresh-animate');

       var getnotes=$.getJSON(HOST,{soid:this.defaults.soid,type:this.defaults.type,note_date:this.defaults.date,operator_id:this.defaults.operator_id});

        getnotes.done(function(res){
          if(res.status && res.data.length)
          {
             --somecode---
          }
       });
},
activaterefresh:function(){

      var self=this;

     $(document).on('click','#btnrefreshcomments',function(){
               $('#notesthread').empty();
                self.getNotes();
            return false;
        });

        return false;
}

}

为了在我写的那个页面上激活这个功能

     Inventory.notes.init();

上面的代码在我打开一次模态时完美运行,但是当我关闭同一个模态并再次打开它但通过单击不同的链接时,所有事件都会被触发两次,三次等等。触发的事件数等于次数模态在该页面上打开。 代码中是否有任何问题或执行相同任务的任何其他方式。

我知道这不是一个插件,我想要的只是将所有与评论系统相关的功能作为库存储在一个屋檐下。

【问题讨论】:

  • 我在 html 中看不到数据目标。你如何打开模态?我想多重打开问题可能与打开模态的代码有关。不确定您在哪里或如何定义 #addnotesdiv,也许引导程序 modal.js 不喜欢您的设置方式 - 看看link,还有 Inventory.notes.init('a.addComment')参数似乎没有被使用。
  • @anthony data-target not required href 属性对我来说是这样做的。我正在使用 boostrap 属性而不是 jquery 代码打开模态。#addnotesdiv 是我的模态 html id。也删除了 a.addComment 。还是一样...

标签: javascript jquery html twitter-bootstrap-3 jquery-plugins


【解决方案1】:

每次打开模态框时,它都会触发 show.bs.modal 事件,然后所有方法都会再次执行,包括事件绑定。例如[addnote] 中的事件绑定

$('div#addnotesdiv').on('show.bs.modal',function(e){
    self.getandsetdefaults(e);
    self.setmodalelements(e);
    self.getNotes();
    self.addnote();
    self.activaterefresh();
});

【讨论】:

  • 再次执行所有方法是可以的,因为我希望它们在同一页面上再次打开模式但通过单击不同的链接时执行。但是当我插入任何评论或按下刷新按钮时,所有这些都会被触发两次,所以有多个插入和选择。我知道它与 show.bs.modal 事件有关的东西无法弄清楚如何修复它。
  • 每次打开模型框,都会调用addnote()方法并执行一次$('button#btnaddnote').on('click',function(){})。因此,当您第二次打开 modal 时,它会在 button#btnaddnote 上绑定两次单击事件回调。此时,评论创建将被复制。 @Vibhas
【解决方案2】:

问题是每当显示模态时调用 getNotes、addnote、activatereferesh 函数,但是当模态再次重新打开时,此函数会再次调用,所以两次等等。以更简单的方式说,有多个侦听器附加到单个元素没有破坏前一个,因为我的 init 函数被调用了很多次。

最后有两个解决方案我需要取消绑定事件或只附加一次。从here得到想法

1) 用下面的代码修改了初始化函数,增加了一个解绑监听函数

init:function(selector)
{
   var self=this;

   $(self.defaults.target).on('show.bs.modal',function(e){
            self.getandsetdefaults(e);
            self.setmodalelements(e);
            self.getNotes();
            self.addnote();
            self.activaterefresh();

   });

   $(self.defaults.target).on('hide.bs.modal',function(e){
           self.unbindlistners();
   });
}
   unbindlistners:function()
{
      var self=this;
     $('#btnrefreshcomments').unbind('click');
     $('button#btnaddnote').unbind('click');

      return false;
}

}

2) 将事件绑定函数放在 show.bs.modal 之外

 init:function(selector)
{
   var self=this;

   $(self.defaults.target).on('show.bs.modal',function(e){
            self.getandsetdefaults(e);
            self.setmodalelements(e);
   });
  self.getNotes();
  self.addnote();
  self.activaterefresh();
}

第二种解决方案有一个小问题,即第一次加载我的 DOM 函数时,getNotes 函数使用默认值调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 2016-03-14
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多