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 341e1e1b5b..795dae8920 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 4d19cfa40e..9287125f66 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 9c9d54570b..e21046a08e 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 8ca4c75d0c..7c09cfe331 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 027145c23b..46d385f2f8 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 2b982cfb5c..b00cb796ab 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 6b8f0d534d..e5b24f86d4 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 d805473e1f..45d5ec1448 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 9c6390d821..24b8752bb5 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 6504657d8e..5f63491927 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; } }