Reputation: 11774
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.
Upvotes: 0
Views: 708
Reputation: 388326
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');
Upvotes: 1