问题
When using the method of event delegation, we set the event handler on a higher level element (parent or grandparent), but this has an issue on iPad's Safari: if the parent element has a click handler, when the user touches anything inside this element, the whole region will gray out (on iOS 5.1), or flicker (on iOS 6).
So, if the parent or grandparent is 300 x 300 pixel, and the link is just a word, say 60 x 20 pixel, then when the user touches any where inside the parent (except the link), the whole 300 x 300 region will either gray out or flicker, depending on the iOS version.
This is an example: http://jsfiddle.net/2K3TB/30/ and it can be run on iPad's Safari with iOS 5.1 or 6 on a physical device or the iOS Simulator.
And I tried all the events listed on Apple's docs, and touchstart
can be listened on, and the event handler can perform a preventDefault()
so that there is no gray out or flicker. Example: http://jsfiddle.net/2K3TB/31/ But now, the link which will prepend a "ha" to the top of the document won't work. To make it work, I have to set a touchstart
handler on the link for the link to work: http://jsfiddle.net/2K3TB/33/
Is this a correct way to fix the gray out or flicker issue? Is there any other way? There is a problem with this method, that within this region, there might be dynamic content, such as links, buttons, checkboxes, radios, select, or any other possible <div>
that has a event handler, so I can't set a touchstart
handler on each unpredictable element. I might be able to use something like:
$("#container").on("touchstart", function(ev) {
if (ev.target.tagName.toLowerCase() !== "a") {
ev.preventDefault();
}
});
as in http://jsfiddle.net/2K3TB/35/ But then I will have to check all of <a>
, <input>
, <button>
, <select>
, or any element that might have a event handler bound to it. So this probably is not a good solution. Is there a good way to solve this gray out or flicker problem?
Update: Charlie's answer below worked well, but there is a catch also: once we set the css style of the container, the <a>
or any other tappable element also inherits from the style, and becomes transparent too. So I had to do something like:
var tapHighlightColorStyle = $("#the-container").css("-webkit-tap-highlight-color");
$("#the-container").css("-webkit-tap-highlight-color", "transparent");
$("#the-container a").css("-webkit-tap-highlight-color", tapHighlightColorStyle);
that is, I have to save the tap highlight color first, and then set the container to have it as transparent, and then set the <a>
underneath back to using that color. It works for <a>
and I wonder what about other elements, and whether I should use $("#the-container *")
to restore them instead, which could be inefficient. Or if there is a better way to deal with this.
By the way, this is the docs for the webkit CSS style. I tried to look for a similar style that is not inherited by the offspring but there doesn't seem to be one.
Update 2: It seems that if we just set the children back to that style, then it will be quite ok, as we go only one level down, and let the offsprings inherit from them:
var tapHighlightColorStyle = $("#the-container").css("-webkit-tap-highlight-color");
$("#the-container").css("-webkit-tap-highlight-color", "transparent");
$("#the-container").children().css("-webkit-tap-highlight-color", tapHighlightColorStyle);
回答1:
Is this the same type of problem you're experiencing: iPad Safari: How to disable the quick blinking effect when a link has been hit
If so, use this CSS rule:
*{
-webkit-tap-highlight-color:transparent;
}
I tested it with your fiddle on iOS 6.1 in the simulator, and there seems to no longer be any flicker.
来源:https://stackoverflow.com/questions/17173723/how-to-solve-flicker-on-ipad-when-event-delegation-is-used