Event doesn't get added in a for-loop

前端 未结 3 400
清酒与你
清酒与你 2020-12-22 10:38

This is the html. If a link is clicked I want to replace the span-element in front of it with some text.

that1

相关标签:
3条回答
  • 2020-12-22 11:13

    The problem with your original code is that you're creating a closure on the variable n. When the event handler is called, it is called with the value of n at the point of invocation, not the point of declaration. You can see this by adding an alert call:

    $(document).ready(function() {
        var numSpans = $("span").length;
        for (n = 1; n <= numSpans; n++) {
            $("a#update" + n).click(function(e) {
                alert(n); //Alerts '6'
                $('span#sp' + n).replaceWith('this');
                e.preventDefault();
            });
        }
    })
    

    One way to fix this is to create a closure on the value of n in each iteration, like so:

    $(document).ready(function() {
        var numSpans = $("span").length;
        for (n = 1; n <= numSpans; n++) {
            $("a#update" + n).click(
                (function(k) {
                    return function(e) {
                        alert(k);
                        $('span#sp' + k).replaceWith('this');
                        e.preventDefault();
                    }
                })(n)
            );
        }
    })
    

    However, this is messy, and you'd do better to use a more jQuery-y method.


    One way to do this would be to remove the ids from your code. Unless you need them for something else, they're not required:

    <p><span>that1</span> <a href="#" class="update">Update1</a></p>
    <p><span>that2</span> <a href="#" class="update">Update2</a></p>
    <p><span>that3</span> <a href="#" class="update">Update3</a></p>
    <p><span>that4</span> <a href="#" class="update">Update4</a></p>
    <p><span>that5</span> <a href="#" class="update">Update5</a></p>
    

    jQuery:

    $(function() {
        $('a.update').live('click', function() {
            $(this).siblings('span').replaceWith("Updated that!");
        });
    });
    

    jsFiddle

    0 讨论(0)
  • 2020-12-22 11:15

    Don't create functions in a loop. With jQuery, there's no need for an explicit loop at all.

    $(function()
    {
        $('span[id^=sp]').each(function(n)
        {
            $('#update' + n).click(function(e)
            {
                $('#sp' + n).replaceWith(this);
                return false;
            });
        });
    });
    

    Demo: http://jsfiddle.net/mattball/4TVMa/


    You can do way better than that, though:

    $(function()
    {
        $('p > a[id^=update]').live('click', function(e)
        {
            $(this).prev().replaceWith(this);
            return false;
        });
    });
    

    Demo: http://jsfiddle.net/mattball/xySGW/

    0 讨论(0)
  • 2020-12-22 11:36

    Try this:

    $(function(){
        $("a[id^='update']").click(function(){
            var index = this.id.replace(/[^0-9]/g, "");
            $("span#sp" + index).replaceWith(this);
            e.preventDefault();
        });
    });
    
    0 讨论(0)
提交回复
热议问题