如何在Scala.js中按属性值对子节点进行排序?

时间:2017-06-15 10:56:49

标签: sorting nodes scala.js

问题是根据top CSS属性对根节点的所有子div进行排序。

这是我的代码:

val elements = global.document.getElementById("root").childNodes.asInstanceOf[dom.NodeList]

val clones = (for (i <- (0 to (elements.length - 1)) if (elements(i).isInstanceOf[dom.raw.HTMLDivElement])) yield {
  val clone = elements(i).cloneNode(true)
  val style = clone.attributes.getNamedItem("style").value
  val parts = style.split("top: ")
  val parts2 = parts(1).split("px")
  val px = parts2(0).toDouble
  Tuple2[dom.Node, Double](clone, px)
}).toList

val sorted = clones.sortWith((a, b) => a._2 > b._2)

global.document.getElementById("root").innerHTML = ""

for (e <- sorted) {
  global.document.getElementById("root").appendChild(e._1)
}

我是Scala.js的新手,并且花了很大力气才想出这个解决方案。它编译并且似乎有效,但是我不确定它是多么合理。

例如,我只能以非常复杂的方式获取节点的top属性。另外我怀疑删除所有子节点global.document.getElementById("root").innerHTML = ""是一种后门方式。我不确定这种排序是否可以在不创建克隆的情况下完成。我欢迎任何改进建议,我希望有些初学者可能会发现这个代码很有用。

1 个答案:

答案 0 :(得分:1)

各种建议,一些与Scala有关,另一些与底层浏览器环境有关:

首先,jQuery(actual JavaScript library)(Scala.js facade)是你的朋友。尝试使用原始DOM做任何事都是痛苦的事情,除了最简单的玩具应用之外我不推荐它。 (这与Scala.js无关,请注意 - 这只是在浏览器中工作的现实,而且JavaScript也是如此。)

使用jQuery,获取元素只是:

val elements = $("root").children

其次,基本上没有人使用Scala中的索引循环 - 这是合法的,但非常罕见。相反,您可以直接在for中获取每个元素。您可以将值赋值直接粘贴到自身中,保持yield子句清洁。

jQuery让您直接获得CSS属性。 (虽然我你仍然需要解析“px”。)同样,如果你尝试使用原始DOM函数,一切都会更难。

拼出Tuple2是非常罕见的 - 你只是使用parens来表示元组。把它们放在一起,它会看起来像这样

for {
  element <- elements
  if (element.isInstanceOf[dom.raw.HTMLDivElement])
  clone = element.clone()
  top = clone.css("top")
  px = top.dropRight(2).toDouble
}
  yield (clone, px)

介意,我还没有尝试过上面的代码 - 可能存在一些错误 - 但这更像是惯用的Scala.js + jQuery代码,并且值得考虑作为起点。< / p>