2017-06-15 5 views
0

Das Problem ist, alle untergeordneten div-Tags von einem Wurzelknoten zu sortieren nach ihrer top CSS-Eigenschaft.Wie kann ich Kindknoten nach Eigenschaftswert in Scala.js sortieren?

Hier ist mein Code:

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) 
} 

Ich bin neu in Scala.js und es dauerte ziemlich Mühe mit dieser Lösung zu kommen. Es kompiliert und scheint zu funktionieren, aber ich bin mir nicht sicher, wie legitim es ist.

Zum Beispiel kann ich nur bekommen die top Eigenschaft des Knotens in einer sehr komplizierten Art und Weise. Auch vermute ich, dass zum Löschen aller Kindknoten global.document.getElementById("root").innerHTML = "" eine Hintertür ist. Ich bin nicht sicher, ob diese Sortierung an Ort und Stelle erfolgen kann, ohne Klone zu erzeugen. Ich freue mich über Verbesserungsvorschläge und hoffe, dass einige Anfänger diesen Code auch nützlich finden.

Antwort

1

verschiedene Vorschläge, einige im Zusammenhang mit Scala und einige der zugrunde liegenden Browser-Umgebung:

Zuerst jQuery (actual JavaScript library) (Scala.js facade) ist dein Freund. Der Versuch, irgendetwas mit dem rohen DOM zu tun, ist ein Schmerz in den Arsch, und ich empfehle es für nichts als die einfachsten Spielzeuganwendungen. (Das hat nichts mit Scala.js zu tun, Geist - das ist nur die Realität im Browser zu arbeiten, und ist alles wahr von JavaScript als auch.)

Mit jQuery, ist es, die Elemente immer nur:

val elements = $("root").children 

Zweitens Schleifen im wesentlichen niemand Indizes in Scala wie das mit - es ist legal, aber extrem selten. Stattdessen erhalten Sie jedes Element direkt in der for. Und Sie können die Wertzuweisungen in das für sich selbst halten, die Klausel yield sauber halten.

jQuery können Sie direkt bei CSS-Eigenschaften erhalten. (Obwohl ich glaube, Sie noch haben, um die „px“ parsen.) Auch hier ist alles viel schwieriger, wenn Sie versuchen, die Roh-DOM-Funktionen zu verwenden.

Und es ist sehr selten Tuple2 zu buchstabieren - man muss nur Pars für ein Tupel verwenden. Dass sie alle zusammen, es etwas würde wie folgt aussehen:

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

Geist, haben versucht, ich nicht wirklich den obigen Code aus - es gibt wahrscheinlich einige Fehler - aber das ist eher wie was idiomatische Scala. js + jQuery Code würde aussehen, und ist als Ausgangspunkt zu betrachten.

+0

Danke für diese Vorschläge. Ich bin mir eigentlich bewusst, dass Scala.js.hat eine jQuery-Erweiterung, aber ich kann einfach nicht importieren diese Erweiterung: https://github.com/scala-js/scala-js-jquery, ich bekomme alle Arten von kryptischen Fehlermeldungen über Bündelung. D3.js Erweiterung ist einfach zu importieren und funktioniert als Charme und ich verwende dies für die Auswahl derzeit. Ich würde jede mögliche Hilfe, wie man jQuery (ein voll funktionierendes Beispiel kann sein), schätzen. Noch komplizierter macht es, dass ich ein integriertes Projekt verwende, in dem Client und Server (+ gemeinsamer Code) zusammen kompiliert werden: https://github.com/vmunier/play-with-scalajs-example. – sbtpr

+0

Nun, die Verwendung der Vmunier-Bibliothek ist ein ziemlich übler Standard - ich benutze es selbst. Ich empfehle, die neuere jquery-Fassade (oben verlinkt) anstelle der älteren scala-js-jquery zu verwenden. Aber ich weiß nicht, woher die Bündelfehler kommen - das ist irgendwie komisch. Ich werde mich in Kürze auf den Weg machen, aber ich würde empfehlen, dies auf dem scala-js/scala-js-Gitter-Kanal (der das Herz der Scala.js-Community ist) einzubringen und die Fehler, die du siehst, zu posten - Leute dort können vielleicht helfen. –

+0

Auch wenn es nicht offensichtlich ist: Denken Sie daran, dass es keine Art von jQuery * Extension * ist, es ist nur eine Fassade. Sie müssen jQuery selbst vor Ihrem Scala.js-Code einfügen. Die Scala.js-Fassade (ob Sie scala-js-jquery oder jquery-facade verwenden) teilt dem Scala-Code nur mit, wie * jQuery * verwendet werden soll. –

Verwandte Themen