I'm not sure if anyone else has experienced this in JQuery Mobile, but for some reason I can't prevent elements underneath my absolute positioned DIVs and fixed header from intercepting clicks/taps on mobile devices.
For example, I have a page that lists contacts in a long scrolling list. On that page is a floating header with a button. If I scroll the list downward and click on the floating header's button, the click will pass through to whatever contact is underneath the header, even though it cannot be visually seen because it is underneath the header.
If I click on a button in the header, the button never triggers - the list element underneath it always fires. If I scroll the list so that there is nothing underneath the header, however, I can click the header's button normally.
So far I've tried: - event.stopPropagation() on the header's button. This never even fired, however. The element underneath always steals focus
Detecting the click event's Y coordinates. If the coordinates are less than the height of the floating header, abort the click action. This didn't work either, however - after I did "return true;", the button's click handler never fired.
Setting z-indexes on the floating header and list item container, even though they are already visually correct.
I'm quite stumped. I tried to make a testbed but it works correctly there. It also works correctly on the JQM demo site, so it must be something about my app's CSS or structure. I can't think of what would cause floating elements to show correctly but only be tappable when nothing else tappable is underneath them.
Any ideas would be appreciated!
Figured this one out though a long process of elimination. The new "panel" introduced in JQM 1.3 causes problems with fixed headers on mobile devices. Any clicks on the header are ignored, as if the header has a lower z-index than what sits beneath it, even though it is visually on top.
I found the issue by ripping all of the classes off of the ui-panel-content-wrap DIV
var wrapper = $(".ui-panel-content-wrap");
$(wrapper).removeClass('ui-body-c').removeClass('ui-panel-animate').removeClass('ui-panel-content-wrap-closed').removeClass('ui-panel-content-wrap');
Once I did this, it of course broke the panel, but my fixed header was properly clickable again.
From there, I re-introduced each class until I found that "ui-panel-content-wrap" was the offender. I then traced it down to this:
/* hardware acceleration for smoother transitions on WebKit browsers */
.ui-panel-animate.ui-panel:not(.ui-panel-display-reveal),
.ui-panel-animate.ui-panel:not(.ui-panel-display-reveal) > div,
.ui-panel-animate.ui-panel-closed.ui-panel-display-reveal > div,
.ui-panel-animate.ui-panel-content-wrap,
.ui-panel-animate.ui-panel-content-fixed-toolbar {
-webkit-backface-visibility: hidden;
-webkit-transform: translate3d(0,0,0);
}
If you comment out or override -webkit-transform: translate3d(0,0,0); fixed headers will begin trapping events.
What I did for WP8 was put a backdrop behind your elements that has a click handler. If the click falls through, the element underneath will catch it. Usually there is a backdrop behind modals so that's where I put it. The e.stopPropagation()
is overkill but shouldn't hurt. You might also try one of the fixes in the comments. For the element that isn't firing when it should be, I don't know the circumstances but make sure your element is fully loaded before attaching the handler or attach it to the parent with the selector parameter parent.on('click','.button',function(){ //code });
html
<div class="backdrop"></div>
css
.backdrop{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
}
js
$(document).ready(){
$('.backdrop').on('click',function(e){
e.stopPropagation();
return false;
}
}
You can also just attach the click handler to the main parent of the elements to prevent it falling through as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With