2013-07-24 7 views
7

Ich versuche CasperJS zu testen, und eine Website sind Schaben, die ein Raster-Layout wie hat:Iterieren über ein Gitter mit CasperJS

|Name  |Name  | 
|Title  |Title  | 
|Image  |Image  | 
|Something |Something | 
|---------------------- 
|Name  |Name  | 
|Title  |Title  | 
|Image  |Image  | 
|Something |Something | 
|---------------------- 

Wenn ich nicht CasperJS verwenden würde ich eine Liste aller abrufen Das enthält (in diesem Fall 4) und führt dann für jeden Container eine Methode aus, mit der ein Objekt mit den gewünschten Eigenschaften abgerufen werden kann.

Ich habe nur eine harte Zeit, dies in CasperJS zu tun. Zuerst habe ich versucht, die Liste der DOM-Elemente in casper.evaluate (function() {....} zurückzugeben, aber es kann keine DOM-Elemente zurückgeben.

Dann habe ich versucht, eine jede Schleife zu machen, die die gewünschten Objekte (4) zu einem Array schieben und es in einem Evalue zurückgeben würde, aber es immer Null zurückgibt.

Wie würde man in CasperJS so etwas machen? Kann ich irgendwie einen Kontext eines Containers an eine Methode zurückgeben, die das Objekt an die Hauptauswertung zurückgeben kann, die die Sammlung der Objekte zurückgeben kann?

+1

Sie schlagen Ihren Kopf gegen das Hauptkonzept von Casper. Die Trennung zwischen Server und Client JS. Außerhalb von evaluate ist es nur Server, kein DOM. Die Brücke sind die serialisierbaren Objekte. Die zwei Antworten erklären es gut. Beachten Sie, wie die Funktion getLinks im Beispiel ein Array von Strings zurückgibt, nicht DOM nodes.http: //docs.casperjs.org/en/latest/quickstart.html –

Antwort

9

Leider kann man nicht eine komplexe Struktur aus evaluate() Funktion bekommen, denn was auch immer arg von evaluate() weitergegeben Art JSON.parse(JSON.stringify(arg)) ist.

Aber es bedeutet nicht, dass Sie nicht in der Lage sind, eine andere Art von Objekten zu übergeben.

Hier ist ein Beispiel, wie man mit Objekten ein Array erhalten von casper.evaluate():

var arrayResult = this.evaluate(function getGridResuls(){ 

    //create array 
    var arrayObjects = new Array(); 

    //Iterates over table (grid) elements 
    jQuery("table.results").each(function(index) { 

     //get table (grid) 
     var tableResult = jQuery(this); 

     //create basic object  
     objResult = new Object(); 

     //fill object properties 
     objResult.name  = tableResult.find('selector to get name').text(); 
     objResult.title  = tableResult.find('selector to get title').text(); 
     objResult.image  = tableResult.find('selector to get image info').text(); 
     objResult.something = tableResult.find('selectot to get something').text().trim(); 

     //assign object to array 
     arrayObjects[index] = objResult; 

    }); 

    //return array with objects 
    return arrayObjects; 

}); 

... 
//do something with arrayResult 

Ich gehe davon aus, dass der Web-Kontext die JQuery-Bibliothek enthält.

Tipp: versuchen Sie, den Js-Code der evaluate()-Funktion mithilfe der Browserkonsole auszuführen, um sicherzustellen, dass Ihr Js-Code wie erwartet funktioniert.

2

Der Ansatz ist korrekt, aber evaluieren ist Sandkasten. Außerdem müssen die Argumente und der Rückgabewert der Funktion evaluate ein einfaches primitives Objekt sein, aber wenn es über JSON serialisiert werden kann, ist es in Ordnung. Verschlüsse, Funktionen, DOM-Knoten usw. funktionieren nicht!

Stattdessen gewünschtes Objekt zurückzugeben, gibt eine serialisierte Version des gewünschten Objekts mit JSON.stringify()

+0

Vielen Dank für Ihre Antwort, aber wie würden Sie es dann DRY. Ich würde eine Methode haben, die einen DOM-Kontext nehmen und ein JSON-Objekt (stringified) zurückgeben kann. Kann ich Funktionen in der Sandbox nicht aufrufen und das DOM-Element zurückgeben? Im Grunde möchte ich nur herausfinden, was die beste Lösung ist, über einen Container zu iterieren und die Elemente aus diesem Container in CasperJS zu holen. – Dofs

+0

@dofs gibt es kein DOM außerhalb von evaluieren, Sie können es einfach nicht tun. Sie müssen Ihre Elemente in einfache serialisierbare Objekte abstrahieren –