2010-02-10 2 views
3

Следующий код достаточно понятен, но я столкнулся с проблемой, связывающей событие click с элементом, который был создан.Связывание динамически созданных элементов в jQuery

Вы можете видеть по строке 25 Я создаю div с идентификатором «overlay». Затем я устанавливаю его свойства 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> 
+0

+1 Добро пожаловать в Stack Overflow, @ Greg-J! – Sampson

ответ

5

Событие click для наложения привязывается до того, как элемент существует. Вам нужно использовать live binding, чтобы сохранить привязку –, иначе вам придется выполнять привязку каждый раз, когда вы создаете элемент. Просто измените функцию, чтобы использовать live() так:

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

Клик событие для .modal .close работ, как уже определенных в DOM, когда событие связано.

Нормальное связывание событий учитывает только те элементы, которые существуют в DOM, в то время как события, связанные с live(), работают также со всеми будущими элементами, которые соответствуют селектору.

+0

Это именно то, что я думал о проблеме, но я не знал, как ее решить. Спасибо! – S16

+2

Я верю .delegate() (или .on() в jquery 1.7+) быстрее и эффективнее – Khodor

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

запускается при загрузке страницы, когда элемент #overlay не существует. Если вы переместите этот фрагмент кода внутри части $('a[name=modal]').click(function(e) {, но после части $ ('body').append('<div id="overlay"></div>'); она должна работать.

0

Если вы программно создаете #overlay, вам необходимо связать его с $ .live();

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

Этот метод привязки связывается со всеми существующими и будущими элементами, которые соответствуют предоставленному селектору.

0

Используя метод .live(), он будет работать с любыми элементами, которые вы добавляете в DOM после его загрузки.

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

Другой способ сделать это было бы привязать его щелкнуть, когда он будет добавлен (внутри обработчика щелчка для $ («[название = модальный]»).

Вы должны, вероятно, также изменить $ ('# перекрытие). Затухание() до $ (это) .fadeOut().

0

Имейте в виду, что ваш код будет создавать новый Overlay каждый раз, когда ссылка a[name=modal] щелчке ..

Либо удалите элемент наложения из DOM, когда вы закончите с ним .. или создайте его вне клика, d просто показать/скрыть это на событии щелчка ..

Вы Специфическая проблема является то, что вы свяжете событие щелчка к накладке, прежде чем он когда-либо созданное (, так как вы создали после того, как вы нажмете на ссылку ..)

Смежные вопросы