2017-06-15 44 views
0

问题是根据它们的top CSS属性对根节点的所有子div进行排序。如何通过Scala.js中的属性值对子节点进行排序?

这里是我的代码:

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

各种建议,一些关于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) 

介意,我还没有真正尝试了上面的代码 - 也有可能是一些错误 - 但是这更像是地道的斯卡拉。 js + jQuery代码看起来很像,而且值得考虑作为一个起点。

+0

感谢您提出这些建议。我实际上知道Scala.js.有一个jQuery扩展,但是我根本无法导入这个扩展:https://github.com/scala-js/scala-js-jquery,我得到了所有关于它的神秘错误信息捆绑。 D3.js扩展程序很容易导入,并且可以作为魅力使用,目前我用它来进行选择。我将不胜感激任何关于如何导入jQuery的帮助(一个完整的工作示例可能)。使用客户端和服务器(+共享代码)编译在一起的集成项目使事情进一步复杂化:https://github.com/vmunier/play-with-scalajs-example。 – sbtpr

+0

那么,使用vmunier的库是非常符合沼泽标准的 - 我自己使用它。我建议使用较新的jquery-facade(上面链接)而不是旧的scala-js-jquery。但我不知道捆绑错误来自哪里 - 这有点奇怪。我将很快出发,但我建议将它放在scala-js/scala-js Gitter频道(这是Scala.js社区的核心),并发布您看到的错误 - 那里的人可能会有帮助。 –

+0

另外,万一它不明显:请记住,它不是任何类型的jQuery *扩展*,它只是一个门面。您仍然需要在您的Scala.js代码之前包含jQuery本身。 Scala.js外观(无论使用scala-js-jquery还是jquery-facade)只是告诉Scala代码如何*使用* jQuery。 –

相关问题