Jquery - одна из тех js - библиотек, которые позволяют увеличить скорость разработки веб-приложений, в частности - на клиентской стороне. Особенно удобно использовать ее вместе с PHP - мне этот коктейль показался мощной штукой.
Думаю, многие при использовании jquery сталкивались с такой проблемкой: предположим, что есть некое событие, например - клик по кнопочке, вызов которого добавляет на страничку некий элемент, например - некую ссылку, и пусть при клике на этой ссылке должен сработать написанный вами обработчик. И если вы попытаетесь кликнуть по этой ссылке, то есть вызвать ваш обработчик, то ничего не произойдет. Например, вот так:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
<script src="jquery-1.9.1.js"></script>
<script>
$(document).ready(function(){
// first handler - click on button
$("#btn").click(function() {
alert("Pressed button");
// Test empty web link
var link = "<a href='#'>Test link</a>";
// Add test link to div
$('#data').html(link);
});
// second handler - click on test link
$("a").click(function(){
var content = $(this).html();
alert(content);
});
});
</script>
</head>
<body>
<p>Test page:</p>
<form>
<input id="btn" type="button" value="Click me">
</form>
<!-- Add test link here -->
<div id="data"></div>
</body>
</html>
Первый обработчик -first handler- добавит линк на страничку, но второй обработчик -second handler- не будет срабатывать. Почему?
В данном случае мы имеем дело с динамически (по событию) добавленным в DOM элементом. Связано это с тем, что изначально идет загрузка всего документа и после полной загрузки DOM-структуры документа, мы можем работать с нашими обработчиками. Получается, что они могут работать только с первоначальной структурой документа. Это демонстрируется на следующем примере:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
<script src="jquery-1.9.1.js"></script>
<script>
$(document).ready(function(){
// Test empty web link
var link = "<a href='#'>Test link</a>";
// Add test link to div
$('#data').html(link);
// second handler - click on test link
$("a").click(function(){
var content = $(this).html();
alert(content);
});
});
</script>
</head>
<body>
<p>Test page:</p>
<form>
<input id="btn" type="button" value="Click me">
</form>
<!-- Add test link here -->
<div id="data"></div>
</body>
</html>
Если вытащить тело первого обработчика наружу, что приведет к добавлению тестовой ссылки во время загрузки и значит обработчику будет известно о ее существовании (ведь ссылка вошла в первоначальную структуру документа), так и есть, он срабатывает.
Как решить первоначальную проблему?
Для этого в jquery - библиотеке есть специальный метод:
.on( events [, selector ] [, data ], handler(eventObject) )
Он позволяет работать с добавляемыми динамически элементами в DOM-структуру докумена, в нашем случае нужно явно указать селектор тега, куда будет добавлена ссылка и повесить наш обработчик -second handler. Вот как будет выглядеть рабочий вариант:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
<script src="jquery-1.9.1.js"></script>
<script>
$(document).ready(function(){
// first handler - click on button
$("#btn").click(function() {
alert("Pressed button");
// Test empty web link
var link = "<a href='#'>Test link</a>";
// Add test link to div
$('#data').html(link);
});
// second handler - click on test link
$("#data").on("click", "a", function(){
var content = $(this).html();
alert(content);
});
});
</script>
</head>
<body>
<p>Test page:</p>
<form>
<input id="btn" type="button" value="Click me">
</form>
<!-- Add test link here -->
<div id="data"></div>
</body>
</html>
Все отрабатывает так, как мы того хотели :)
Ниже приведены еще пара рабочих примеров с аналогичной задачей:
- добавление ссылок в таблицу
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
<script src="jquery-1.9.1.js"></script>
<script>
$(document).ready(function(){
// second handler - click on test link
$("#tbl").on("click", "a", function(event){
var content = $(this).html();
alert(content);
});
// first handler - click on button
$("#btn").click(function() {
alert("Pressed button");
// Create and fill table
var table_row = "<tr>" +
"<td><a href='#' class='gip'>A11</a></td>" +
"<td><a href='#' class='gip'>A12</a></td>" +
"<td><a href='#' class='gip'>A21</a></td>" +
"<td><a href='#' class='gip'>A22</a></td>" +
"</tr>";
// Add content to table
$('#tbl').html(table_row);
});
});
</script>
<style>
#table_content
{
background-color:#00CCFF;
color:#000000;
}
</style>
</head>
<body>
<p><a href="#">Test page:</a></p>
<form>
<input id="btn" type="button" value="Click me to get json-data">
</form>
<!-- In this table will be displayed the data -->
<table id="tbl" border="1"></table>
</body>
</html>
- добавление ссылок в строку
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
<script src="jquery-1.9.1.js"></script>
<script>
$(document).ready(function(){
$('#add').click(function(){
$('body').append('<a class="new_el">new element</a>');
});
$('body').on('click','.new_el', function(){
alert('event on new_wl');
});
});
</script>
</head>
<body>
<p>Test page:</p>
<!-- Add test link here -->
<a id="add">add element</a>
</body>
</html>