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

时间:2012-05-16 22:10:13

标签: javascript jquery

我制作了一个模态插件,但由于某种原因,我生成的一个div没有得到我附加到它的点击事件监听器。

<a class="close" id="js-close-modal"></a>就是我指的。我正在使用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);

});

演示:JSFiddle

知道为什么吗?

4 个答案:

答案 0 :(得分:2)

您在$.on方法中将jQuery对象作为选择器传递。您应该单独传入选择器

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

您在$caller.on()上犯了同样的错误。您没有将$.on()绑定到您单击的元素,而是将其绑定到该元素的父元素之一。我已将偶数绑定到body元素,但理想情况下应将其绑定到更接近的父级。

我在上面演示的更改会修复您的关闭按钮:http://jsfiddle.net/P5B4q/22/

当然,您正在使用相同的代码创建关闭按钮,因此事件委派不是必需的。您可以取消上面的代码,并在创建时修改关闭按钮:

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

将其替换为:

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

答案 1 :(得分:1)

将click事件绑定到#js-close-modal,然后将其附加到DOM。也就是说,$("#js-close-modal")没有选择任何东西。你需要在之后将它绑定在之后(即close.insertBefore之后)。你也可以在那个时候链接它,并且你也可以链接其他的调用(元素)创作,attrinsertBefore ...)

在一个不相关的建议中,您应该尝试限制发布到相关点的代码量。巨型密码墙往往会吓跑人们。

答案 2 :(得分:1)

在绑定时,$('#js-close-modal').size()返回0.这是因为尚未创建元素。重新安排你的代码,它应该工作。 Here is the updated fiddle

以下是改变的内容:

(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
    });
});​

答案 3 :(得分:0)

您可以将点击处理程序绑定到新创建的元素,而不是重新查询元素。 http://jsfiddle.net/P5B4q/20/

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