简体   繁体   English

jQuery .change()事件仅触发一次

[英]Jquery .change() event fires only once

So I'm fairly novice with jquery and js, so I apologise if this is a stupid error but after researching I can't figure it out. 因此,我对jquery和js还是一个新手,因此,如果这是一个愚蠢的错误,我深表歉意,但经过研究,我无法弄清楚。

So I have a list of data loaded initially in a template, one part of which is a dropdown box that lets you filter the data. 因此,我在模板中最初加载了一个数据列表,其中一部分是一个下拉框,可让您过滤数据。 My issue is that the filtering only works once? 我的问题是过滤仅能运行一次? As in, the .change function inside $(document).ready() only fires the once. 与之类似,$(document).ready()内部的.change函数仅触发一次。

There are two ways to reload the data, either click the logo and reload it all, or use the search bar. 有两种方法可以重新加载数据,或者单击徽标并全部重新加载,或者使用搜索栏。 Doing either of these at any time also means the .change function never fires again. 随时执行其中任一操作也意味着.change函数不再触发。 Not until you refresh the page. 直到刷新页面。

    var list_template, article_template, modal_template;
var current_article = list.heroes[0];


function showTemplate(template, data)
{
    var html = template(data);
    $("#content").html(html);
}

$(document).ready(function()
{
  var source = $("#list-template").html();
  list_template = Handlebars.compile(source);

  source = $("#article-template").html();
  article_template = Handlebars.compile(source);

    source = $("#modal-template").html();
    modal_template = Handlebars.compile(source);

  showTemplate(list_template,list);
    $(".articleButton").click(function()
    {
        var index = $(this).data("id");
        current_article = list.heroes[index];
        showTemplate(article_template,current_article);
        $('.poseThumb').click(displayModal);
    });

    $("#classFilter").change(function()
    {
        console.log("WOW!");
        var classToFilter = this.value;
        var filteredData =
        {
            heroes: list.heroes.filter(function(d)
            {
                if (d.heroClass.search(classToFilter) > -1)
                {
                    return true;
                }
                return false;
            })
        };
        console.log(filteredData);
        showTemplate(list_template,filteredData);
        $(".articleButton").click(function()
        {
            var index = $(this).data("id");
            current_article = filteredData.heroes[index];
            showTemplate(article_template,current_article);
            $('.poseThumb').click(displayModal);
        });
    });

    $("#searchbox").keypress(function (e)
    {
        if(e.which == 13)
            {
                var rawSearchText = $('#searchbox').val();
                var search_text = rawSearchText.toLowerCase();
                var filteredData =
                {
                    heroes: list.heroes.filter(function(d)
                    {
                        if (d.name.search(search_text) > -1)
                        {
                            return true;
                        }
                        return false;
                    })
                };
                console.log(filteredData);
                showTemplate(list_template,filteredData);
                $(".articleButton").click(function()
                {
                    var index = $(this).data("id");
                    current_article = filteredData.heroes[index];
                    showTemplate(article_template,current_article);
                    $('.poseThumb').click(displayModal);
                });
            }
    });

    $("#logo").click(function()
    {
            showTemplate(list_template,list);

            $(".articleButton").click(function()
            {
        var index = $(this).data("id");
                current_article = list.heroes[index];
                showTemplate(article_template,current_article);
                $('.poseThumb').click(displayModal);
            });
    });
    //$("#logo").click();
});

function displayModal(event)
{
        var imageNumber = $(this).data("id");
        console.log(imageNumber);
        var html    = modal_template(current_article.article[0].vicPose[imageNumber]);
        $('#modal-container').html(html);
        $("#imageModal").modal('show');
}

I should note two things: first, that the search bar works perfectly, and the anonymous function inside both of them is nearly identical, and like I said, the filtering works perfectly if you try it after the initial load. 我应该注意两件事:首先,搜索栏可以正常工作,并且它们内部的匿名函数几乎相同,并且就像我说的那样,如果在初始加载后尝试过滤,则筛选可以完美地工作。 The second is that the same problem occurs replacing .change(anonymous function) with .on("change",anonymous function) 第二个问题是,使用.on(“ change”,anonymous function)替换.change(anonymous function)时,会出现相同的问题

Any help or advice would be greatly appreciated. 任何帮助或建议,将不胜感激。 Thanks. 谢谢。

Try to use some reference like 'body' in the event listeners inside your DOM like: 尝试在DOM内部的事件侦听器中使用一些引用,例如“ body”:

  $('body').on('click','.articleButton', function() {
        //Do your stuff...
    })


    $('body').on('click','#classFilter', function() {
        //Do your stuff...  
    })


    $('body').on('keypress','#searchbox', function() {
       //Do your stuff...   
    })

    $('body').on('click','#logo', function() {
        //Do your stuff...  
    })

This will work that you can fire it more than once. 这样可以使您多次触发它。

I agree with Fernando Urban's answer, but it doesn't actually explain what's going on. 我同意费尔南多·厄本(Fernando Urban)的回答,但实际上并没有解释发生了什么。

You've created a handler attached to an HTML element ( id="classFilter" ) which causes part of the HTML to be rewritten. 您已经创建了一个附加到HTML元素( id="classFilter" )的处理程序,该处理程序导致部分HTML被重写。 I suspect that the handler overwrites the HTML which contains the element with the handler on it. 我怀疑处理程序会覆盖其中包含带有处理程序的元素的HTML。 So after this the user is clicking on a new HTML element, which looks like the old one but doesn't have a handler. 因此,此后,用户单击了一个新的HTML元素,该元素看起来像旧的HTML元素,但是没有处理程序。

There are two ways round this. 有两种解决方法。 You could add code inside the handler which adds the handler to the new element which has just been created. 您可以在处理程序中添加代码,从而将处理程序添加到刚刚创建的新元素中。 In this case, that would mean making the handler a named function which refers to itself. 在这种情况下,这意味着使处理程序成为引用自身的命名函数。 Or (the easier way) you could do what Fernando did. 或者(更简单的方法)您可以做费尔南多所做的事情。 If you do this, the event handler is attached to the body , but it only responds to clicks on the #classFilter element inside the body . 如果执行此操作,则事件处理程序将附加到body ,但是它仅对body内部#classFilter元素上的单击做出响应。 In other words, when the user clicks anywhere on the body, jQuery checks whether the click happened on a body #classFilter element. 换句话说,当用户单击主体上的任何位置时,jQuery会检查单击是否发生在body #classFilter元素上。 This way, it doesn't matter whether the #classFilter existed when the handler was set. 这样,设置处理程序时#classFilter是否存在并不重要。 See "Direct and delegated events" in jQuery docs for .on method . 有关.on方法,请参见jQuery文档中的 “直接和委托事件”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM