How to make :checked work on Android Browser?

2019-04-19 05:16发布

问题:

I'm trying to make a form that has a list of default options, and which can also expand to show a couple of exta options. I do this with the following CSS code:

.myForm .moreOpts {display:none;}
.myForm #more:checked +*+ .moreOpts {display:block;}

with the following HTML:

<form action="#" class="myForm">
  <ul>
    <li>
      <input type="checkbox" id="pref-1" name="pref-1" value="1">
      <label for="pref-1">Foo</label>
    </li>
    <li>
      <input type="checkbox" id="pref-2" name="pref-2" value="2">
      <label for="pref-2">Bar</label>
    </li>
    <li>
      <input type="checkbox" id="more" name="more" value="true">
      <label for="more">More options</label>
      <ul class="moreOpts">
        <li>
          <input type="checkbox" id="pref-3" name="pref-3" value="3">
          <label for="pref-3">Baz</label>
        </li>
        <li>
          <input type="checkbox" id="pref-4" name="pref-4" value="3">
          <label for="pref-4">Qux</label>
        </li>
      </ul>
    </li>
  </ul>
</form>

Demo

This code works perfectly in every browser, except for Android Browser and Dolphin. I've found an article that recommends adding this "bugfix", but that only fixes my problem in Dolphin.

Is there any way to make this work for the default Android Browser too?

回答1:

You can achieve this with the help of the details element. Android supports it since version 4. However, you will have to deal with IE and Firefox, but fortunatly these browser support the CSS3 pseudo states, including :checked.

Two merge these two, just use the checkbox hack in browsers that don't support details. Here's the process explained in code: http://jsfiddle.net/hF6JP/1/

EDIT: this is the final solution, putting label inside the summary resolves the problem of having a forced checkbox to toggle the options: http://jsfiddle.net/mYdsT/



回答2:

I wouldn't trust :checked for all browsers. I'd capture the click event of #more and just add a class to the parent. It's easy with jQuery. This option will work in Android and IE8.

$("#more").on("click", toggleCheckboxes);
var toggleCheckboxes = function(evt){
  var $this = $(this);
  $this.parents("li").toggleClass("show-more-options");
  evt.preventDefault()
}



.myForm .moreOpts {
  display:none;
}
.myForm .show-more-options .moreOpts {
  display:block;
}

:checked isn't supported in IE8, which is sadly still a big deal

https://developer.mozilla.org/en-US/docs/Web/CSS/:checked



回答3:

http://quirksmode.org/css/selectors/mobile.html#t60

:checked apparently doesn't work in any version of Android. I'm not sure why so many webpages report that it should work (apparently from 2.1 up), but this is false.

The nice thing about QuirksMode is that every feature is actually tested in a real browser before they post it on the web.

JavaScript appears to be your best solution. I would even recommend javascript because if a user checks the "more" box, then selects some of the extra options, and then unchecks the "more" box... the extra selections will still be "checked" and will get submitted if a user hits a "submit" button. You will have to un-check those boxes every time the "more" box is un-checked. The only way to do this is with javascript.

UPDATE: QuirksMode has written a flawed test for the :checked selector:

:checked {
    display: inline-block;
    width: 3em;
}

You will notice that on Android the width never changes... but this is due to the fact that Android does not apply a width to checkboxes and radios (while desktop browsers do).

The following does work, even in my Android 2.3:

:checked {
    display: inline-block;
    margin: 3em;
}

So, as stated in other comments, the problem is with the combination of the checked selector and the adjacent sibling selector:

:checked + .test { /* does not work on android :( */ }
:checked ~ .test { /* does not work on android :( */ }