Fossil SCM

Added a guard on the use of CSS transitions so it falls back to a non-animated menu pull down if they appear not to be available on the current browser. Also added a check for the existence of the hamburger menu item in case the skin admin diked it out, and did a few other minor tweaks to the footer JS code.

wyoung 2018-09-10 13:41 js-hamburger-menu
Commit 5d9a3454816e1f57ea6df6e70a40013ad93aca7222712a0c2b8f1ce6ed6cb4c4
1 file changed +48 -24
--- skins/default/footer.txt
+++ skins/default/footer.txt
@@ -7,11 +7,14 @@
77
<th1>
88
html "<script nonce='$nonce'>"
99
html " (function() { var home='$home'; "
1010
</th1>
1111
var panel = document.getElementById("hbdrop");
12
+ if (!panel) return; // site admin might've nuked it
1213
var panelBorder = panel.style.border;
14
+ var animate = panel.style.hasOwnProperty('transition');
15
+ var animMS = 400;
1316
1417
// Calculate panel height despite its being hidden at call time.
1518
// Based on https://stackoverflow.com/a/29047447/142454
1619
var panelHeight; // computed on sitemap load
1720
function calculatePanelHeight() {
@@ -42,28 +45,47 @@
4245
// state change as the visibility change, so it doesn't see a state
4346
// *transition*, hence never kicks off the *CSS* transition:
4447
//
4548
// https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#JavaScript_examples
4649
function showPanel() {
47
- setTimeout(function() {
48
- panel.style.maxHeight = panelHeight;
49
- panel.style.border = panelBorder;
50
- }, 40); // 10ms is insufficient with Firefox 62
50
+ if (animate) {
51
+ setTimeout(function() {
52
+ panel.style.maxHeight = panelHeight;
53
+ panel.style.border = panelBorder;
54
+ }, 40); // 25ms is insufficient with Firefox 62
55
+ }
56
+ else {
57
+ panel.style.display = 'block';
58
+ }
59
+ }
60
+
61
+ // Return true if the panel is showing.
62
+ function panelShowing() {
63
+ if (animate) {
64
+ return panel.style.maxHeight == panelHeight;
65
+ }
66
+ else {
67
+ return panel.style.display == 'block';
68
+ }
5169
}
5270
5371
// Click handler for the hamburger button.
5472
var needSitemapHTML = true;
5573
document.querySelector("div.mainmenu > a").onclick = function() {
56
- if (panel.style.maxHeight == panelHeight) {
57
- // Hamburger button clicked while panel visible. Trigger the
58
- // transition back to hidden state.
59
- panel.style.maxHeight = '0';
60
- setTimeout(function() {
61
- // Browsers show a 1px high border line when maxHeight == 0,
62
- // our "hidden" state, so hide the borders in that state, too.
63
- panel.style.border = 'none';
64
- }, 500); // same as transition time below
74
+ if (panelShowing()) {
75
+ // Transition back to hidden state.
76
+ if (animate) {
77
+ panel.style.maxHeight = '0';
78
+ setTimeout(function() {
79
+ // Browsers show a 1px high border line when maxHeight == 0,
80
+ // our "hidden" state, so hide the borders in that state, too.
81
+ panel.style.border = 'none';
82
+ }, animMS);
83
+ }
84
+ else {
85
+ panel.style.display = 'none';
86
+ }
6587
}
6688
else if (needSitemapHTML) {
6789
// Only get it once per page load: it isn't likely to
6890
// change on us.
6991
var xhr = new XMLHttpRequest();
@@ -77,21 +99,23 @@
7799
panel.innerHTML = sm.outerHTML;
78100
if (window.setAllHrefs) {
79101
setAllHrefs(); // don't need anti-robot defense here
80102
}
81103
82
- // Set up the CSS transition to animate the panel open and
83
- // closed. Only needs to be done once per page load.
84
- // Based on https://stackoverflow.com/a/29047447/142454
85
- calculatePanelHeight();
86
- panel.style.transition = 'max-height 0.5s ease-in-out';
87
- panel.style.overflowY = 'hidden';
88
- panel.style.maxHeight = '0';
89
- panel.style.display = 'block';
90
-
91
- // Kick off the transition
92
- showPanel();
104
+ // Display the panel
105
+ if (animate) {
106
+ // Set up a CSS transition to animate the panel open and
107
+ // closed. Only needs to be done once per page load.
108
+ // Based on https://stackoverflow.com/a/29047447/142454
109
+ calculatePanelHeight();
110
+ panel.style.transition = 'max-height ' +
111
+ (animMS / 1000) + 's ease-in-out';
112
+ panel.style.overflowY = 'hidden';
113
+ panel.style.maxHeight = '0';
114
+ showPanel();
115
+ }
116
+ panel.style.display = 'block';
93117
}
94118
}
95119
// else, can't parse response as HTML or XML
96120
}
97121
xhr.open("GET", home + "/sitemap");
98122
--- skins/default/footer.txt
+++ skins/default/footer.txt
@@ -7,11 +7,14 @@
7 <th1>
8 html "<script nonce='$nonce'>"
9 html " (function() { var home='$home'; "
10 </th1>
11 var panel = document.getElementById("hbdrop");
 
12 var panelBorder = panel.style.border;
 
 
13
14 // Calculate panel height despite its being hidden at call time.
15 // Based on https://stackoverflow.com/a/29047447/142454
16 var panelHeight; // computed on sitemap load
17 function calculatePanelHeight() {
@@ -42,28 +45,47 @@
42 // state change as the visibility change, so it doesn't see a state
43 // *transition*, hence never kicks off the *CSS* transition:
44 //
45 // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#JavaScript_examples
46 function showPanel() {
47 setTimeout(function() {
48 panel.style.maxHeight = panelHeight;
49 panel.style.border = panelBorder;
50 }, 40); // 10ms is insufficient with Firefox 62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51 }
52
53 // Click handler for the hamburger button.
54 var needSitemapHTML = true;
55 document.querySelector("div.mainmenu > a").onclick = function() {
56 if (panel.style.maxHeight == panelHeight) {
57 // Hamburger button clicked while panel visible. Trigger the
58 // transition back to hidden state.
59 panel.style.maxHeight = '0';
60 setTimeout(function() {
61 // Browsers show a 1px high border line when maxHeight == 0,
62 // our "hidden" state, so hide the borders in that state, too.
63 panel.style.border = 'none';
64 }, 500); // same as transition time below
 
 
 
 
65 }
66 else if (needSitemapHTML) {
67 // Only get it once per page load: it isn't likely to
68 // change on us.
69 var xhr = new XMLHttpRequest();
@@ -77,21 +99,23 @@
77 panel.innerHTML = sm.outerHTML;
78 if (window.setAllHrefs) {
79 setAllHrefs(); // don't need anti-robot defense here
80 }
81
82 // Set up the CSS transition to animate the panel open and
83 // closed. Only needs to be done once per page load.
84 // Based on https://stackoverflow.com/a/29047447/142454
85 calculatePanelHeight();
86 panel.style.transition = 'max-height 0.5s ease-in-out';
87 panel.style.overflowY = 'hidden';
88 panel.style.maxHeight = '0';
89 panel.style.display = 'block';
90
91 // Kick off the transition
92 showPanel();
 
 
93 }
94 }
95 // else, can't parse response as HTML or XML
96 }
97 xhr.open("GET", home + "/sitemap");
98
--- skins/default/footer.txt
+++ skins/default/footer.txt
@@ -7,11 +7,14 @@
7 <th1>
8 html "<script nonce='$nonce'>"
9 html " (function() { var home='$home'; "
10 </th1>
11 var panel = document.getElementById("hbdrop");
12 if (!panel) return; // site admin might've nuked it
13 var panelBorder = panel.style.border;
14 var animate = panel.style.hasOwnProperty('transition');
15 var animMS = 400;
16
17 // Calculate panel height despite its being hidden at call time.
18 // Based on https://stackoverflow.com/a/29047447/142454
19 var panelHeight; // computed on sitemap load
20 function calculatePanelHeight() {
@@ -42,28 +45,47 @@
45 // state change as the visibility change, so it doesn't see a state
46 // *transition*, hence never kicks off the *CSS* transition:
47 //
48 // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#JavaScript_examples
49 function showPanel() {
50 if (animate) {
51 setTimeout(function() {
52 panel.style.maxHeight = panelHeight;
53 panel.style.border = panelBorder;
54 }, 40); // 25ms is insufficient with Firefox 62
55 }
56 else {
57 panel.style.display = 'block';
58 }
59 }
60
61 // Return true if the panel is showing.
62 function panelShowing() {
63 if (animate) {
64 return panel.style.maxHeight == panelHeight;
65 }
66 else {
67 return panel.style.display == 'block';
68 }
69 }
70
71 // Click handler for the hamburger button.
72 var needSitemapHTML = true;
73 document.querySelector("div.mainmenu > a").onclick = function() {
74 if (panelShowing()) {
75 // Transition back to hidden state.
76 if (animate) {
77 panel.style.maxHeight = '0';
78 setTimeout(function() {
79 // Browsers show a 1px high border line when maxHeight == 0,
80 // our "hidden" state, so hide the borders in that state, too.
81 panel.style.border = 'none';
82 }, animMS);
83 }
84 else {
85 panel.style.display = 'none';
86 }
87 }
88 else if (needSitemapHTML) {
89 // Only get it once per page load: it isn't likely to
90 // change on us.
91 var xhr = new XMLHttpRequest();
@@ -77,21 +99,23 @@
99 panel.innerHTML = sm.outerHTML;
100 if (window.setAllHrefs) {
101 setAllHrefs(); // don't need anti-robot defense here
102 }
103
104 // Display the panel
105 if (animate) {
106 // Set up a CSS transition to animate the panel open and
107 // closed. Only needs to be done once per page load.
108 // Based on https://stackoverflow.com/a/29047447/142454
109 calculatePanelHeight();
110 panel.style.transition = 'max-height ' +
111 (animMS / 1000) + 's ease-in-out';
112 panel.style.overflowY = 'hidden';
113 panel.style.maxHeight = '0';
114 showPanel();
115 }
116 panel.style.display = 'block';
117 }
118 }
119 // else, can't parse response as HTML or XML
120 }
121 xhr.open("GET", home + "/sitemap");
122

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button