Domanda

I have a list of elements with anchor tags whose href I populate dynamically on hover. Here is my binding code:

$('.charts-container').on('mouseenter', '.track', function(e) {
  Itunes.populateDownloadLink(e);
}

Here is the code that fires when the event is triggered:

var ITunes = {
  populateDownloadLink: function(e) {
 e.preventDefault();
 trackDownloadLink = jQuery(e.currentTarget).find('.itunes-download a');
   if (trackDownloadLink.attr('href') == '#') {
      apiURL = ITunes.getApiUrl(trackDownloadLink);
      // retrieve iTunes download link from iTunes API
      jQuery.getJSON(apiURL, function(data) {
         if (data.results.length > 0) {
            trackDownloadLink.attr('href', data.results[0].trackViewUrl);
       }
  });
}

This works for the most part, except when I hover really quickly between elements. Sometimes, when that happens, it seems the links will get messed up. The element above another element, for example, will have a link that was generated by an element below it when I quickly hovered over it. There seems to be some kind of race condition occurring where an element takes on the first URL generated, even if it's not the element the URL was generated for. I find this weird, because I'm using e.currentTarget, which from what I understand should always refer to the element that a function was bound to, not where the mouse currently is or even the exact element that triggered the event to be registered.

È stato utile?

Soluzione

The problem seems to be you are declaring trackDownloadLink as a global variable, you need to declare it as a local variable to the populateDownloadLink method by using var to declare it.

If you use it as a global variable, assume you hover over link 1 then trackDownloadLink will refer to the corresponding anchor element and an ajax request is sent to fetch the href value, then before the ajax is completed you hover over link2 now the global variable trackDownloadLink is referring to the anchor in link2 instead of link1 and then the first ajax returns, at this time in the ajax complete when trackDownloadLink.attr('href', data.results[0].trackViewUrl); is executed trackDownloadLink is referring to the second link instead of first.

var trackDownloadLink = jQuery(e.currentTarget).find('.itunes-download a');
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top