summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-13 01:39:45 -0800
committerLi Haoyi <haoyi@dropbox.com>2014-11-13 01:39:45 -0800
commit64f9b0b4625298d1b78d1991636c2d32fe1f422f (patch)
treece372b1d613e0412fb4083c22ed0439f87169e2e /examples
parent3beb1dd285d89dd4b746b1c4cd287a8748376556 (diff)
downloadhands-on-scala-js-64f9b0b4625298d1b78d1991636c2d32fe1f422f.tar.gz
hands-on-scala-js-64f9b0b4625298d1b78d1991636c2d32fe1f422f.tar.bz2
hands-on-scala-js-64f9b0b4625298d1b78d1991636c2d32fe1f422f.zip
fixed the perf problems by deferring the sidebar-update while a scroll is happening
Diffstat (limited to 'examples')
-rw-r--r--examples/demos/Controller.scala127
1 files changed, 66 insertions, 61 deletions
diff --git a/examples/demos/Controller.scala b/examples/demos/Controller.scala
index e17cde9..6e7df42 100644
--- a/examples/demos/Controller.scala
+++ b/examples/demos/Controller.scala
@@ -1,13 +1,12 @@
-import japgolly.scalajs.react.React
-import japgolly.scalajs.react.vdom.VDomBuilder
-
import scala.scalajs.js
import scala.scalajs.js.annotation.JSExport
import org.scalajs.dom
import org.scalajs.dom.extensions._
import scala.collection.mutable
-import scalatags.JsDom.all._
+import japgolly.scalajs.react._ // React
+
+import vdom.ReactVDom.all._ // Scalatags html & css (div, h1, textarea, etc.)
case class Tree[T](name: T, children: Vector[Tree[T]])
@@ -34,14 +33,21 @@ object Controller{
val structure = upickle.readJs[Tree[String]](upickle.json.readJs(data))
var i = 0
- def recurse(t: Tree[String]): Tree[(String, String, Int)] = {
- val curr = (t.name, munge(t.name), i)
+ def recurse(t: Tree[String], depth: Int): Tree[(Tag, Int)] = {
+ val curr =
+ li(paddingLeft := s"${depth * 15}px")(
+ a(
+ t.name,
+ href:=munge("#"+t.name),
+ cls:="menu-item"
+ )
+ )
+ val originalI = i
i += 1
- val children = t.children.map(recurse)
- Tree(curr, children)
+ val children = t.children.map(recurse(_, depth + 1))
+ Tree(curr -> originalI, children)
}
-
val Seq(main, menu, layout, menuLink) = Seq(
"main", "menu", "layout", "menuLink"
).map(dom.document.getElementById)
@@ -69,7 +75,7 @@ object Controller{
val menuBar = React.renderComponent(
- Menu(recurse(structure)),
+ Menu(recurse(structure, 0)),
menu
)
menuLink.onclick = (e: dom.MouseEvent) => {
@@ -78,23 +84,28 @@ object Controller{
toggleClass(menuLink, "active")
}
- var scrolling = false
- main.onscroll = (e: dom.UIEvent) => {
- if (!scrolling){
- scrolling = true
- dom.requestAnimationFrame{(d: Double) =>
- scrolling = false
- val threshold = main.scrollTop + main.clientHeight
-
- var index = 0
- while(index < headers.length && index >= 0){
- index += 1
- if (headers(index) > threshold) index *= -1
- }
- index = -index
- menuBar.setState(index)
+ var x = -1
+ def start() =
+ x = dom.setTimeout(() => {
+ x = -1
+ val threshold = main.scrollTop + main.clientHeight
+
+ var index = 0
+ while(index < headers.length && index >= 0){
+ index += 1
+ if (headers(index) > threshold) index *= -1
}
+ index = -index
+ menuBar.setState(index)
+
+ }, 100)
+
+ main.onscroll = (e: dom.UIEvent) => {
+ if (x != -1){
+ dom.clearTimeout(x)
+ s
}
+ start()
}
}
def isElementInViewport(el: dom.HTMLElement) = {
@@ -102,54 +113,48 @@ object Controller{
rect.top >= 0 && rect.bottom <= dom.innerHeight
}
- import japgolly.scalajs.react._ // React
- import vdom.ReactVDom._ // Scalatags → React virtual DOM
- import vdom.ReactVDom.all._ // Scalatags html & css (div, h1, textarea, etc.)
- val Menu = ReactComponentB[Tree[(String, String, Int)]]("Menu")
+
+ val Menu = ReactComponentB[Tree[(Tag, Int)]]("Menu")
.getInitialState(_ => 0)
.render{ (structure, _, index) =>
val contentList = {
var i = 0
- def rec1(current: Tree[(String, String, Int)]): Tree[(String, String, Int, Boolean)] = {
+ val winArray = new js.Array[Boolean](0)
+ def rec1(current: Tree[(Tag, Int)]): Unit = {
val initialI = i
i += 1
- val children = current.children.map(rec1)
-
- val win = i >= index && initialI < index
- Tree(
- (current.name._1, current.name._2, current.name._3, win),
- children
- )
+ current.children.foreach(rec1)
+ winArray(current.name._2) = i >= index && initialI < index
}
- def rec(current: Tree[(String, String, Int, Boolean)],
- depth: Int,
- classes: String): Iterator[Tag] = {
- val winIndex = current.children.indexWhere(_.name._4)
+ val output = new js.Array[Tag](0)
+ def rec(current: Tree[(Tag, Int)],
+ classes: String): Unit = {
+
+
+ val winIndex = current.children.indexWhere { x =>
+ winArray(x.name._2)
+ }
val (before, after) = current.children.splitAt(winIndex)
- val myCls =
- "menu-item" +
- (if (depth <= 1) " menu-item-divided" else "")
-
- val (name, munged, currIndex, win) = current.name
- val frag =
- li(paddingLeft := s"${depth * 15}px")(
- a(
- name,
- href:="#"+munged,
- cls:=myCls
- ),
- cls:=classes + (if (win) " pure-menu-selected" else "")
- )
- val afterCls = if (!win) "hide" else ""
- Iterator(frag) ++
- before.flatMap(rec(_, depth+1, "lined")) ++
- after.flatMap(rec(_, depth+1, afterCls))
+ val (tag, currIndex) = current.name
+
+ val win = winArray(currIndex)
+
+ val frag = tag(
+ cls:=classes + (if (win) " pure-menu-selected" else "")
+ )
+
+ output.push(frag)
+
+ before.foreach(rec(_, "lined"))
+ after.foreach(rec(_, if (!win) "hide" else ""))
}
- rec(rec1(structure), 0, "")
+ rec1(structure)
+ rec(structure, "")
+ output
}
val frag = div(cls:="pure-menu pure-menu-open")(
@@ -157,7 +162,7 @@ object Controller{
"Contents"
),
ul(cls:="menu-item-list")(
- contentList.drop(1).toVector
+ contentList.drop(1):_*
)
)
frag