简体   繁体   English

动态生成的div不会附加我的事件侦听器

[英]Dynamically generated div isn't attaching my event listener

I made a modal plugin but for some reason one of the divs that I generate isn't getting a click event listener that I am attaching to it. 我做了一个模态插件,但由于某种原因,我生成的一个div没有得到我附加到它的点击事件监听器。

<a class="close" id="js-close-modal"></a> is what I'm referring to. 我指的是<a class="close" id="js-close-modal"></a> I'm using jQuery's on, but that doesn't seem to help. 我正在使用jQuery,但这似乎没有帮助。

        var $caller = $(this);
        var $modal = $('.modal');

        $caller.on('click', $caller, function(e) {
            e.stopPropagation();

            $('#js-close-modal').on('click', $('#js-close-modal'), function(e) {
                $('.modal_outer').remove();
                $('#modal_page_cover').remove();
            });


            var modal_outer = $('<div />');
            modal_outer.addClass('modal_outer');
            modal_outer.css({
                top: ($(window).scrollTop()) + 'px'
            });

            var $div = $('<div />');

            var modal = $('<div />');
            modal.addClass('modal');

            var modal_inner = $('<div />');
            modal_inner.addClass('modal_inner');

            modal.append(modal_inner);
            modal_outer.append(modal);

            var body = $('body');
            body.append(modal_outer).hide().fadeIn(100);
            modal_inner.text('yo');

            var close = $('<a />');
            close.addClass('close').attr('id', 'js-close-modal');
            close.insertBefore(modal_inner);


            var page_cover = $('<div />');
            page_cover.attr('id', 'modal_page_cover');
            body.prepend(page_cover);

});

Demo: JSFiddle 演示: JSFiddle

Any idea why? 知道为什么吗?

You're passing a jQuery object in as your selector on the $.on method. 您在$.on方法$.on jQuery对象作为选择器$.on You should instead be passing in a selector alone: 你应该单独传递一个选择器

$("body").on("click", "#js-close-modal", function(){
  /* Do stuff */
});

You made the same error on $caller.on() . 你在$caller.on()上犯了同样的错误。 You don't bind $.on() to the element you're clicking, you bind it to one of the parents of that element. 您没有将$.on()绑定到您单击的元素,而是将其绑定到该元素的父元素之一。 I've bound the even to the body element, but you should ideally bind it to a much closer parent. 我已将偶数绑定到body元素,但您应该理想地将它绑定到更接近的父级。

Making the change I demonstrated above fixes your close button: http://jsfiddle.net/P5B4q/22/ 我在上面演示的更改修复了您的关闭按钮: http//jsfiddle.net/P5B4q/22/

Of course you're creating the close button in the same code, so event delegation isn't really necessary. 当然,您在相同的代码中创建了关闭按钮,因此事件委派不是必需的。 You could do away with the code above, and modify your close button upon creation: 您可以取消上面的代码,并在创建时修改关闭按钮:

var close = $('<a />');
close.addClass('close').attr('id', 'js-close-modal');
close.insertBefore(modal_inner);

Replace that with: 替换为:

$("<a>", { class: "close", id: "js-close-modal" })
  .on("click", function(){ $('#modal_page_cover, #modal_outer').remove() })
  .insertBefore( modal_inner );

You bind the click event to #js-close-modal before it's appended to the DOM. 在将click事件附加到DOM之前,将click事件绑定到#js-close-modal That is to say, $("#js-close-modal") is not selecting anything. 也就是说, $("#js-close-modal")没有选择任何东西。 You need to bind it after you've appended it (ie after close.insertBefore . You can also chain it at that time, and by the way you can chain the other calls too (the element creation, attr , insertBefore ...) 你需要在附加它之后绑定它(即在close.insertBefore之后。你也可以在那个时候链接它,并且你可以链接其他调用的方式(元素创建, attrinsertBefore ......)

In an unrelated suggestion, you should try to limit the amount of code you post to the relevant points. 在一个不相关的建议中,您应该尝试限制发布到相关点的代码量。 Giant code walls tend to scare people away. 巨型密码墙往往会吓跑人们。

At the time of binding, the $('#js-close-modal').size() returns 0. This is because the element is not created yet. 在绑定时, $('#js-close-modal').size()返回0.这是因为该元素尚未创建。 Re-arrange your code and it should work. 重新安排你的代码,它应该工作。 Here is the updated fiddle 这是更新的小提琴

And here is the what have changed: 以下是变化的内容:

(function($) {
    var methods = {
        init: function(options) {
            var settings = $.extend({
                'fade': false
            }, options);

            return this.each(function() {
                var $caller = $(this);
                var $modal = $('.modal');

                $caller.on('click', $caller, function(e) {
                    e.stopPropagation();
                    $('body').on('click', function(e) {
                        e.stopPropagation();
                        var modalCover = $('.modal_outer');
                        if (modalCover.has(e.target).length === 0) {
                            $('.modal_outer').remove();
                            $('#modal_page_cover').remove();

                        }
                    });

                    /*$('#js-close-modal').on('click', $('#js-close-modal'), function(e) {
                            $('.modal_outer').remove();
                            $('#modal_page_cover').remove();
                    });*/ //moved down

                    $('body').keyup(function(e) {
                        e.stopPropagation();
                        if (e.keyCode === 27) {
                            $('.modal_outer').remove();
                            $('#modal_page_cover').remove();
                        }
                    });




                    var modal_outer = $('<div />');
                    modal_outer.addClass('modal_outer');
                    modal_outer.css({
                        top: ($(window).scrollTop()) + 'px'
                    });

                    var $div = $('<div />');

                    var modal = $('<div />');
                    modal.addClass('modal');

                    var modal_inner = $('<div />');
                    modal_inner.addClass('modal_inner');

                    modal.append(modal_inner);
                    modal_outer.append(modal);

                    var body = $('body');
                    body.append(modal_outer).hide().fadeIn(100);
                    modal_inner.text('yo');

                    var close = $('<a />');
                    close.addClass('close').attr('id', 'js-close-modal');
                    close.insertBefore(modal_inner);
                    //moved from above.
                    $('#js-close-modal').on('click', $('#js-close-modal'), function(e) {
                            $('.modal_outer').remove();
                            $('#modal_page_cover').remove();
                    });



                    var page_cover = $('<div />');
                    page_cover.attr('id', 'modal_page_cover');
                    body.prepend(page_cover);
                });


            });

        }
    };

    $.fn.modal = function(method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            return false;
        }
    };
})(jQuery);

$(window).ready(function() {
    $('.js-modal').modal({
        'fade': false
    });
});​

Rather than re-querying for the element, you can just bind the click handler to the newly created element. 您可以将单击处理程序绑定到新创建的元素,而不是重新查询元素。 http://jsfiddle.net/P5B4q/20/ http://jsfiddle.net/P5B4q/20/

close.on('click', function(e) {
    $('.modal_outer').remove();
    $('#modal_page_cover').remove();
});

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

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