更改DOM后,jQuery点击不起作用

时间:2017-02-17 19:34:45

标签: javascript jquery html asp.net razor

我在razor中设置了我的HTML,如下所示:

  @if (ViewBag.Added != null)
                            {
                                if (ViewBag.Added == false)
                                {                        
                                    <div class="col-lg-2 col-md-3 col-sm-12 col-xs-12" id="wholeBtn">

                                     <a class="btn btn-app btnWatchList" style="min-width:100%;margin:0;height:67px">
                                    <i class="fa fa-save"></i> Add to Watchlist
                                  </a>
                                </div>
                                }
                                else if (ViewBag.Added)
                                {
                                    <div class="col-lg-2 col-md-3 col-sm-12 col-xs-12" id="addedToWatchList" style="padding:10px 0">
                                        <h4 style="text-align:center;margin-top:20px"><i class="fa fa-check" style="color:darkseagreen;font-size:25px"></i> Watching</h4>
                                    </div>
                                }
                            }
                            else
                            {
                                <div class="col-lg-2 col-md-3 col-sm-12 col-xs-12" id="wholeBtn">

                                    <a class="btn btn-app btnWatchList" style="min-width:175px;margin:0;height:67px">
                                        <i class="fa fa-save"></i> Add to Watchlist
                                    </a>
                                </div>
                            }

onclick按钮如下所示:

$(".btnSaveWatchlist").on("click", function (event) {
       $.post("/User/SaveWatchList", { comment: $('#TextArea1').val(), rating: $('input[name=rating]:checked').val(), competitor: $('.txtSearch').val() }, $(this).prop('disabled', true))
                             .done(function (data) {
                                 if (data == "AllFieldsRequired") {
                                     ShowErrorMessage("All fields are required!");
                                     return;
                                 }
                                 else {
                                     $('.hideit').hide();
                                     $('.canvas').show();
                                     AnimateGreenCheck();
                                     setTimeout(function () {
                                         var result = $('<div />').append(data).find('#addedToWatchList').html();
                                         $('#wholeBtn').html(result);
                                         var l = document.getElementById('cancelButton');
                                         l.click();
                                     },
                                   3000);

                                     setTimeout(function () {
                                         ResetWatchListField();
                                     },
                                  4500);
                                 }
                             });
});

所以最初这个按钮&#34;添加到关注列表&#34;没有出现在DOM中。在网站上执行搜索后将其加载到DOM中。

一旦完成,onclick事件就可以了。发布完成后,我隐藏按钮并更新DOM以向用户显示他已将此用户添加到关注列表。

现在再次对未添加到关注列表的其他用户执行搜索,并按下&#34;添加到关注列表&#34;与班级&#34; btnSaveWatchlist&#34;再次加载到DOM中。

但是这次它完全没有反应......我检查了控制器中的动作是否已启动,它没有...按钮看起来像是&#34;冻结&#34;。 ..

任何想法可能是什么人?

P.S。所有这些都是在没有刷新页面的情况下完成的。我不想为最终用户刷新页面......

这里编辑的是带有类的btnSaveWatchList按钮:

  <button data-remodal-action="cancel" class="remodal-cancel" id="cancelButton">Cancel</button>
    <button class="remodal-confirm btnSaveWatchlist">Save</button>

3 个答案:

答案 0 :(得分:1)

我建议您使用绑定操作来终止一项功能。

function bindButton() {
    $(".btnSaveWatchlist").click(function () {
        $.post("/User/SaveWatchList", { comment: $('#TextArea1').val(), rating: $('input[name=rating]:checked').val(), competitor: $('.txtSearch').val() }, $(this).prop('disabled', true))
            .done(function (data) {
                if (data == "AllFieldsRequired") {
                    ShowErrorMessage("All fields are required!");
                    return;
                }
                else {
                    $('.hideit').hide();
                    $('.canvas').show();
                    AnimateGreenCheck();
                    setTimeout(function () {
                        var result = $('<div />').append(data).find('#addedToWatchList').html();
                        $('#wholeBtn').html(result);
                        var l = document.getElementById('cancelButton');
                        l.click();
                        bindButton();
                    },
                        3000);
                    setTimeout(function () {
                        ResetWatchListField();
                        bindButton();
                    },
                        4500);
                }
            });
    });
}

