Skip to content
This repository was archived by the owner on Mar 15, 2018. It is now read-only.

Commit 64ff8a3

Browse files
committed
Merge pull request #833 from cvan/nav-tweax-scroll
add smooth scrolling to mobile nav (bug 1109260, bug 1059002)
2 parents dca5f72 + 8b59387 commit 64ff8a3

File tree

3 files changed

+92
-152
lines changed

3 files changed

+92
-152
lines changed

src/media/css/navbar.styl

Lines changed: 47 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@
66
background-image: url(../img/pretty/gear.svg);
77
}
88

9-
.navbar a {
10-
text-decoration: none;
9+
.navbar {
10+
disable-user-select();
11+
display: inline-block;
12+
13+
a {
14+
text-decoration: none;
15+
}
1116
}
1217

1318
.tab-item {
1419
display: inline-block;
1520
font-size: 15px;
21+
height: $header-height;
22+
line-height: 50px;
1623
position: relative;
1724
text-align: center;
1825
text-transform: uppercase;
@@ -34,6 +41,7 @@
3441
border-bottom: 3px solid transparent;
3542
color: $navbar-text;
3643
display: block;
44+
height: $header-height;
3745

3846
&:hover {
3947
border-bottom-color: $bg-gray;
@@ -61,18 +69,14 @@
6169
}
6270

6371
@media $narrower-than-desktop {
64-
// New feed navigation (mobile only).
65-
header .act-tray {
72+
// Feed navigation (mobile only).
73+
header .act-tray,
74+
body[data-page-type~=settings] .back {
6675
display: none;
6776
}
68-
body[data-page-type~=settings] {
69-
.back {
70-
display: none;
71-
}
72-
.site {
73-
display: block;
74-
width: 35px;
75-
}
77+
body[data-page-type~=settings] .site {
78+
display: block;
79+
width: 35px;
7680
}
7781
body[data-page-type~=leaf],
7882
body[data-page-type~=search] {
@@ -85,10 +89,11 @@
8589
.site-nav {
8690
background: $navbar-gray;
8791
bottom: 0;
88-
height: 50px;
92+
height: 49px;
8993
overflow: hidden;
9094
position: relative;
91-
transition(unquote('bottom .5s, margin-bottom .5s'));
95+
transition(unquote('bottom .2s, margin-bottom .2s'));
96+
transform(unquote('translate3d(0,0,0)'));
9297

9398
// act-tray is link to Settings tabs (e.g., Settings, Purchases).
9499
// mkt-tray is link to Marketplace tabs (e.g., Home, New, Popular).
@@ -97,13 +102,13 @@
97102
background-color: $cloud-gray;
98103
border: 1px solid $cement-gray;
99104
height: 51px;
100-
transition(right .4s);
105+
transition(right .2s);
101106
width: 56px;
102107
z-index: 2;
103108

104109
&.active {
105110
right: 0;
106-
transition(right .2s .6s);
111+
transition(right .2s .4s);
107112
}
108113
.header-button {
109114
background-size: 30px auto;
@@ -116,7 +121,7 @@
116121
border-radius: 0 80px 80px 0;
117122
bottom: 2px;
118123
position: relative;
119-
right: 55px;
124+
right: 56px;
120125

121126
&.active .header-button.settings {
122127
background-image: url(../img/pretty/gear.svg);
@@ -127,7 +132,7 @@
127132
}
128133
.mkt-tray {
129134
border-radius: 80px 0 0 80px;
130-
bottom: 0;
135+
bottom: -1px;
131136
position: absolute;
132137
right: -60px;
133138

@@ -145,45 +150,41 @@
145150
}
146151
}
147152

148-
.navbar {
149-
disable-user-select();
153+
.navbar-container {
150154
display: inline-block;
151-
opacity: 1;
152-
padding: 8px 0;
155+
left: 0;
156+
-moz-overflow-scrolling: touch;
157+
-webkit-overflow-scrolling: touch;
158+
overflow-scrolling: touch;
159+
overflow-x: scroll;
160+
overflow-y: hidden;
153161
position: absolute;
154162
top: 0;
155-
transition(unquote('right .5s ease-out, left .3s ease-in'));
156163
white-space: nowrap;
157164
width: 100%;
165+
}
158166

159-
&.nav-mkt {
160-
visibility: hidden;
161-
right: -100%;
167+
.navbar {
168+
display: none;
169+
padding-bottom: 60px;
162170

163-
&.active {
164-
right: -65px;
165-
visibility: visible;
166-
}
171+
&.active {
172+
display: block;
167173
}
168-
&.nav-settings {
169-
visibility: hidden;
170-
right: 100%;
171174

172-
&.active {
173-
right: 0;
174-
visibility: visible;
175-
}
175+
// Account for "Settings" icon.
176+
&.nav-mkt.active .tab-item:first-child {
177+
padding-left: 65px;
176178
}
177-
}
178179

179-
.tab-item {
180-
top: 2px;
180+
// Account for "Back to Marketplace" icon.
181+
&.nav-settings.active .tab-item:last-child {
182+
padding-right: 65px;
183+
}
181184
}
182185

183186
.tab-link {
184187
color: $navbar-text;
185-
height: 38px;
186-
line-height: 32px;
187188
padding: 0 10px;
188189
}
189190

@@ -199,19 +200,16 @@
199200
display: none;
200201
}
201202
.site-nav {
202-
background-color: #E0E0E0;
203+
background-color: $navbar-gray;
203204
margin: 0 auto;
204205
z-index: 25;
205206
}
207+
206208
.navbar {
207-
disable-user-select();
208-
display: inline-block;
209209
margin: 0 auto;
210210
left: 0;
211-
height: 100%;
212-
opacity: 1;
213211
position: absolute;
214-
right: 0 !important; // navbar.js sets rule on `style`, so override.
212+
right: 0;
215213
top: 0;
216214
white-space: nowrap;
217215
width: -moz-fit-content;
@@ -220,15 +218,13 @@
220218
}
221219

222220
.tab-item {
223-
line-height: 50px;
224221
padding: 0 60px;
225222

226223
&.active > .tab-link {
227224
color: $breezy-blue;
228225
}
229226
}
230227
.tab-link {
231-
display: block;
232228
outline: 0;
233229
height: $header-height;
234230
}
@@ -239,6 +235,7 @@
239235

240236
.desktop-cat-link {
241237
display: inline;
238+
pointer-events: none;
242239

243240
&:after {
244241
border: 4px solid transparent;

src/media/js/navbar.js

Lines changed: 23 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
define('navbar',
2-
['categories', 'jquery', 'log', 'navigation', 'nunjucks', 'settings',
3-
'underscore', 'urls', 'user', 'z'],
4-
function(cats, $, log, navigation, nunjucks, settings, _, urls, user, z) {
2+
['capabilities', 'categories', 'jquery', 'log', 'navigation', 'nunjucks',
3+
'settings', 'underscore', 'user', 'z'],
4+
function(capabilities, cats, $, log, navigation, nunjucks, settings, _,
5+
user, z) {
56
'use strict';
67
var logger = log('navbar');
78

8-
var DESKTOP_WIDTH = 710;
9-
var NAV_MKT_BASE_OFFSET = -65;
10-
var NAV_SETTINGS_BASE_OFFSET = 0;
119
var NAV_LINK_VISIBLE_WIDTH = 50;
1210

1311
function initNavbarButtons() {
1412
// Navbar settings + Marketplace buttons.
13+
var $navContainer = $('.navbar-container');
1514
var $mktNav = $('.nav-mkt');
1615
var $settingsNav = $('.nav-settings');
1716
var $mktNavGroup = $mktNav.add('.act-tray-mobile');
@@ -20,14 +19,15 @@ define('navbar',
2019
function toggleNavbar($on, $off) {
2120
$on.addClass('active');
2221
$off.removeClass('active');
22+
$navContainer[0].scrollLeft = 0;
2323
}
2424

2525
function fitNavbarOnSwitch($navbar, $item) {
2626
// Switching between navbars makes it difficult to do initial
2727
// line-fitting since the navbar is in a transitioning state. So
2828
// we do a timeout. But for navbars that have already been fitted,
2929
// don't do a timeout delay.
30-
var waitForTransition = 500;
30+
var waitForTransition = 200;
3131
if ($navbar.data('fitted')) {
3232
waitForTransition = 0;
3333
}
@@ -41,7 +41,6 @@ define('navbar',
4141
z.body.on('click', '.act-tray-mobile', function(e) {
4242
// Activate Settings page navbar.
4343
e.preventDefault();
44-
$mktNav.css('right', ''); // Reset the offset for transition effect.
4544
toggleNavbar($settingsNavGroup, $mktNavGroup);
4645

4746
var $firstLink = $settingsNavGroup.find('[data-tab]:first-child a');
@@ -53,7 +52,6 @@ define('navbar',
5352
.on('click', '.mkt-tray', function(e) {
5453
// Activate Marketplace pages navbar.
5554
e.preventDefault();
56-
$('.nav-settings').css('right', ''); // Reset the offset for transition effect.
5755
toggleNavbar($mktNavGroup, $settingsNavGroup);
5856

5957
var $firstLink = $mktNavGroup.find('[data-tab]:first-child a');
@@ -65,76 +63,22 @@ define('navbar',
6563
.on('click', '.site a', function() {
6664
// Activate Marketplace pages navbar.
6765
toggleNavbar($mktNavGroup, $settingsNavGroup);
68-
});
69-
}
70-
z.body.one('loaded', initNavbarButtons);
71-
72-
z.body.on('click', '.navbar li > a', function() {
73-
var $this = $(this);
74-
if ($this.hasClass('desktop-cat-link')) {
75-
// Don't allow click of category tab on desktop.
76-
return;
77-
}
78-
79-
calcNavbarOffset($this.closest('li'));
80-
});
81-
82-
function calcNavbarOffset($item) {
83-
// Calculate appropriate offsets for the navbar so that it slides well
84-
// for any language. Good luck understanding what's going on.
85-
var $navbar = $item.closest('.navbar');
86-
if (!$navbar.length) {
87-
return;
88-
}
89-
90-
var currentNavbarOffset = $navbar.offset().left * -1;
91-
var padding = 10;
92-
var right = currentNavbarOffset;
93-
var rightEdgeOffset = $item.offset().left + $item.width();
94-
95-
var baseOffset = NAV_MKT_BASE_OFFSET;
96-
var windowWidth = z.win.width();
97-
if ($navbar.hasClass('nav-settings')) {
98-
baseOffset = NAV_SETTINGS_BASE_OFFSET;
99-
windowWidth -= $('.mkt-tray').width();
100-
}
101-
102-
if (rightEdgeOffset > windowWidth) {
103-
// Sliding forwards.
104-
// If the link is overflowing off the right edge of the page,
105-
// slide the navbar enough so the link is fully visible.
106-
right = (currentNavbarOffset +
107-
(rightEdgeOffset - windowWidth) + padding);
108-
109-
// If there is another link after the current link, move the navbar
110-
// some more such that the next link is clickable (50px target).
111-
if ($item.next().length) {
112-
right += NAV_LINK_VISIBLE_WIDTH;
113-
}
114-
} else if (currentNavbarOffset !== NAV_MKT_BASE_OFFSET) {
115-
// Sliding backwards.
116-
// If the next link to the one clicked is in full view, slide it
117-
// so it becomes visible by only 50px and thus clickable.
118-
var $next = $item.next();
119-
if ($next.length) {
120-
var nextLeftEdgeOffset = $next.offset().left;
121-
var nextRightEdgeOffset = nextLeftEdgeOffset + $next.width();
122-
if (nextRightEdgeOffset < windowWidth) {
123-
right = (currentNavbarOffset -
124-
(windowWidth + NAV_LINK_VISIBLE_WIDTH - nextRightEdgeOffset) +
125-
padding);
126-
}
66+
})
67+
.on('click', '.tab-link', function(e) {
68+
if (capabilities.widescreen()) {
69+
return;
12770
}
128-
}
129-
130-
if (right < baseOffset) {
131-
// Don't scroll past the base starting point.
132-
right = baseOffset;
133-
}
13471

135-
$item.closest('.navbar').css('right', right + 'px');
136-
return right;
72+
// Jump to the beginning when user clicks on the first link.
73+
if ($(this).closest('.tab-item').is(':first-child')) {
74+
$navContainer[0].scrollLeft = 0;
75+
} else {
76+
$navContainer[0].scrollLeft = this.getBoundingClientRect().left;
77+
}
78+
this.blur();
79+
});
13780
}
81+
z.body.one('loaded', initNavbarButtons);
13882

13983
function linefitNavbarMobile($navbar) {
14084
// Linefits the navbar on mobile such that the nav element flowing
@@ -183,20 +127,17 @@ define('navbar',
183127
}
184128

185129
function fitNavbarMobile($item) {
186-
// Does both line-fitting and offset calculations for the navbar.
187-
// Note that line-fitting must be done first since the offset affects
188-
// its calculations.
130+
// Does line-fitting for the navbar.
189131
linefitNavbarMobile($item.closest('.navbar'));
190-
calcNavbarOffset($item);
191132
}
192133

193134
function fitNavbarDesktop() {
194135
// Shrinks the font-size and padding of the nav elements until it
195136
// all fits within the window.
196-
var windowWidth = z.win.width();
197-
if (windowWidth < DESKTOP_WIDTH) {
137+
if (!capabilities.widescreen()) {
198138
return;
199139
}
140+
var windowWidth = z.win.width();
200141
var $navbar = $('.nav-mkt');
201142
var $navbarItems = $navbar.find('li');
202143
var navbarWidth = $navbar.width();

0 commit comments

Comments
 (0)