2011-12-20 24 views
12

Quale sarebbe il modo migliore per ottenere tutte le div che hanno una classe che inizia con input? In altre parole, a e devono essere restituiti da ciò che è di seguito, ma non c.jQuery - ha classe che inizia con

<div id="a" class="input1 foo"></div> 
<div id="b" class="foo input2"></div> 
<div id="c" class="xinput3 foo"></div> 

Il modo apparente, che sorprendentemente è stata accettata here, è quello di fare $("div[class^='input']"); ma, naturalmente, che manca b. E ovviamente $("div[class*='input']"); darà un falso positivo su c.

il meglio che potevo venire con era questa mostruosità

function getAllInputDivs() { 
    return $("div").filter(function (i, currentDiv) { 
     return $.grep($(currentDiv).attr("class").split(" "), function (val) { 
      return val.substr(0, "input".length) === "input"; 
     }).length > 0; 
    }); 
} 

C'è un modo più pulito? Ecco un working fiddle di quanto sopra

+0

Non penso che i nomi di classe siano l'opzione migliore quando si hanno cose come input1 e input2. Se l'input è abbastanza unico da essere enumerato in questo modo, puoi usare ID o nomi che possono essere selezionati con '$ (" [id^= input] ")' –

+0

@KevinB - probabilmente hai ragione. Non sono sicuro se ci sia un buon uso di questo o no. In questo momento è solo una domanda teorica per vedere se può essere fatto. –

+0

Domanda simile: [selettore jQuery per indirizzare qualsiasi nome di classe (di più presenti) che inizia con un prefisso?] (Http://stackoverflow.com/questions/4524412/jquery-selector-to-target-any-css-name- di-multiple-present-starting-with-a-pre) ma non ho ancora creato le espressioni di selettore personalizzate, quindi mi piacciono molto le risposte a questa domanda :) – BoltClock

risposta

22

È possibile creare la propria espressione in jQuery

$.expr[':'].hasClassStartingWithInput = function(obj){ 
    return (/\binput/).test(obj.className); 
}; 

ed è possibile recuperare quei div con

$('div:hasClassStartingWithInput'); 

un Esempio JsFiddle: http://jsfiddle.net/7zFD6/


Modifica: potresti anche usare un parametro (senza hard codifica il nome della classe all'interno della funzione di identificativo) in questo modo

$.expr[':'].hasClassStartingWith = function(el, i, selector) { 
    var re = new RegExp("\\b" + selector[3]); 
    return re.test(el.className); 
} 

nuovo esempio su http://jsfiddle.net/pMepk/1/

+1

Non dovrebbe che '\ b' sia un'^'invece? – Blazemonger

+0

no non lo fa. il '^' controllerebbe solo se una classe che inizia con input è anche la prima classe elencata nell'attributo class. Come ha specificato nella domanda, ha bisogno di avere un e b casi – fcalderan

+1

Penso che '\ b' potrebbe fallire in alcune situazioni (strette) poiché una classe può contenere caratteri che potrebbero essere interpretati come un limite di parole. Come 'my.input', che è una classe valida. –

6

Ecco un modo ...

function getAllInputDivs() { 
    return $("div").filter(function() { 
     return /(?:^|\s)input/.test(this.className); 
    }); 
} 

o renderlo più versatile ..

function classStartsWith(tag, s) { 
    var re = new RegExp('(?:^|\\s)' + s); 
    return $(tag || '*').filter(function() { 
     return re.test(this.className); 
    }); 
} 

Oppure prendere l'approccio indexOf se non vi piace regex ...

function classStartsWith(tag, s) { 
    return $(tag || '*').filter(function() { 
     return this.className.indexOf(s)===0 || this.className.indexOf(' ' + s)>-1; 
    }); 
} 

Anche se si deve essere consapevoli che does't di prova per i caratteri di tabulazione, solo caratteri di spazio, in modo che potesse fallire se è stata usata una scheda al posto di uno spazio.


Tornando alle versioni di regex, è possibile migliorare l'efficienza aggiungendo la stringa cercata al selettore.

Quindi verifica solo un sottoinsieme di div.

function getAllInputDivs() { 
    return $("div[class*='input']").filter(function() { 
     return /(?:^|\s)input/.test(this.className); 
    }); 
} 

Con il .filter() applicata ai soli div che conosco hanno input da qualche parte nella classe, le prestazioni miglioreranno.

o la versione versatile sarebbe simile a questa:

function classStartsWith(tag, s) { 
    var re = new RegExp('(?:^|\\s)' + s); 
    return $((tag || '*') + '[class*="' + s + '"]').filter(function() { 
     return re.test(this.className); 
    }); 
} 
+1

+1 - bello - sembra che tu abbia corretto la regex nella risposta di Fabrizio. –

2

Questa è la mia soluzione per il problema:

(function($) { 
    $.fn.hasClassStartsWith = function(klass) { 
    var _return = []; 
    for(var i = 0; i < this.length; i++){ 
     if((' ' + $(this[i]).attr('class')).indexOf(klass) != -1) 
      _return.push(this[i]); 
    } 
    return _return; 
    } 
})(jQuery); 

usarlo come segue:

var divs = $('div').hasClassStartsWith("my_class_prefix"); 

funziona anche per il caso qualcuno crea una classe con un punto nel mezzo.

Problemi correlati