开发者

How to simulate :active css pseudo class in android on non-link elements?

I'd like to be able to mimic the behavior of the :active pseudo class on all elements in Android webkit. Currently, the :active syntax only works on a elements (links). Nearly all of the actionable elements in the app I'm working on are something other than a standard link tag. iOS we开发者_如何学Gobkit supports :active on all elements.

/* works on both android iOS webkit */
a:active {
    color: blue;
}
/* works on iOS webkit, does not work on android webkit */
div:active {
    color: red;
}

I've found a couple of resources [1,2] that solve similar problems, but they're both a bit heavy, and I'm wondering if there's a lighter weight solution that I'm just not able to find.

  1. http://cubiq.org/remove-onclick-delay-on-webkit-for-iphone
  2. http://code.google.com/intl/ro-RO/mobile/articles/fast_buttons.html


Based on what @caffein said, here's a full implementation of this:

For all :active code, write CSS rules that look like this.

my-button:active, .my-button.fake-active {
 background-color: blue;
}

Then in your document ready event add this code:

if (navigator.userAgent.toLowerCase().indexOf("android") > -1) {
 $(".my-button")
 .bind("touchstart", function () {
     $(this).addClass("fake-active");
 })
 .bind("touchend", function() {
     $(this).removeClass("fake-active");
 });
}

This has the advantage of using the fast native :active class on iOS, and dropping back to JavaScript on Android.

Taken from my blog at http://pervasivecode.blogspot.com/2011/11/android-phonegap-active-css-pseudo.html

EDIT: I've since discovered that buttons can occasionally 'stick' in the fake-active state. The fix for this is to also handle the touchcancel event. E.g. add this to the above..

.bind("touchcancel",
 function() {
  var $this = $(this);
  $this.removeClass("fake-active");
 });


If you don't want to use any script, which adds and removes class for active state of an element, just add empty touchstart event to the body tag:

<body ontouchstart="">

This will tell the android device to handle touch events and pseudo class :active will work correctly on all elements.


No-jQuery version based on Ben Clayton's solution.

EDIT: added "touchmove" event.

function hasClass(ele,cls) {
  return ele.className.match(new RegExp("(\\s|^)"+cls+"(\\s|$)"));
}
function addClass(ele,cls) {
  if (!this.hasClass(ele,cls)) ele.className += " "+cls;
}
function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp("(\\s|^)"+cls+"(\\s|$)");
    ele.className=ele.className.replace(reg," ");
  }
}

window.onload = function() {
  if (navigator.userAgent.toLowerCase().indexOf("android") > -1) {
    var elements = document.getElementsByClassName("my-button");
    for(var i = 0; i < elements.length; i++) {
      var elm = elements[i];
      elm.addEventListener("touchstart", function() {
        addClass(this, "fake-active");}, false);
      elm.addEventListener("touchmove", function() {
        removeClass(this, "fake-active");}, false);
      elm.addEventListener("touchend", function() {
        removeClass(this, "fake-active");}, false);
      elm.addEventListener("touchcancel", function() {
        removeClass(this, "fake-active");}, false);
    }
  }
}


The ":active " pseudo class is triggered when you actually click or press an element. A workaround for smartphones is to use the Javascript events: "ontouchstart" & "ontouchend".

Try using ontouchstart to modify the style and ontouchend to actually trigger the action.


Since I can't comment, I'm going to add another answer here.

Nadzeya suggested the following solution:

<body ontouchstart="">

This does work as described, but I believe it may also have an unintended consequence.

There has been a problem on our site where buttons would occasionally stop working. In fact, the button would change colors (as if it was pressed) but the click event wouldn't fire. Even submit buttons on forms would fail to submit the form (no Javascript involved), even after appearing pressed.

Today, I saw the problem again. On a whim, I removed this attribute and the problem went away. I then added it again and the problem came back.

Since I can't reproduce the problem reliably, I can't be certain that this was the cause, but for now I'm going to leave the tag off and solve the :active problem another way.


try this. It works for me perfectly on Android

.my-button {
     -webkit-tap-highlight-color: blue;
}


Trying add this code to your HTML:

<script>
document.body.addEventlistener('touchstart',function(){},false);
</script>


I got an easy alternate solution. This however requires you to change from div tag to a tag.

<a class="html5logo" href="javascript:void(0);" ontouchstart="return true;"></a>

.html5logo {
  display: block;
  width: 128px;
  height: 128px;
  background: url(/img/html5-badge-128.png) no-repeat;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  -webkit-tap-highlight-color: transparent; /* For some Androids */
}
.html5logo:active {
  -webkit-transform: scale3d(0.9, 0.9, 1);
}

Please find the source at phone gap tutorial


you just need put this code in your document:

<script type="application/x-javascript">document.addEventListener('touchmove', function(e){e.preventDefault();}, false);</script>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