-1

i'm using the following

  jquery 1.11.1
  jquery.mobile 1.4.3
  cordova 2.9.0
  iscroll 5

here's my html:

<div data-role="page" id="listpageid">

<div data-role="header" data-position="fixed">
         some radio buttons
</div>

    <div id="wrapper">
      <div data-role="content" id="scroller">
      </div>
     </div>

</div>

i have an ajax call that gets a bunch of data from a server. i loop thru the results and add them to the div with id="scroller"

$('#scroller').empty();

for (var i=0;i<resultsArr.length;i++)
{

     htmlToAppend = "";

     htmlToAppend = "<a id=" + i + " >" + resultsArr[i].field + "<br><br></a>";

     contentForDisplay = contentForDisplay.concat(htmlToAppend);

}

$('#scroller').append(contentForDisplay);

$('#scroller a').click(function() {
      alert("you clicked on " + this.id);
});

this code runs whenever an ajax call fills resultsArr

the first time the page displays and this is executed it gives me exactly what i want, a scrollable list of clickable links.

if i leave the page and navigate back however, things don't work properly.

the div named scroller is emptied and the contents of resultsArr are displayed but clicking on every link results in 2 alerts instead of 1.

if i leave the page and navigate back a 3rd time, clicking on a link gives 3 alerts instead of 1.

i have tried preventing this code

$('#scroller a').click(function() {
      alert("you clicked on " + this.id);
});

from executing on all but the first page display and that makes the displayed links unclickable on the 2nd, 3rd etc page displays.

i thought

$('#scroller').empty(); 

removed/destroyed the contents of the page and would include the function that gets fired on the click event.

obviously its not.

how do i allow for page redisplay BUT only attach the function to the click event once?

EDIT: none of your solutions worked. until i removed iscroll. then ALL your solutions worked. so .... does anyone have any ideas about how iscroll is screwing this up?

user1126515
  • 1,133
  • 3
  • 17
  • 34
  • Seems strange, you empty the container and insert new elements, and the old event handler shouldn't work on those new elements as it's not delegated. You must be adding the event handler inside some function that runs multiple times. – adeneo Jan 17 '15 at 19:05
  • Here's a more jQuery'ish way of doing things -> **http://jsfiddle.net/u2ffL7mp/** – adeneo Jan 17 '15 at 19:06
  • i was adding the event handler in a routine that executed each time i rebuilt the screen. however, after i changed to a delegated event the problem continued - see my conversation with Ozan below. i'm going to try your suggestion next. – user1126515 Jan 17 '15 at 20:25

2 Answers2

0

Use delegated events.

http://learn.jquery.com/events/event-delegation/

$(document).on("click", "#scroller a", function(e){ alert("You clicked " + this.id); });

Edit : Another way is to try unbinding events before rebinding them.

$('#scroller a').off("click.myEvent");
$('#scroller a').on("click.myEvent", function() {
  alert("you clicked on " + this.id);
});
Ozan
  • 3,709
  • 2
  • 18
  • 23
  • i tried adding this in onLoad(). the alert is being displayed once for each time the page is displayed. so if i display the page 4 times, click on a link then i'll get 4 alerts. i tried adding e.preventDefault() before the alert() but it didn't make a difference. – user1126515 Jan 17 '15 at 19:32
  • Why are you binding this multiple times? You need to call this only once. Just run this code once on page load and it should work. When you add any elements that matches the "#scroller a" selection, they would have the function bind to their click events. Another solution is using event namespaces and unbinding events before rebinding them again every time. You can see http://api.jquery.com/off/ for that. But using delegated events are much more elegant and sustainable. – Ozan Jan 17 '15 at 19:37
  • i thought putting this in onLoad() would only bind it once. i moved it to onDeviceReady() and am having the same results. edit: i verified my onLoad() and onDeviceReady() functions are only getting executed once. – user1126515 Jan 17 '15 at 19:54
  • That is strange. Try unbinding method i mentioned before. – Ozan Jan 17 '15 at 20:47
0

Put the delegated click handler in the jQM pagecreate event handler for the #listpageid page:

$(document).on("pagecreate", "#listpageid", function(){
    $("#scroller").on("click", "a", function(e){ 
        alert("You clicked " + this.id); 
        return false;
    });
});

Then leave your AJAX code where it is (in my demo it is in the pagebeforeshowhandler which runs each time you navigate to the page.

Here is a working DEMO

Each time you navigate to and from the page, a different number of fields is added to the scroller div; however only one click handler is ever active.

ezanker
  • 24,628
  • 1
  • 20
  • 35