2013-06-24 3 views
6

enthält Ich habe eine Reihe von Listenelementen mit einem Attribut. Ich möchte nur zwei oder drei davon gleichzeitig auswählen. Derzeit bin ich split eine durch Kommata getrennte Liste von Ids ing dann einen Array von Selektoren zu schaffen für jQuery zurückzukehren:jQuery-Attributselektor, wobei Wert im Array

var ids = $(this).text().split(','); //e.g. text = 1,13,27 
var selectors = []; 
for (var index in ids) 
{ 
    selectors.push('.container ul.class li[data-id="'+ids[index]+'"]'); 
} 
$(selectors.join(',')).addClass('active'); 

Diese recht teuer Ansatz für Firefox zu sein scheint. Gibt es eine Möglichkeit, dies zu optimieren, so dass ich eine li mit dem Daten-ID-Attribut auswählen kann, das eine der IDs enthält?

Etwas ähnlich wie unten, aber die Auswahl eines der Werte?

var ids = $(this).text().split(','); //e.g. text = 1,13,27 
$('.container ul.class li[data-id~="' + ids + '"]').addClass('active'); 

[Bearbeiten]

Dank @Alnitak ‚s Kommentar Ich habe meine Schleifen geändert:

var ids= $(this).text().split(','); 
var length = ids.length; 
for (var i=0; i<length;i++) 
{ 
    selectors.push('.container ul.class li[data-id="'+ids[i]+'"]'); 
} 

dies eine große Verbesserung geliefert hat, aber gibt es nicht mehr was ich tun kann?

+3

nicht 'für ... in' auf Arrays verwenden Sie - es ist für _object keys_ aufzählt, nicht _array indices_. – Alnitak

+0

Danke. Ich habe das 'for ... in' für' for (var i = 0; i

Antwort

9

Wie wäre:

var ids = "21,5,6,7,10".split(","); 

// selector produced: [data-id='21'],[data-id='5'],[data-id='6'],[data-id='7'],[data-id='10'] 
$("[data-id='" + ids.join("'],[data-id='") + "']").addClass("active"); 

http://jsfiddle.net/3MNDy/

+0

Dies hat mir die beste Leistungsverbesserung gegeben. Ich habe den Selektor geändert, um die Klassen div und ul einzuschließen: 'var selector = '.container ul.class li [daten-id ="'; $ (selektor + ids.join (''] '+ selector) + ''] '). addClass (' active '); ' –

+1

@ RichardParnaby-King _Dies hat mir die beste Leistungsverbesserung gegeben._ Ich glaube nicht, basierend auf welchem ​​Kriterium? – undefined

4
var ids = $(this).text().split(','); 

$.each(ids, function(k, v){ 
    $('.container ul.class li[data-id="' + v + '"]').addClass('active'); 
}); 
+0

Ich habe das versucht. Es funktioniert, aber ich versuche, dieses Skript zu optimieren, um so wenige Dom-Aufrufe/Updates wie möglich zu machen (nicht in der Frage erklärt, aber sollte). Aus diesem Grund erstelle ich ein Array von Selektoren und führe das eine dom-Update am Ende der Schleife durch. –

8

können Sie filter Methode verwenden:

$('.container ul.class li').filter(function() { 
    return ids.indexOf($(this).data('id')) > -1; 
}).addClass('active'); 
+0

+1 sogar ich weiß seine redundante aber ältere Version von IE unterstützt nicht indexOf-Methode für Arrays –

+0

@roasted Ja, das stimmt, für _IE_ jQuery '' .inArray' kann stattdessen verwendet werden. – undefined

1

Es sollte mehr performant sein, alle mit einem data-id Attribut um die Elemente auszuwählen einmal, dann filtern die Liste basierend auf dem Wert des Attributs:

var $matches = $('.container ul.class li[data-id]').filter(function() { 
    return $.inArray(this.getAttribute("data-id"), ids); 
}); 

$matches.addClass('active'); // or whatever else you want to do 
+0

Das Array von IDs wird in Strings umgewandelt "[" 1 "," 13 "," 27 "]' und ich denke, '$ .inArray' wird ebenfalls überprüft und gibt immer -1 zurück. –

+0

@ RichardParnaby-King: Der Rückgabewert von 'getAttribute' ist eine Zeichenkette und so sind die Werte in' ids'. Ich sehe nicht, warum das -1 zurückgeben würde. – Jon

0

Ich denke, das optimierteren Ansatz sein:

var ids = $(this).text().split(','); //e.g. text = 1,13,27 
var lis = $('.container ul.class li'); 
lis.filter(function() { 
    return $.inArray($(this).data('id'), ids); 
}).addClass('active');