在准备好的文档中,只需调用bindButton函数即可。然后,在每次通话之后,您将再次绑定按钮,因为您正在清理div的内容。

答案 1 :(得分:1)

我的代码目前还不清楚,所以我不是百分百肯定这会解决这个问题,但是这是我的理由:

您可能在以后使用jquery绑定要渲染的元素。

有两种方法可以解决这个问题。最简单的(对我来说)是使用父子样式绑定。 这意味着您将绑定放在父级上,jQuery检查子级是否在事后被单击。这实际上适用于动态内容(通过ajax或其他任何方式加载的html)

示例:

var $parent = $('#parent'); //the element you append your html to

$parent.on('click', '.btnSaveWatchlist', function(){
  //Do whatever you want here
  //The binding will hold as long as the parent doesn't get replaced.
});

或者,还有另一种方式;每次渲染html时,你的函数调用都会重新设置绑定(效率低一点)

示例:

请注意我的评论。我错过了很多信息,所以我在那里提出了一些“问题”。

function setBinding(){

  $(".btnSaveWatchlist").off('click');
  $(".btnSaveWatchlist").on("click", function (event) {
       $.post("/User/SaveWatchList", { comment: $('#TextArea1').val(), rating: $('input[name=rating]:checked').val(), competitor: $('.txtSearch').val() }, $(this).prop('disabled', true))
         .done(function (data) {
           if (data == "AllFieldsRequired") {
             ShowErrorMessage("All fields are required!");
             return; //this is not valid. make it true or false.
           }
           else {
             $('.hideit').hide();
             $('.canvas').show();
             AnimateGreenCheck();

             setTimeout(function () {
               var result = $('<div />').append(data).find('#addedToWatchList').html();
               $('#wholeBtn').html(result);
               var l = document.getElementById('cancelButton');

               //Why do you trigger the cancel button here? Doesn't this always cause it to cancel right away?
               l.click();
             },3000);

              setTimeout(function () {
                 ResetWatchListField();
                 //is this where you reset the html?
                 //in that case:
                 setBinding();
              }, 4500);
            }
        });
  });
}

你必须在某个地方第一次打电话给setBinding()(比如在document.ready?上),否则它将无效。

请注意,在渲染所需的按钮后,应调用setBinding()函数。

在某个地方,您在问题中显示的代码之外,您将呈现此按钮。无论是真append()还是html(),我都不知道,但无论您何时呈现此按钮,请在html()之后添加element.html(myhtml).promise().done(setBinding);

答案 2 :(得分:1)

  

任何想法可能是什么人?

是的,标记(基本上是普通字符串)和文档对象模型之间的区别。您将事件侦听器附加到特定DOM节点,但在加载新标记时,将释放此节点,并从您提供的标记创建一个新节点。

事件监听器也随旧节点消失了。

//listen for every 'click' event on an '.btnSaveWatchlist' that bubbles up to the `document.body`
$(document.body).on("click", ".btnSaveWatchlist", function (event) {
    //don't inline such stuff, it's completely unreadable
    var postData = { 
        comment: $('#TextArea1').val(), 
        rating: $('input[name=rating]:checked').val(), 
        competitor: $('.txtSearch').val() 
    };

    //don't know why you put this into the $.post() call.
    //this line returns $(this), but the arguments for $.post() 
    //are url, data, successHandler and dataType.
    //and $(this) is neither a successHandler, nor a dataType
    $(this).prop('disabled', true);

    $.post("/User/SaveWatchList", postData)
        .done(function (response) {
            if (response == "AllFieldsRequired") {
                ShowErrorMessage("All fields are required!");
                return;
            } else {
                $('.hideit').hide();
                $('.canvas').show();

                AnimateGreenCheck();

                setTimeout(function() {
                    //you don't need to manually parse the response
                    var result = $('#addedToWatchList', response)
                        .html();

                    $('#wholeBtn').html( result );

                    //don't try to fire a click-event by code. 
                    //Better call the function that gets executed if this event happened

                    //since chances are good, that you used jQuery to register this click-listener
                    //triggering the click-event will probably call it.
                    //this is more reliable than relying on the click-function of a dom-node.
                    $('#cancelButton').click();
                }, 3000);

                //a function that just forwards the call to another function is useless
                //just pass the function you want to call.
                setTimeout(ResetWatchListField, 4500);
             }
        });
});