2012-04-13 8 views
4

Ich schreibe ein Skript für CasperJS. Ich muss auf den Link klicken, der einen Bereich mit "1" enthält. In jQuery kann :contains('1') verwendet werden, aber was ist die Lösung für Selektoren in reinem Javascript?jQuery ": contains()" analog für reine JS

HTML: <a class="swchItem"><span>1</span></a><a class="swchItem"><span>2</span></a>

jQuery Variante: $('a .swchItem span:contains("1")')

UPD CasperJS Code:

casper.then(function() { 
    this.click('a .swchItem *select span with 1*') 
}) 

Antwort

6

Seit 0.6.8, CasperJS XPath support bietet, so dass Sie so etwas schreiben können :

var x = require('casper').selectXPath; 

casper.then(function() { 
    this.click(x('//span[text()="1"]')) 
}) 

Hoffe, dass dies hilft.

1
var spans = document.getElementsByTagName('span'), 
    len = spans.length, 
    i = 0, 
    res = []; 

for (; i < len; i++) { 
    if (spans.innerHTML == 1) res.push(spans[i]); 
} 

Ist das, was Sie, es sei denn die Browser-Unterstützung nativer CSS-Abfragen zu tun haben.

1

Versuchen Sie Folgendes. Der Unterschied zwischen meiner und Gillescs Antwort ist, dass ich nur a Tags mit dem von Ihnen angegebenen Klassennamen bekomme. Wenn Sie also mehr a Tags auf der Seite ohne diese Klasse haben, könnten Sie unerwartete Ergebnisse mit seiner Antwort haben. Hier ist meins:

var aTags = document.getElementsByTagName("a"); 
var matchingTag; 

for (var i = 0; i < aTags.length; i++) { 

    if (aTags[i].className == "swchItem") { 
     for (var j = 0; j < aTags[i].childNodes.length; j++) { 
      if (aTags[i].childNodes[j].innerHTML == "1") { 
       matchingTag = aTags[i].childNodes[j]; 
      } 
     } 
    } 
} 
1

jQuery ist Javascript. Es gibt auch eine Anzahl von Auswahlmaschinen, die als Alternativen verfügbar sind.

Wenn Sie es von Grund auf neu erstellen möchten, können Sie querySelectorAll verwenden und dann nach dem passenden Inhalt suchen (vorausgesetzt, der Inhaltsselektor ist nicht implementiert) und wenn das nicht verfügbar ist, implementieren Sie Ihre eigenen.

Das würde bedeuten, Elemente von Tag-Namen bekommen, das Filtern von der Klasse, dann für die internen Spannweiten mit passendem Inhalt suchen, so:

// Some helper functions 
function hasClass(el, className) { 
    var re = new RegExp('(^|\\s)' + className + '(\\s|$)'); 
    return re.test(el.className); 
} 

function toArray(o) { 
    var a = []; 
    for (var i=0, iLen=o.length; i<iLen; i++) { 
    a[i] = o[i]; 
    } 
    return a; 
} 

// Main function 
function getEls() { 

    var result = [], node, nodes; 

    // Collect spans inside A elements with class swchItem 
    // Test for qsA support 
    if (document.querySelectorAll) { 
     nodes = document.querySelectorAll('a.swchItem span'); 

    // Otherwise... 
    } else { 

     var as = document.getElementsByTagName('a'); 
     nodes = []; 

     for (var i=0, iLen=as.length; i<iLen; i++) { 
     a = as[i]; 

     if (hasClass(a, 'swchItem')) { 
      nodes = nodes.concat(toArray(a.getElementsByTagName('span'))); 
     } 
     } 
    } 

    // Filter spans on content 
    for (var j=0, jLen=nodes.length; j<jLen; j++) { 
     node = nodes[j]; 

     if ((node.textContent || node.innerHTML).match('1')) { 
     result.push(node); 
     } 
    } 
    return result; 
} 
+0

Die Pseudo-Klasse ': contains()' gehört nicht mehr zum CSS-Standard und wird daher von 'querySelectorAll()' nicht erkannt. Das heißt, Sie können tatsächlich auf den Quellcode verweisen, um zu sehen, wie jQuery/Sizzle ': contains()' mit JS implementiert. – BoltClock

+0

Ich habe ein bisschen Zeit damit verbracht, durch jQuery zu waten, ich will nicht wirklich sehen, wie es '' contains' 'tut. Es sollte so gemacht werden, wie ich bin-Matching auf dem textContent oder innerText (was auch immer unterstützt wird), obwohl es seine eigene 'text' -Funktion verwenden kann (was unnötig und langsamer ist, aber ich weiß nicht, ob es das ist, was es tatsächlich tut). – RobG