Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safari iphone/ipad "mouse hover" on new link after prior one is replaced with javascript

After you click a link on the iphone or ipad, it leaves a simulated mouse hover that triggers the a:hover css styling on that link. If the link has a javascript handler that keeps you on same page, the hover state will not change until you click on another link.

This gets weird if you have an ajax widget that asks questions and each answer is link. When you touch one of the answers, it highlights with the hover state, and then when the question and answers are replaced (using javascript) by a new question and answers, the new answer that appears in the same position as the prior answer has its hover state automatically triggered. I want to prevent that from happening to the new answer link.

Is there any way (maybe some something in javascript) that can give me the same result as the "hover" no longer being above this element?

Notes:

  • I know I could just have a:hover use the same css styling as a, but a:active styling is hardly noticeable since the active state of a touch click is so brief, so I'm hoping for something that can show the hover state on a link until I replace it with new html
  • I have tried a variety of approaches in javascript, like calling "blur()" on the dom element and some other stuff, but no luck—I'm starting to think that the best solution is to apply classes to the links on javascript events to manage the hover state myself (or just leave it as it is)
like image 497
MrColes Avatar asked Jun 25 '10 18:06

MrColes


1 Answers

The problem is that when you replace the content in place, Mobile Safari treats the new elements as if they were the old ones, because they occupy the same position in the DOM. One workaround is to remove the old elements first, then add the new elements asynchronously. The simplest way to do this is using setTimeout().

http://jsfiddle.net/chad/JNZvu/10/

// When we click on an answer
$('body').on('click', '.answer', function(){
  // don't follow it's link
  event.preventDefault();
   // fade out the container
  $('.container').fadeOut(function(){
    // remove old elements (happens after fadeOut because we are in the callback)
    $('.container').html('');
    // add new elements asynchronously and fade container back in.
    setTimeout( '$(\'.container\').html(\'<a class="answer" href="#c">link 3</a><a class="answer" href="#d">link 4</a>\');$(\'.container\').fadeIn();', 0);
  });
});

When doing this for real, the fadeOut would be called at the same time as the AJAX function, and then the removal/addition would happen in the AJAX callback.

like image 155
Chad von Nau Avatar answered Nov 04 '22 11:11

Chad von Nau