Javascript单击事件侦听器仅触发一次

Javascript单击事件侦听器仅触发一次,javascript,jquery,twitter,addeventlistener,Javascript,Jquery,Twitter,Addeventlistener,我有一个Chrome扩展,可以在推文发布之前拦截和检查推文。为此,我在Tweet按钮中添加了一个事件侦听器。由于内容是动态的,我使用: 如果tweet通过了检查,它将通过使用.trigger('click')以编程方式触发事件来提交 这很好,但只有一次。提交并发布推文后,tweet按钮上的事件侦听器将消失,我无法截获下一条推文进行检查。我尝试在再次提交后调用initialize()——可能按钮被删除并新添加到DOM中(在提交tweet时,它实际上会消失片刻)——但是querySelector会立

我有一个Chrome扩展,可以在推文发布之前拦截和检查推文。为此,我在
Tweet
按钮中添加了一个事件侦听器。由于内容是动态的,我使用:

如果tweet通过了检查,它将通过使用
.trigger('click')
以编程方式触发事件来提交

这很好,但只有一次。提交并发布推文后,
tweet
按钮上的事件侦听器将消失,我无法截获下一条推文进行检查。我尝试在再次提交后调用
initialize()
——可能按钮被删除并新添加到DOM中(在提交tweet时,它实际上会消失片刻)——但是
querySelector
会立即找到按钮。但是,即使再次调用
initialize()
,也不会触发对
Tweet
按钮的单击


这里可能有什么问题?我的问题是,我甚至不知道去哪里查找以及如何调试它。

再过几个小时,我终于找到了答案。问题本质上是新推特网站的高度动态内容。提交tweet后,
tweet
按钮确实会被删除并再次添加。我们需要做一系列的改变:

  • 使用
    MutationObserver
    跟踪任何更改。每次发生更改时,调用
    initialize()
    函数。为了避免太多的调用,我会在发生某些更改时执行此操作(此处不必要的详细信息)

  • 更改
    addSubmitNewTweetClickHandler()
    方法,以便首先删除事件侦听器,以避免重复侦听器(请注意,我使用对象,因此与我的原始问题相比,使用了

    创建引用函数时需要进行此更改
    handleSubmitNewWeetClick

总的来说,这仍然不是一个完美的解决方案,因为我调用了
initialize()
很多不必要的时间。但是,我无法可靠地确定
Tweet
按钮何时添加到文档中。当我使用
MutationObserver
时,添加的节点中没有一个具有属性
data testid
,我需要该属性来识别正确的按钮。我不知道为什么这个属性不存在。可能属性在添加到按钮后添加了几次,但即使使用额外的
MutationObserver
查找属性更改,我也可以检测到这一点


无论如何,它现在可以工作了,而且只适用于原型。

如果您的按钮是传入动态内容的一部分,或者如果您在某个地方重新创建它,则确实需要重新启动侦听器。请注意,尽管您应该在实际添加内容或从中调用适当方法的地方这样做。因为使用定时事件可能运行得太早,所以您也可以使用事件委派instead@PatrickEvans这不是我的钮扣。这是Twitter网站上提交新推文的默认按钮。但是,我假设按钮是在提交tweet后重新创建的。这就是我第二次尝试调用
initialize()
的方式,我再次得到日志消息
按钮find
。我想在我再次调用
initialize()
之后,该按钮可能会被删除并再次添加。但我不知道如何正确地观察这个。你有权使用那个按钮吗?尝试为该按钮添加新事件,但在文档包装器上,即使该按钮被删除,事件也将保留<代码>(文档).on('click','.btn class',function(){})
initialize : function() {
    let that = this;
    let jsInitChecktimer = setInterval(checkForJsFinished, 111);
    function checkForJsFinished () {
        if (document.querySelector("div[data-testid='tweetButtonInline']")) {          
            clearInterval (jsInitChecktimer);
            console.log("Button found");
            that.addSubmitNewTweetClickHandler();
        }
    }
},

addSubmitNewTweetClickHandler : function() {
    let that = this;
    let buttonSubmitTweet = document.querySelector("div[data-testid='tweetButtonInline']");
    buttonSubmitTweet.addEventListener('click', function(e) {
        console.log("CLICK");
        // Stop default event from happening
        e.preventDefault();
        e.stopImmediatePropagation();
        // Do stuff
    });
},
addSubmitNewTweetClickHandler : function() {
  let that = this;
  let buttonSubmitTweet = document.querySelector("div[data-testid='tweetButtonInline']");
  buttonSubmitTweet.removeEventListener('click', this.handleSubmitNewTweetClick ); 
  this.handleSubmitNewTweetClick = this.handleSubmitNewTweetClick.bind(this)
  buttonSubmitTweet.addEventListener('click', this.handleSubmitNewTweetClick );    
},