Add -webkit-overflow-scrolling via JavaScript on navigation

This commit is contained in:
squidfunk
2016-12-28 11:49:57 +01:00
parent be5c94128d
commit e1310aa9ee
15 changed files with 174 additions and 32 deletions

View File

@@ -119,12 +119,19 @@ export default class Application {
new Material.Nav.Blur("[data-md-component=toc] .md-nav__link")))
/* Component: collapsible elements for navigation */
const collapsibles = document.querySelectorAll("[data-md-collapse]")
const collapsibles =
document.querySelectorAll("[data-md-component=collapsible]")
for (const collapse of collapsibles)
new Material.Event.MatchMedia("(min-width: 1200px)",
new Material.Event.Listener(collapse.previousElementSibling, "click",
new Material.Nav.Collapse(collapse)))
/* Component: pane monitor for iOS scrolling fixes */
new Material.Event.MatchMedia("(max-width: 1199px)",
new Material.Event.Listener(
"[data-md-component=navigation] [data-md-toggle]", "change",
new Material.Nav.Scrolling("[data-md-component=navigation] nav")))
/* Component: search body lock for mobile */
new Material.Event.MatchMedia("(max-width: 959px)",
new Material.Event.Listener("[data-md-toggle=search]", "change",

View File

@@ -22,6 +22,7 @@
import Blur from "./Nav/Blur"
import Collapse from "./Nav/Collapse"
import Scrolling from "./Nav/Scrolling"
/* ----------------------------------------------------------------------------
* Module
@@ -29,5 +30,6 @@ import Collapse from "./Nav/Collapse"
export default {
Blur,
Collapse
Collapse,
Scrolling
}

View File

@@ -82,7 +82,7 @@ export default class Blur {
for (let i = this.index_; i >= 0; i--) {
if (this.anchors_[i] > offset) {
if (i > 0)
delete this.els_[i - 1].dataset.mdState
this.els_[i - 1].dataset.mdState = ""
} else {
this.index_ = i
break
@@ -99,7 +99,7 @@ export default class Blur {
*/
reset() {
for (const el of this.els_)
delete el.dataset.mdState
el.dataset.mdState = ""
/* Reset index and page y-offset */
this.index_ = 0

View File

@@ -59,7 +59,7 @@ export default class Collapse {
/* Read height and unset pseudo-toggled state */
const height = this.el_.getBoundingClientRect().height
delete this.el_.dataset.mdState
this.el_.dataset.mdState = ""
/* Set initial state and animate */
this.el_.style.maxHeight = "0px"
@@ -70,8 +70,8 @@ export default class Collapse {
}
/* Remove state on end of transition */
const end = function(ev) {
delete ev.target.dataset.mdState
const end = ev => {
ev.target.dataset.mdState = ""
ev.target.style.maxHeight = ""
/* Only fire once, so directly remove event listener */
@@ -84,7 +84,7 @@ export default class Collapse {
* Reset height and pseudo-toggled state
*/
reset() {
delete this.el_.dataset.mdState
this.el_.dataset.mdState = ""
this.el_.style.maxHeight = ""
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/* ----------------------------------------------------------------------------
* Class
* ------------------------------------------------------------------------- */
export default class Scrolling {
/**
* Set overflow scrolling on the current active pane (for iOS)
*
* @constructor
* @param {(string|HTMLElement)} el - Selector or HTML element
*/
constructor(el) {
this.el_ = (typeof el === "string")
? document.querySelector(el)
: el
}
/**
* Setup panes
*/
setup() {
/* Initially set overflow scrolling on main pane */
this.el_.children[1].style.webkitOverflowScrolling = "touch"
/* Find all toggles and check which one is active */
const toggles = this.el_.querySelectorAll("[data-md-toggle]")
for (const toggle of toggles) {
if (!toggle.checked)
return
/* Find corresponding navigational pane */
let pane = toggle.nextElementSibling
while (pane.tagName !== "NAV")
pane = pane.nextElementSibling
/* Find current and parent list elements */
const parent = toggle.parentNode.parentNode
const target = pane.children[pane.children.length - 1]
/* Always reset all lists when transitioning */
parent.style.webkitOverflowScrolling = ""
target.style.webkitOverflowScrolling = "touch"
}
}
/**
* Update active panes
*
* @param {Event} ev - Change event
*/
update(ev) {
/* Find corresponding navigational pane */
let pane = ev.target.nextElementSibling
while (pane.tagName !== "NAV")
pane = pane.nextElementSibling
/* Find current and parent list elements */
const parent = ev.target.parentNode.parentNode
const target = pane.children[pane.children.length - 1]
/* Always reset all lists when transitioning */
parent.style.webkitOverflowScrolling = ""
target.style.webkitOverflowScrolling = ""
/* Set overflow scrolling on parent */
if (!ev.target.checked) {
const end = () => {
parent.style.webkitOverflowScrolling = "touch"
pane.removeEventListener("transitionend", end)
}
pane.addEventListener("transitionend", end, false)
}
/* Set overflow scrolling on target */
if (ev.target.checked) {
const end = () => {
target.style.webkitOverflowScrolling = "touch"
pane.removeEventListener("transitionend", end, false)
}
pane.addEventListener("transitionend", end, false)
}
}
/**
* Reset panes
*/
reset() {
/* Reset overflow scrolling on main pane */
this.el_.children[1].style.webkitOverflowScrolling = ""
/* Find all toggles and check which one is active */
const toggles = this.el_.querySelectorAll("[data-md-toggle]")
for (const toggle of toggles) {
if (!toggle.checked)
return
/* Find corresponding navigational pane */
let pane = toggle.nextElementSibling
while (pane.tagName !== "NAV")
pane = pane.nextElementSibling
/* Find current and parent list elements */
const parent = toggle.parentNode.parentNode
const target = pane.children[pane.children.length - 1]
/* Always reset all lists when transitioning */
parent.style.webkitOverflowScrolling = ""
target.style.webkitOverflowScrolling = ""
}
}
}

View File

@@ -66,7 +66,7 @@ export default class Lock {
/* Exiting search mode */
} else {
delete document.body.dataset.mdState
document.body.dataset.mdState = ""
/* Scroll to former position, but wait for 100ms to prevent flashes on
iOS. A short timeout seems to do the trick */
@@ -81,8 +81,8 @@ export default class Lock {
* Reset locked state and page y-offset
*/
reset() {
if (document.body.dataset.mdState)
if (document.body.dataset.mdState === "lock")
window.scrollTo(0, this.offset_)
delete document.body.dataset.mdState
document.body.dataset.mdState = ""
}
}

View File

@@ -86,7 +86,7 @@ export default class Position {
/* Sidebar should be unlocked, if locked */
} else if (this.el_.dataset.mdState === "lock") {
delete this.el_.dataset.mdState
this.el_.dataset.mdState = ""
}
}
@@ -94,7 +94,7 @@ export default class Position {
* Reset locked state and height
*/
reset() {
delete this.el_.dataset.mdState
this.el_.dataset.mdState = ""
this.el_.style.height = ""
this.height_ = 0
}