Jquery. События для динамически добавленных элементов в DOM - структуру

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>