1

モーダルプラグインを作成しましたが、何らかの理由で、生成したdivの1つが、アタッチしているクリックイベントリスナーを取得していません。

<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

$.onメソッドのセレクターとして jQuery オブジェクトを渡しています。代わりに、セレクターのみを渡す必要があります。

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

で同じエラーを起こしました$caller.on()。クリックしている要素にバインド$.on()するのではなく、その要素の親の 1 つにバインドします。イベントを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

#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 に答える