From baa04cde4d7292d07ec2bfae949e008aeaafae1b Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Sat, 15 Mar 2014 01:12:56 -0500 Subject: [PATCH] feat(active): Removing use of :active in favor of .active for more control of active state Using the :active pseudo works fine for desktop, but mobile is a completely different beast, especially with the quirks of each platform. By intentionally not using any :active selectors and manually adding/removing a .active class, it gives us a precise control on how the active state works for ALL platforms. Additionally, this places less selectors in the css, and reduces the possibility of unnecessary repaints. Currently this method of using .active instead of :active is being applied to .button and .item elements. --- js/utils/tap.js | 23 +++++++++++++++++++++++ scss/_action-sheet.scss | 2 +- scss/_bar.scss | 1 - scss/_button.scss | 3 +-- scss/_checkbox.scss | 3 +-- scss/_form.scss | 6 ------ scss/_items.scss | 3 +-- scss/_mixins.scss | 4 ++-- scss/_tabs.scss | 3 +-- scss/_toggle.scss | 3 +-- 10 files changed, 31 insertions(+), 20 deletions(-) diff --git a/js/utils/tap.js b/js/utils/tap.js index 341e1e1b5b5..795dae89200 100644 --- a/js/utils/tap.js +++ b/js/utils/tap.js @@ -175,6 +175,13 @@ var tap = isRecentTap(e); if(tap) delete tapCoordinates[tap.id]; }, REMOVE_PREVENT_DELAY); + + setTimeout(function(){ + for(var hitKey in hitElements) { + hitElements[hitKey] && hitElements[hitKey].classList.remove('active'); + delete hitElements[hitKey]; + } + }, 150); } function stopEvent(e){ @@ -197,6 +204,20 @@ function recordStartCoordinates(e) { startCoordinates = getCoordinates(e); + + var x, ele = e.target; + for(x=0; x<5; x++) { + if(!ele || ele.tagName === 'LABEL') break; + if( ele.classList.contains('item') || ele.classList.contains('button') ) { + hitElements[hitCounts] = ele; + hitCounts = (hitCounts > 24 ? 0 : hitCounts + 1); + ionic.requestAnimationFrame(function(){ + ele.classList.add('active'); + }); + break; + } + ele = ele.parentElement; + } } var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly @@ -204,6 +225,8 @@ var CLICK_PREVENT_DURATION = 1500; // max milliseconds ghostclicks in the same area should be prevented var REMOVE_PREVENT_DELAY = 375; // delay after a touchend/mouseup before removing the ghostclick prevent var HIT_RADIUS = 15; + var hitElements = {}; + var hitCounts = 0; // set global click handler and check if the event should stop or not document.addEventListener('click', preventGhostClick, true); diff --git a/scss/_action-sheet.scss b/scss/_action-sheet.scss index 4d19cfa40e9..9287125f669 100644 --- a/scss/_action-sheet.scss +++ b/scss/_action-sheet.scss @@ -69,7 +69,7 @@ border-width: 1px 0px 0px 0px; border-radius: 0; - &.active, &:active { + &.active { background-color: transparent; color: inherit; } diff --git a/scss/_bar.scss b/scss/_bar.scss index 9c9d54570b9..e21046a08e8 100644 --- a/scss/_bar.scss +++ b/scss/_bar.scss @@ -173,7 +173,6 @@ } } - &.back-button:active, &.back-button.active { opacity: 1; } diff --git a/scss/_button.scss b/scss/_button.scss index 8ca4c75d0ce..7c09cfe331f 100644 --- a/scss/_button.scss +++ b/scss/_button.scss @@ -164,7 +164,6 @@ border-color: transparent; background: none; - &.button:active, &.button.active { border-color: transparent; background: none; @@ -187,7 +186,7 @@ background: none; box-shadow: none; - &:active, &.active { + &.active { opacity: 0.3; } } diff --git a/scss/_checkbox.scss b/scss/_checkbox.scss index 027145c23b1..46d385f2f8a 100644 --- a/scss/_checkbox.scss +++ b/scss/_checkbox.scss @@ -100,8 +100,7 @@ .item-checkbox { padding-left: ($item-padding * 2) + $checkbox-width; - &.active, - &:active { + &.active { box-shadow: none; } } diff --git a/scss/_form.scss b/scss/_form.scss index 2b982cfb5cd..b00cb796ab5 100644 --- a/scss/_form.scss +++ b/scss/_form.scss @@ -68,12 +68,6 @@ textarea { font-size: 16px; } - &.item.active, - .ionic-pseudo &.item:active { - border-color: $item-default-border; - background-color: transparent; - } - .button-bar { @include border-radius(0); @include flex(1, 0, 220px); diff --git a/scss/_items.scss b/scss/_items.scss index 6b8f0d534d1..e5b24f86d4b 100644 --- a/scss/_items.scss +++ b/scss/_items.scss @@ -95,8 +95,7 @@ } // Link and Button Active States -.item.active:not(.item-divider):not(.item-input-inset), -.item:active:not(.item-divider):not(.item-input-inset), +.item.active:not(.item-divider):not(.item-input):not(.item-input-inset), .item-complex.active .item-content { @include item-active-style($item-default-active-bg, $item-default-active-border); diff --git a/scss/_mixins.scss b/scss/_mixins.scss index d805473e1f2..45d5ec14486 100644 --- a/scss/_mixins.scss +++ b/scss/_mixins.scss @@ -12,7 +12,7 @@ color: $color; text-decoration: none; } - &.active, &:active { + &.active { background-color: $active-bg-color; box-shadow: inset 0px 1px 3px rgba(0,0,0,0.15); border-color: $active-border-color; @@ -44,7 +44,7 @@ $text-color: $color; } color: $text-color; - &.active, &:active { + &.active { background-color: $color; color: #fff; box-shadow: none; diff --git a/scss/_tabs.scss b/scss/_tabs.scss index 9c6390d8210..24b8752bb5c 100644 --- a/scss/_tabs.scss +++ b/scss/_tabs.scss @@ -168,8 +168,7 @@ /* Navigational tab */ /* Active state for tab */ -.tab-item.active, -.tab-item:active { +.tab-item.active { opacity: 1; &.tab-item-light { diff --git a/scss/_toggle.scss b/scss/_toggle.scss index 6504657d8e2..5f63491927b 100644 --- a/scss/_toggle.scss +++ b/scss/_toggle.scss @@ -104,8 +104,7 @@ .item-toggle { padding-right: ($item-padding * 3) + $toggle-width; - &.active, - &:active { + &.active { box-shadow: none; } }