【问题标题】:Binding dynamically created elements in jQuery在 jQuery 中绑定动态创建的元素
【发布时间】:2011-01-15 08:49:09
【问题描述】:

下面的代码是相当不言自明的,但我遇到了一个将点击事件绑定到已创建元素的问题。

您可以在第 25 行看到我正在创建一个 id 为 'overlay' 的 div。然后我设置它的 css 属性。

然后在第 65 行我绑定单击以触发模式的隐藏。问题是,它不起作用。如果我将 div 放在 html 中,.click 会按预期工作。

感谢任何帮助。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Modal</title>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript">

$(document).ready(function() {  

    // Select the link(s) with name=modal
    $('a[name=modal]').click(function(e) {

        // Cancel the link behavior
        e.preventDefault();

        // Get the id of this link's associated content box.
        var id = $(this).attr('href');

        // Find the screen height and width
        var overlayHeight = $(document).height();
        var overlayWidth = $(window).width();

        // Create the overlay
        $('body').append('<div id="overlay"></div>');

        //Set css properties for newly created #overlay
        $('#overlay').css({
                'width' : overlayWidth,
                'height' : overlayHeight,
                'position':'absolute',
                'left' : '0',
                'top' : '0',
                'z-index' : '9000',
                'background-color' : '#000',
                'display' : 'none'          
            });

        // Get the viewpane height and width
        var winH = $(window).height();
        var winW = $(window).width();

        // Center the modal
        $(id).css('top',  winH/2-$(id).height()/2);
        $(id).css('left', winW/2-$(id).width()/2);

        // Transition effects for overlay
        $('#overlay').fadeIn(1000).fadeTo(1000,0.8);

        // Transition effect for modal
        $(id).fadeIn(1000); 

    });

    // Close link click = trigger out
    $('.modal .close').click(function (e) {
        //Cancel the link behavior
        e.preventDefault();

        $('#overlay').fadeOut(1000);
        $('.modal').fadeOut(200);
    });     

    // Overlay click = trigger out
    $('#overlay').click(function () {
        $('#overlay').fadeOut(1000);
        $('.modal').fadeOut(200);
    });

    // Load rules in to modal
    $('#rules .text').load('rules.html');

});

</script>
<style type="text/css">

.modal{
  position:absolute;
  display:none;
  z-index:9999;
}
#rules{
  width:600px; 
  height:400px;
}
#rules p{
    background: #fff;
    margin: 0;
    padding: 0;
}
#rules .head{
    background: #ddd;
    text-align: right;
    padding: 0 10px;
    height: 30px;
}
#rules .text{
    height: 370px;
    padding: 0 20px;
    overflow: auto;
}

</style>
</head>
<body>

<p><a href="#rules" name="modal">Open Modal</a></p>

<div id="rules" class="modal">
    <p class="head"><a href="#" class="close">close</a></p>
    <p class="text"></p>
</div>

</body>
</html>

【问题讨论】:

  • +1 欢迎来到 Stack Overflow,@Greg-J!

标签: javascript jquery


【解决方案1】:

请记住,每次单击 a[name=modal] 链接时,您的代码都会创建一个新的叠加层。

完成后从 DOM 中删除覆盖元素 .. 或在点击之外创建它,然后在点击事件中显示/隐藏它..

您的具体问题是您在创建覆盖之前将单击事件绑定到覆盖(因为您将在单击链接后创建......

【讨论】:

    【解决方案2】:

    使用 .live() 方法,它可以处理加载后添加到 DOM 的任何元素。

    // Overlay click = trigger out
    $('#overlay').live('click', function () {
        $('#overlay').fadeOut(1000);
        $('.modal').fadeOut(200);
    });
    

    另一种方法是在添加时将其绑定到单击(在 $('a[name=modal]') 的单击处理程序中。

    您可能还应该将 $('#overlay').fadeOut() 更改为 $(this).fadeOut()。

    【讨论】:

      【解决方案3】:

      如果您以编程方式创建#overlay,则需要将其与 $.live(); 绑定

      $('#overlay').live("click", function () {
        $('#overlay').fadeOut(1000);
        $('.modal').fadeOut(200);
      });
      

      这种绑定方法绑定到所有当前和未来与提供的选择器匹配的元素。

      【讨论】:

        【解决方案4】:

        叠加层的点击事件在元素存在之前被绑定。您需要使用live binding 来保留绑定——否则每次创建元素时都必须进行绑定。只需将您的函数更改为使用live(),如下所示:

        $('#overlay').live('click', function () {
            $('#overlay').fadeOut(1000);
            $('.modal').fadeOut(200);
        });
        

        .modal .close 的点击事件在绑定事件时已在 DOM 中定义。

        普通事件绑定仅考虑当前存在于 DOM 中的元素,而使用live() 绑定的事件也适用于所有未来匹配选择器的元素。

        【讨论】:

        • 这正是我认为的问题所在,但我不知道如何解决。谢谢!
        • 我相信 .delegate()(或 jquery 1.7+ 中的 .on())更快更高效
        【解决方案5】:
         // Overlay click = trigger out
            $('#overlay').click(function () {
                $('#overlay').fadeOut(1000);
                $('.modal').fadeOut(200);
            });
        

        在页面加载时触发,当#overlay 元素不存在时。如果您将这段代码移动到 $('a[name=modal]').click(function(e) { 部分内,但在 $('body').append('&lt;div id="overlay"&gt;&lt;/div&gt;'); 部分之后,它应该可以工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-09-29
          相关资源
          最近更新 更多