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

How can I sort child nodes by property value in 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 = "" 是一种后门方式。我不确定是否可以在不创建克隆的情况下就地完成这种排序。我欢迎任何改进建议,我希望一些初学者甚至可以发现这段代码有用。

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

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

使用jQuery,获取元素只是:

val elements = $("root").children

其次,基本上没有人像那样在 Scala 中使用索引进行循环——这是合法的,但极为罕见。相反,您直接在 for 中获取每个元素。您可以将值赋值直接插入 for 本身,保持 yield 子句干净。

jQuery 可让您直接获取 CSS 属性。 (尽管我 认为 你仍然需要解析 "px"。)同样,如果你尝试使用原始 DOM 函数,一切都会变得更加困难。

而且拼写 Tuple2 非常罕见——您只需使用括号作为元组。将它们放在一起,它看起来 像这样:

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 代码的样子,并且是值得考虑作为起点。