how to prevent bleeding through of clicks on Andro

2019-04-02 02:22发布

I have a Jquery Mobile page. In my header I have a button to open a hidden layer above my actual page. This layer also contains a header with a button on the same spot. If I show the layer and click the button, it "bleeds" through to the button below firing both.

Not sure if the HTML is any help:

<div data-role="page" id="base" data-wrapper="true">
   <div data-role="header" data-theme="a">
      // first button 
      <div class="headWrapLeft ui-btn-left">
        <div data-role="controlgroup" > 
           <select data-iconpos="notext" data-icon="home">
              <option value="global">ALL</option>
              <option value="local" selected="selected">SINGLE</option>         
              <option value="menu">Main Menu</option>
            </select>
         </div>
       </div>
       <h1>Header</h1>                  
    </div>
    <div data-role="content">
    // page content  
    </div>


    <div data-role="panel" data-id="setup" data-panel="popover"">

       <div data-role="page" data-show="first" id="main_setup">
      <div data-role="header" data-position="fixed" data-theme="a">
            // back button will be inserted here
            <h1>Setup</h1>
          </div>
          ...
       </div>
    </div>
 </div>// end wrapper page

The first page is my base page. The popover panel is an overlay container, which opens as a fullscreen HTML page on smartphones. On Tablet everything works fine, because the panel opens like a popup window AND there is no button "behind" the panel on the background. On smartphone however, the backbutton is sitting right on top of the background page select. When I click the back button, the select fires.

Question:
You can find some people asking here and there how to prevent bleeding through of clicks on Android. I have not really found any solution that works.

I'm not sure this has to do with event bubbling or z-index being ignored, so:

I'm looking for any ideas how to make sure, if I click on a button, this button and nothing else gets a click... Any idea on how to achieve this are greatly appreciated!

Thanks for help!

EDIT:
I think I know what's wrong - see this issue on Android:
http://code.google.com/p/android/issues/detail?id=6721

Pondering what the best way to work around this is. I can't set the background page to display:none or move it out of view, because the overlay pages is nested. I also don't want to disable all background links while the overlay page is visible.

Thanks for some more ideas!

3条回答
Fickle 薄情
2楼-- · 2019-04-02 02:58

You don't show how you are binding your event handler(s) so I'll have to assume you are binding to the vclick event. If this is the case then you will have to manually discard the second vclick event that gets dispatched.

The vclick event can fire twice on some devices (namely Android 2.1 to 2.3, but others too), and if the content around the clicked area changes between the times those two events fire, then you can get two elements that trigger event handlers.

Here is the fix I use when I want to use the vclick event:

//setup flag
var vclick_ok = true;

//delegate the event handling so any element added at any time with the correct class and tagName will trigger this event handler
$(document).delegate('a.vclick', 'vclick', function () {

    //check if it's OK to run the event handler
    if (vclick_ok) {

        //if it's OK to run, disable the next time this event handler runs until the setTimeout fires and resets the flag
        vclick_ok = false;
        setTimeout(function () { vclick_ok = true; }, 500);
    }
});

This allows a link to only be pressed once every half second, which should be fine for opening a dialog (since the user won't expect to be able to click the button rapidly anyway).

查看更多
Anthone
3楼-- · 2019-04-02 03:08

Ok. Here is how I'm doing it.

When showing the overlay popover panel, I'm calling this:

// Android-Bleeding-Click
// http://code.google.com/p/android/issues/detail?id=6721   
var $popPanel = $('div:jqmData(id="setup")');

$('.ui-page').not( $popPanel.find('.ui-page-active') )
    .find(".ui-header")
    .first()
       .find(".ui-btn, input, select, textarea")
       .addClass('ui-disabled androidStealsMyTime')
       .attr('disabled','disabled')

When hiding the overlay, I'm calling this:

$('.androidStealsMyTime').removeClass('ui-disabled androidStealsMyTime')
                           .removeAttr('disabled');

The above is for JQM enhanced elements. If it was plain inputs, you could toggle disabled on the input itself, but since JQM adds some elements as child or siblings, you need to capture everything there is. It's not perfect ... disabled=disabled on a.link elements is semantically questionable I guess, but then agin, it fits into one line and works.

查看更多
Bombasti
4楼-- · 2019-04-02 03:21

Returning false from the click() method should prevent it from bubbling any farther.

查看更多
登录 后发表回答