1

我制作了一个模态插件,但由于某种原因,我生成的其中一个 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

4 回答 4

2

您正在传递一个 jQuery 对象作为$.on方法上的选择器。相反,您应该单独传入一个选择器

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

你在 上犯了同样的错误$caller.on()。您不会绑定$.on()到您单击的元素,而是将其绑定到该元素的父元素之一。我已将 even 绑定到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 );
于 2012-05-16T22:13:00.030 回答
1

您将 click 事件绑定到#js-close-modal它附加到 DOM 之前。也就是说,$("#js-close-modal")不是选择任何东西。您需要在添加它之后绑定它(即在之后close.insertBefore。您也可以在那个时候链接它,顺便说一下您也可以链接其他调用(元素创建attrinsertBefore...)

在不相关的建议中,您应该尝试将发布的代码数量限制在相关点。巨大的代码墙往往会吓跑人们。

于 2012-05-16T22:14:51.010 回答
1

绑定时$('#js-close-modal').size()返回0。这是因为元素还没有创建。重新安排您的代码,它应该可以工作。这是更新的小提琴

这是发生了什么变化:

(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
    });
});​
于 2012-05-16T22:15:28.520 回答
0

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

close.on('click', function(e) {
    $('.modal_outer').remove();
    $('#modal_page_cover').remove();
});
于 2012-05-16T22:15:34.520 回答