September 1, 2012

Can not control the item which create by appendTo function

Question by jchuang1977

I want to get the image url (the img in #demo) wich I parser from the JSON data and appendTo #demo.

I can see the picture which I get from flickr after parser the JSON data and appendTo to #demo.

But the “$(‘#demo img’).bind(‘click’, function()” never be trigger. So I can not get the img url and dump to #log to debug.

But If I write some static img elements into #demo , the click function can be triggered.

Is the “appendTo” cause it ?

<!DOCTYPE html>
<html> 
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ch13_4_2</title>
<link rel="stylesheet" href="jquery.mobile.min.css">
<script src="cordova-1.5.0.js"></script>
<script src="jquery-1.6.4.min.js"></script>
<script src="jquery.mobile.min.js"></script>

<script>
function onDeviceReady() {
   $('#shoot').bind('click', function() {
     $("#demo").empty();
      $("#log").empty();

      $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tagmode=any&format=json&jsoncallback=?&tags=baby&id=82216313@N00" ,
              function(data) {
                $.each(data.items, function(i,item){

                var photoString = "<a href="#"><img src=" + item.media.m + "></a>";                
                 $(photoString).appendTo("#demo");

                  if ( i == 3) return false;
                });
              });             
   });   
} 

function onLoad() { 
   document.addEventListener("deviceready", onDeviceReady, false);
}   
</script>
</head>
<body onload="onLoad()">

<div data-role="page" id="home">   
   <div data-role="header" data-position="fixed">
     <h1>Andy's Flickr Search</h1>
     <a href="#" id="shoot" data-role="button" data-icon="search" data-inline="true">search</a>
   </div>


   <div data-role="content">
   <div id="log"></div>


     <div id="demo">

     </div> 

<script>

              $('#demo img').bind('click', function() {
                    $("#log").empty();
                    var img_link = this.src;                            
                    var photoString = "<img src=" + img_link + ">";                    
                    $('div #log').html(photoString);

           });  
</script>    


</div>   
</div>



</body>
</html>

Answer by undefined

For dynamically generated elements, events should be delegated from one of static parents of the element, you can use on method.

$('#demo').on('click', 'img', function(){
  // ...
})

Answer by Starx

Do not use bind any more. As of 1.7, use .on() to delegate the event handler.

$('#demo').on('click', 'img', function() {
   // ...
});

Update:

live() and bind() worked differently: live() will also work for non existent elements or elements that are created on the fly but bind() will only bind the event handlers for currently existing elements. Read More

.delegate() was used for event delegation, but .on() is improved version of it and will created for clean coding and combination of bind() and delegate()

Other good questions:

  1. jQuery: live() vs delegate()
  2. .delegate() vs .on()
  3. Jquery live() vs delegate()
...

Please fill the form - I will response as fast as I can!