Why are touch event listeners seemingly preventing

2020-04-10 01:42发布

问题:

I've a problem with the google translate widget. When using the iphone or the ipad I can't select the language to translate to. I can click the first button, but then when the languages menu appears and I tap a language, the menu immediately disappears and the click registers on the element that was behind the menu. This problem only occurs under very specific situations which I will outline below.

  • The problem described below has been observed on an iphone4 ios5.0.1 and ipad2 ios 7.0.6.
  • The problem has NOT been observed on firefox 29.0.1, chrome 31.0.1650.63 m or internet explorer 11.
  • JSfiddle of the problem at http://jsfiddle.net/LfkLy/1/
  • Reveal.js is not needed to recreate this problem.

I first noticed the problem when I used the widget on a page with reveal.js After a lot of playing around, I found that if I set touch to false in the reveal.js config or commented out lines below, the widget worked as it should have.

dom.wrapper.addEventListener( 'touchstart', onTouchStart, false );
dom.wrapper.addEventListener( 'touchmove', onTouchMove, false );
dom.wrapper.addEventListener( 'touchend', onTouchEnd, false );

I decided to remove reveal.js touch events and implement my own using hammer.js and the hammer jquery plugin. I used something like this

// hammer.js
$('.reveal').hammer().on("tap", function() 
{                       
    console.log("tapped with a hammer");
}); 

Once the above code was implemented, the problem occurred again. I modified the code and tried it with just hammer.js and got the same result. The problem occurred regardless of which part of the page I attached the touch listener to. For curiosity's sake I tried it with jquery and again got the same result.

//Test with jquery    
$('.reveal').on("touchstart", function() 
{ 
   console.log("touched with jquery");
});

Interestingly enough, when I used the click function there was no problem with the widget.

$('.reveal').on('click',function()
{
    console.log("jquery click worked");
});

Despite the obvious link between touch events and the problem, I haven't dismissed the possibility that this may somehow be related to CSS. UPDATE: In particular, I'm starting to suspect it might have something to do with :hover and the touch events.

QUESTIONS

  1. Why is this happening?
  2. How can I listen for touch events such as touchstart and still use the google translate widget on the iphone/ipad?

MY GOOGLE TRANSLATE WIDGET CODE

<div class="custom-translate" id="google_translate_element"></div>


<script type="text/javascript">
function googleTranslateElementInit() {
  new google.translate.TranslateElement({pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false},'google_translate_element');
}

(function() {
  var googleTranslateScript = document.createElement('script');
  googleTranslateScript.type = 'text/javascript';
  googleTranslateScript.async = true;
  googleTranslateScript.src = '//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit';
  ( document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] ).appendChild( googleTranslateScript );
})();
</script>       

回答1:

The problem is that for the layout you've selected, the Google Translate widget opens the language options "dropdown" in a new iframe, and (long story short) hammer.js doesn't play nicely with iframe content (presumably reveal.js has the same issue).

You could try some pretty complicated means of working around the issue involving dealing with the events and the iframe content, but a much simpler solution is to use another layout that doesn't use the iframe, e.g. replace SIMPLE with HORIZONTAL or VERTICAL

function googleTranslateElementInit() {
  new google.translate.TranslateElement({
    pageLanguage: 'en',
    layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL,
    autoDisplay: false
  },'google_translate_element');
}

I've updated your most recent fiddle here: http://jsfiddle.net/LfkLy/10/