jQuery valor de selector de escape

Tengo una lista desplegable que contiene una serie de opciones:

 ">a'b]<p> easy  

Tenga en cuenta que el valor / texto de la opción contiene algunas cosas desagradables:

  • comillas simples
  • cierre de corchete
  • escapó html

Necesito eliminar la opción a’b]

pero no tengo suerte escribiendo el selector. Ninguno:

 $("#SomeDropdown >option[value='a''b]<p>']"); 

o

 $("#SomeDropdown >option[value='a\'b]<p>']"); 

están devolviendo la opción.

¿Cuál es la forma correcta de escapar de los valores cuando se usa el selector “value =”?

No creo que puedas. Debería ser:

 #SomeDropdown >option[value='a\'b]

']

Y esto funciona como un selector de CSS (en los navegadores modernos). Expresado en un literal de cadena de JavaScript, naturalmente necesitaría otra ronda de escape:

 $("#SomeDropdown >option[value='a\\'b]

']")

Pero esto no funciona en jQuery porque su analizador de selector no es completamente compatible con los estándares. Utiliza esta expresión regular para analizar la parte del value de una condición [attr=value] :

 (['"]*)(.*?)\3|)\s*\] 

\ 3 es el grupo que contiene las comillas de apertura, que extrañamente pueden tener múltiples citas de apertura o ninguna cita de apertura. Los .*? a continuación, puede analizar cualquier carácter, incluidas las comillas hasta que llegue al primer carácter ‘]’, finalizando la coincidencia. No hay ninguna disposición para los caracteres especiales CSS de escape de barra invertida, por lo que no puede hacer coincidir un valor de cadena arbitrario en jQuery.

(Una vez más, los analizadores de expresiones regulares pierden).

Pero la buena noticia es que no tiene que depender de los selectores de jQuery; hay métodos DOM perfectamente buenos que puede usar, en particular HTMLSelectElement.options:

 var select= document.getElementById('SomeDropdown'); for (var i= select.options.length; i-->0;) { if (select.options[i].value=="a'b]

") { // do something with option } }

Esto es muchas veces más simple y más rápido que pedirle a jQuery que analice e implemente laboriosamente su selector, y puede usar cualquier cadena de valores que desee sin tener que preocuparse por escapar de los caracteres especiales.

Uso esta función para escapar de los selectores de jquery. Se escapa básicamente todo lo cuestionable, pero puede ser demasiado agresivo.

 función escapeStr (str) 
 {
     si (str)
         return str.replace (/ ([#;?% &,. + * ~ \ ': "! ^ $ [\] () => | \ / @]) / g,' \\ $ 1 ');      

     devolver str;
 }

use .filter() con una función personalizada. txt debe contener su cadena desagradable, o simplemente puede reemplazar indexOf con cualquier otra función que elija.

 $("#SomeDropdown option") .filter(function(i){ return $(this).attr("value").indexOf(txt) != -1; }) .remove(); 

Me parece que puedes usar \ \ para escapar de los selectores. Piense en ello como uno \ para la expresión regular y para escapar de la expresión regular.

Ejemplo:

 $(this).find('input[name=user\\[1\\]\\[name\\]]').val(); 

Si intenta escaparse programáticamente, solo necesita un conjunto de barras diagonales. Esto no funcionará:

 var key = 'user[1][name]'; $(this).find('select[name=' + key + ']'); 

Pero esto hará:

 var key = 'user\[1\]\[name\]'; $(this).find('select[name=' + key + ']'); 

Y también lo hará esto:

 $(this).find('select[name=user\\[1\\]\\[name\\]]'); 

Puede usar este javascript para construir un selector correctamente escapado:

 if(key.indexOf('[') !== -1) { key = key.replace(/([\[\]])/g, "\\$1"); } 

Aquí hay un JS Fiddle que muestra algunos de los comportamientos raros:

http://jsfiddle.net/dH3cV/

El problema se debe a las entidades HTML; el “navegador” ve ” < ” como ” < ".

Lo mismo podría decirse del ejemplo proporcionado por bobince; tenga en cuenta que lo siguiente no funciona con jQuery 1.32 en Win + FF3:

 var select= document.getElementById('SomeDropdown'); for (var i= select.options.length; i-->0;) { if (select.options[i].value=="a'b]<p>") { alert('found it'); } } 

Sin embargo, cambiar la entidad a un literal de hecho encontrará el valor deseado:

 var select= document.getElementById('SomeDropdown'); for (var i= select.options.length; i-->0;) { if (select.options[i].value=="a'b]

") { alert('found it'); } }

Por supuesto, aquí hay un problema, ya que el valor que está especificando no es el valor exacto que está buscando. Esto también se puede corregir con la adición de una función de ayuda:

 function html_entity_decode(str) { var decoder = document.createElement('textarea'); decoder.innerHTML = str; return decoder.value; } 

Todos juntos ahora:

 var srcValue = html_entity_decode("a'b]<p>"); var select= document.getElementById('SomeDropdown'); for (var i= select.options.length; i-->0;) { if (select.options[i].value == srcValue) { alert('found it'); } } 

Ahora, el valor de entrada que está buscando coincide exactamente con el valor del elemento de selección.

Esto también se puede escribir usando métodos jQuery:

 var srcValue = html_entity_decode("a'b]<p>"); $($('#SomeDropdown').attr('options')).each(function() { if (this.value == srcValue) { $(this).remove(); } }); 

Y finalmente, como un complemento, ya que son muy fáciles de hacer:

 jQuery.fn.removeByValue = function( val ) { var decoder = document.createElement('textarea'); decoder.innerHTML = val; var srcValue = decoder.value; $( $(this)[0].options ).each(function() { if (this.value == srcValue) { $(this).remove(); } }); return this; }; $('#SomeDropdown').removeByValue("a'b]<p>"); 

El foro de jQuery tiene una buena solución para esto:

https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/

Esta versión ligeramente modificada de lo que sugieren también es nula.

 function jqid (id) { return (!id) ? null : '#' + id.replace(/(:|\.|\[|\]|,)/g, '\\$1'); } 

Escapar cadenas de CSS de manera segura no es fácil y no se puede hacer con expresiones regulares simples.

Puedes usar CSS.escape() .

esto no es compatible con todos los navegadores, pero existe un polyfill .