2012-05-16 27 views
1

我做了一个模态插件,但由于某种原因,我生成的一个div没有获得我附加到它的单击事件侦听器。动态生成的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

任何想法,为什么?

+2

如果在''live''方法中使用'on'方法,则应该将事件添加到元素的父元素之一。 – VisioN

回答

2

你正在传递一个jQuery对象作为$.on方法的选择器。你应该改为传递一个选择独自:

$("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); 
+0

这是迄今为止最好的方法。使用事件冒泡始终是一种有效的,可靠的方式来处理动态内容和侦听器。 – bmarti44

+0

@ bmarti44我认为这不一定是最好的办法*远远*。它对于某些动态内容当然有其优势,但是在一个包中创建和销毁的自包含元素集中,您可以通过绑定到动态创建的元素本身来获得轻微的性能提升。这也使得更容易从这些元素中解除绑定,并为您提供更多控制。不过,我不会敲''.on'的委托方法。 –

+1

不知道你可以在创建时链接事件。这是拉德。谢谢。 –

1

你之前它添加到DOM click事件绑定到#js-close-modal。也就是说,$("#js-close-modal")没有选择任何东西。您需要在之后绑定(即在close.insertBefore之后)。您也可以在当时链接它,并且您还可以链接其他呼叫(创建元素,attr,insertBefore ...)

在一个不相关的建议,你应该尽量限制的代码你邮寄到相关点的数量。巨人代码墙壁往往把人吓跑。

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

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

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