From efc1b9cfd9c04b8d7f8cf0fb35e77bcb94a25a6e Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Tue, 18 Nov 2014 03:12:51 -0800 Subject: Fixed sidebar scrolling problems and added a button to collapse/expand the sidebar --- .../src/main/scala/scrollmenu/Controller.scala | 49 ++++++++++++++++++---- .../src/main/scala/scrollmenu/ScrollMenu.scala | 16 +++++-- 2 files changed, 52 insertions(+), 13 deletions(-) (limited to 'examples') diff --git a/examples/demos/src/main/scala/scrollmenu/Controller.scala b/examples/demos/src/main/scala/scrollmenu/Controller.scala index de120c6..132a073 100644 --- a/examples/demos/src/main/scala/scrollmenu/Controller.scala +++ b/examples/demos/src/main/scala/scrollmenu/Controller.scala @@ -28,29 +28,60 @@ object Controller{ val snippets = dom.document.getElementsByClassName("highlight-me") snippets.foreach(js.Dynamic.global.hljs.highlightBlock(_)) - val scrollSpy = new ScrollSpy(structure, main) + val list = ul(cls:="menu-item-list collapsed")( + scrollSpy.domTrees.map(_.value.frag) + ).render + + def updateScroll() = scrollSpy(main.scrollTop + main.clientHeight) + val expandIcon = i(cls:="fa fa-caret-down").render + val expandLink = + a( + expandIcon, + href:="javascript:", + marginLeft:="0px", + paddingLeft:="15px", + paddingRight:="15px", + cls:="pure-menu-selected", + onclick := { (e: dom.Event) => + expandIcon.classList.toggle("fa-caret-down") + expandIcon.classList.toggle("fa-caret-up") + list.classList.toggle("collapsed") + scrollSpy.clean = !scrollSpy.clean + updateScroll() + } + ).render + menu.appendChild( - div(cls:="pure-menu pure-menu-open")( - a(cls:="pure-menu-heading", href:="#")( - "Contents" - ), + div( + zIndex:=10, + position:="absolute", + cls:="pure-menu pure-menu-open", ul(cls:="menu-item-list")( - scrollSpy.domTrees.map(_.value.frag) + li( + width:="43px", + float:="right", + expandLink + ) ) ).render ) + menu.appendChild( + div(cls:="pure-menu pure-menu-open")( + list + ).render + ) + menuLink.onclick = (e: dom.MouseEvent) => { layout.classList.toggle("active") menu.classList.toggle("active") menuLink.classList.toggle("active") } - main.onscroll = (e: dom.UIEvent) => { - scrollSpy(main.scrollTop + main.clientHeight) - } + main.onscroll = (e: dom.UIEvent) => updateScroll() + updateScroll() } } diff --git a/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala b/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala index 7b238f4..5bd5259 100644 --- a/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala +++ b/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala @@ -2,6 +2,7 @@ package scrollmenu import org.scalajs.dom +import scala.scalajs.js import scalatags.JsDom.all._ case class Tree[T](value: T, children: Vector[Tree[T]]) @@ -12,7 +13,9 @@ case class MenuNode(frag: dom.HTMLElement, start: Int, end: Int) * High performance scrollspy to work keep the left menu bar in sync. * Lots of sketchy imperative code in order to maximize performance. */ -class ScrollSpy(structure: Tree[String], main: dom.HTMLElement){ +class ScrollSpy(structure: Tree[String], + main: dom.HTMLElement, + var clean: Boolean = false){ val (headers, domTrees) = { var i = 0 def recurse(t: Tree[String], depth: Int): Tree[MenuNode] = { @@ -64,18 +67,20 @@ class ScrollSpy(structure: Tree[String], main: dom.HTMLElement){ } private[this] def start(threshold: Double) = { scrolling = false - def scroll(el: dom.HTMLElement) = { + def scroll(el: dom.Element) = { val rect = el.getBoundingClientRect() if (rect.top <= 0) el.scrollIntoView(true) - else if (rect.bottom > dom.innerHeight) + else if (rect.top > dom.innerHeight) el.scrollIntoView(false) } def walkTree(tree: Tree[MenuNode]): Boolean = { val Tree(MenuNode(menuItem, start, end), children) = tree val before = headers(start) < threshold val after = (end >= headers.length) || headers(end) > threshold + val win = before && after + if (win){ menuItem.classList.remove("hide") var winFound = false @@ -90,10 +95,13 @@ class ScrollSpy(structure: Tree[String], main: dom.HTMLElement){ // This means it's the leaf element, because it won but there // aren't any children which won, so it must be the actual leaf tree.children.foreach(_.value.frag.classList.remove("selected")) - scroll(menuItem) + + scroll(menuItem.children(0)) + } menuItem.children(0).classList.add("pure-menu-selected") }else{ + if(clean) tree.children.map(walkTree) menuItem.children(0).classList.remove("pure-menu-selected") menuItem.classList.add("hide") menuItem.classList.remove("selected") -- cgit v1.2.3