【问题标题】:JQuery .on("click"... works intermitentlyJQuery .on("click"... 间歇性工作
【发布时间】:2015-02-26 18:34:40
【问题描述】:

我有一段代码:

$("body").on("click", ".reply-button", function(){
    alert("test");
});

假设当我单击动态生成的元素时会提醒我(执行此代码时它不是 DOM 的一部分)。

有时它会按预期工作。我单击按钮并弹出一个小警报。但是,其他时候它会停止工作。我绑定到它的任何东西都不起作用。如果我绑定到容器 div(也是动态生成的),它确实可以工作,但如果我将处理程序更改为合并按钮,则不会。

我想知道这个错误的可能原因是什么?我不知道如何进行调试。我的第一个猜测是,这是由于 stopImmediatePropagationstopPropagation 而导致的,但我找不到在同一区域使用。

有人知道我应该如何进行调试吗?

编辑: DOM 是如何生成的?

我从一个隐藏的模板中获取 HTML。

var html = $("#template").html();

然后我将模板附加到一个 div 容器中

$("#container").append(html);

编辑2: 这是被拉取的模板:

<div id="tweets-container" class="feed-wrapper">
</div>

<div id="tweet-template" style="display:none;">
    <!-- Tweet 1 -->
    <div class="tweet animated" data-scannedTweetId="s_id">
        <!-- User -->
        <div class="tweet-user">
            <!-- User picture -->
            <img class="tweet-user-picture" src="s_twt_owner_profile_img_url" />

            <!-- User info -->
            <div class="tweet-user-info">
                <!-- User name -->
                <div class="tweet-user-info-name">
                    <a href="//twitter.com/s_twt_owner_sn" target="_blank">s_twt_owner_name (@s_twt_owner_sn)</a>
                </div>

                <!-- User biography -->
                <div class="tweet-user-info-biography">
                    s_twt_owner_desc
                </div>
            </div>
        </div>

        <!-- User statistics (following, followers, and tweets) -->
        <span class="tweet-statistics animated">
            <div class="following">
                <div class="statistic-count"><a href="http://twitter.com/s_twt_owner_sn/following">s_twt_owner_num_following</a></div>
                <div class="statistic-label">following</div>
            </div>

            <div class="followers">
                <div class="statistic-count"><a href="http://twitter.com/s_twt_owner_sn/followers">s_twt_owner_num_follower</a></div>
                <div class="statistic-label">followers</div>
            </div>

            <div class="tweets">
                <div class="statistic-count"><a href="http://twitter.com/s_twt_owner_sn">s_twt_owner_num_twt</a></div>
                <div class="statistic-label">tweets</div>
            </div>
        </span>

        <!-- Tweet bars/graph -->
        <div class="side-information animated">
            <div class="bar-wrapper">
                <!-- Actual bars -->
                <div class="bars">
                    <div class="bar big-bar bar-green" style="height: tqes_heightpx; background: tqes_color;" data-toggle="tooltip" data-placement="top" title="tq_engage_score"></div>
                    <div class="bar bar-yellow" style="height: tqrs_heightpx; background: tqrs_color;" data-toggle="tooltip" data-placement="top" title="tq_relevancy_score"></div>
                    <div class="bar bar-light-green" style="height: sks_heightpx; background: sks_color;" data-toggle="tooltip" data-placement="top" title="s_klout_score"></div>
                    <div class="bar bar-green" style="height: sls_heightpx; background: sls_color;" data-toggle="tooltip" data-placement="top" title="s_legitimacy_score"></div>
                    <div class="bar bar-gray" style="height: tqgs_heightpx; background: tqgs_color;" data-toggle="tooltip" data-placement="top" title="tq_geography_score"></div>
                </div>

                <!-- Labels that correspond with each bar -->
                <div class="bar-labels">
                    <div class="bar-label big-bar-label" data-toggle="tooltip" data-placement="bottom" title="Score">tq_engage_score</div>
                    <div class="bar-label-icon" style="font-size: 12px; color: #000;" data-toggle="tooltip" data-placement="bottom" title="Relevancy">
                        <i class="fa fa-bullseye"></i>
                    </div>
                    <div class="bar-label-icon" data-toggle="tooltip" data-placement="bottom" title="Influence">
                        <i class="fa fa-users"></i>
                    </div>
                    <div class="bar-label-icon" data-toggle="tooltip" data-placement="bottom" title="Legitimacy">
                        <i class="fa fa-check-circle"></i>
                    </div>
                    <div class="bar-label-icon" data-toggle="tooltip" data-placement="bottom" title="Geography">
                        <i class="fa fa-map-marker"></i>
                    </div>
                </div>
            </div>

            <!-- Notes below the bars/graph -->
            <div class="explanations">
                <!-- Note below the bars/graph -->
                <div class="explanation">
                    <div class="explanation-check"><i class="fa fa-first-comment">&nbsp;&nbsp;&nbsp;&nbsp;</i>
                        <div class="explanation-text">
                            comment_one
                        </div>
                    </div>
                </div>

                <!-- Note below the bars/graph -->
                <div class="explanation">
                    <div class="explanation-check"><i class="fa fa-second-comment">&nbsp;&nbsp;&nbsp;&nbsp;</i>
                        <div class="explanation-text">
                            comment_two
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Tweet score -->
        <div class="score-wrapper">
            <div class="score animated">tq_engage_score</div>
        </div>

        <!-- Tweet content -->
        <div class="tweet-content">
            s_twt_text
        </div>

        <!-- Time since tweet was posted -->
        <div class="tweet-time-elapsed">
            s_twt_time
        </div>

        <!-- Area below tweet with reply textarea and buttons -->
        <div class="tweet-reply-section animated">
            <!-- Reply textarea -->
            <textarea class="tweet-reply animated">@s_twt_owner_sn </textarea>

            <!-- Buttons -->
            <div class="buttons animated">
                <!-- Small buttons on top of reply button -->
                <div class="top-buttons">
                    <span class="character-count">
                    </span>
                </div>

                <!-- Reply button -->
                <div class="reply-button">
                    Reply <i class="fa fa-reply"></i>
                </div>
            </div>
        </div>
    </div>
</div>

JavaScript:

   /**
     * Add a tweet to the feed.
     */
    function _addTweetToFeed(tweet, keywords) {
        /** Get the tweet template */
        var tweetHtml = $('#tweet-template').html();

        // add score heights and colors properties to the tweet
        tweet = _setScoreBars(tweet);

        /** Linkify elements of the tweet */
        tweet.s_twt_text = twitterify(tweet.s_twt_text); // the tweet
        tweet.s_twt_owner_desc = twitterify(tweet.s_twt_owner_desc);

       // fix search terms to be highlighted
        tweet.s_twt_text = _highlightSearchTerms(tweet.s_twt_text, keywords); // the tweet
        tweet.s_twt_owner_desc = _highlightSearchTerms(tweet.s_twt_owner_desc, keywords);

       // change from twitter links to readable links
       tweet = _fixTweetLinks(tweet);

        /** Make numbers readable */
        tweet.s_twt_owner_num_following = abbrNum(tweet.s_twt_owner_num_following, 1);
        tweet.s_twt_owner_num_follower = abbrNum(tweet.s_twt_owner_num_follower, 1);
        tweet.s_twt_owner_num_twt = abbrNum(tweet.s_twt_owner_num_twt, 1);

        /** Loop through the properties of tweet object and populate tweetHtml with them */
        for (var prop in tweet) {
            if (tweet.hasOwnProperty(prop)) {
                tweetHtml = _replaceAll(tweetHtml, prop, tweet[prop]);
            }

            // add comments
            tweetHtml = _addComments(tweet, tweetHtml);

            /** If both location and url are not present, remove the comma */
            if (!(tweet.s_twt_owner_loc && tweet.s_twt_owner_url)) {
                $('#url_comma').html('');
            }
        }
        $('#tweets-container').append(tweetHtml);
    }

【问题讨论】:

  • 是否有任何控制台错误? DOM 元素是如何生成的?
  • 使用正确的术语很重要。您没有将任何内容绑定到按钮,而是将处理程序绑定到 body
  • @aldux:使用事件委托的原因是:“动态生成的元素”
  • 我是说,你能把你的 HTML 和 JS 贴在这里吗:jsfiddle.net 这样我们就可以看到它是如何工作的 :)。就目前而言,信息太少了。
  • 绝对同意@acquinas,并建议就 SO 提出问题之前在 jsfiddle 中重新创建您的问题。这有一半的时间会让你意识到问题所在。

标签: javascript jquery


【解决方案1】:

“有时它会按预期工作” 仅此行就建议您在创建 DOM 之前运行代码。有时您的浏览器足够快地创建 dom 并且处理程序被附加到主体,有时您的 javascript 会首先运行并且它没有被附加。将您的代码包装在此:

$(function(){
    $("body").on("click", ".reply-button", function(){
        alert("test");
    });
});

【讨论】:

  • “有时您的浏览器创建 dom 的速度足够快,并且处理程序被附加到主体,有时您的 javascript 会先运行而没有附加。” 我非常怀疑那。该页面是按顺序解析的。 body 在调用代码时存在或不存在。这里没有竞争条件。
  • 我只是尝试包装函数,但它似乎不起作用。我认为使用 .on() 而不是 .click() 的目的是为了处理 JavaScript 运行时 DOM 不存在的事实?
  • body 也是 dom 的一部分。如果您想在 dom 准备好之前附加它,请将其委托给 document
  • 这可能有助于理清事情的顺序? stackoverflow.com/questions/22083248/…
  • Banana,我的评论是针对我上面的评论...不过,我也必须同意@FelixKling 的评论。
【解决方案2】:

有人知道我应该如何进行调试吗?

有时最好抽出一小部分代码,看看它是否单独工作。例如:http://jsfiddle.net/6v7z9fak/

js:

$("body").on("click", ".reply-button", function(){
    alert("test");
});

html:

<button type="button" class="reply-button">Reply</button>

如您所见,它运行良好。因此,您可以确信错误不仅仅存在于那段代码中。它要么是代码的另一部分,要么是这些部分如何相互作用,或者是其他东西。现在慢慢添加更多代码,测试一下,看看哪里出错了。

【讨论】:

  • 请记住,jsFiddle 会自动使用内部 DOM 就绪事件处理程序。
  • ^没错,说得好。您还应该获取正在测试的代码,并将其放在与给您问题的页面相同的环境中的单独的空白页面中。调试就是保持一件事不变并改变其他变量。
  • 如果它高度依赖于代码的其他部分,你会如何建议隔离它?你会复制粘贴所有内容吗?
  • 如果回复按钮失败,则从空白页开始,并仅添加按钮 - 就像我链接到的 jsfiddle 一样。然后开始重建页面,逐段添加现有代码。有很多调试方法,这是一种方法。您需要做更多的工作来缩小您的问题范围,因为您可以提出一个可以回答的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 2014-06-03
  • 2011-07-09
相关资源
最近更新 更多