jQuery的select器值转义

我有一个下拉列表,其中包含一系列选项:

<select id=SomeDropdown> <option value="a'b]&lt;p>">a'b]&lt;p></option> <option value="easy">easy</option> <select> 

注意选项值/文本包含一些讨厌的东西:

  • 单引号
  • closures方括号
  • 转义的HTML

我需要删除a'b] <p>选项,但我没有运气写select器。 无论是:

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

要么

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

正在返回选项。

使用“value =”select器时,转义值的正确方法是什么?

我不认为你可以。 它应该是:

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

这可以作为一个CSSselect器(在现代浏览器中)。 用JavaScriptstring表示,你自然需要进行另一轮转义:

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

但是这在jQuery中不起作用,因为它的select器parsing器不完全符合标准。 它使用这个正则expression式来parsing[attr=value]条件的value部分:

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

3是包含开盘价格的集团,这些开盘价格可以是多个开盘报价,也可以不是开盘报价。 。*? 然后可以parsing任何字符, 包括引号,直到遇到第一个']'字符,结束匹配。 没有提供反斜杠转义的CSS特殊字符,所以你不能在jQuery中匹配任意的string值。

(再次,正则expression式parsing器丢失。)

但好消息是你不必依赖jQueryselect器; 有完美的DOM方法可以使用,特别是HTMLSelectElement.options:

 var select= document.getElementById('SomeDropdown'); for (var i= select.options.length; i-->0;) { if (select.options[i].value=="a'b]<p>") { // do something with option } } 

这比要求jQuery费力地parsing和实现select器要简单快捷很多,而且你可以使用任何你喜欢的string,而不用担心特殊字符的转义。

我使用这个函数来转义jQueryselect器。 它基本上逃脱了所有可疑的事情,但可能过于激进。

函数escapeStr(str) 
 {
    如果(str)
         return str.replace(/([#;?%&,。+ *〜':“!^ $ [\]()=> | \ / @])/ g,'\\ $ 1');      

    返回str;
 }

使用.filter()与自定义函数。 txt应该包含你讨厌的string,或者你可以用你select的其他函数replaceindexOf

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

我发现你可以使用\ \来逃避select器。 把它看作一个“正则expression式”,一个从正则expression式中逃脱出来。

例:

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

如果您尝试以编程方式进行转义,则只需要一组斜线。 这不会工作:

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

但是这将会:

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

这样做也是如此:

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

你可以使用这个JavaScript来构build一个正确的转义select器:

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

这是一个JS小提琴,显示了一些奇怪的行为:

http://jsfiddle.net/dH3cV/

问题是由于HTML实体; 浏览器将“ &lt; ”视为“ < ”。

同样可以说,由bobince提供的例子; 请注意以下不适用于Win + FF3上的jQuery 1.32:

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

但是,将实体更改为文字将确实find所需的值:

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

当然,这里有一个问题,因为你指定的价值不是你正在寻找的确切的价值。 这也可以通过添加辅助函数来纠正:

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

现在都在一起了:

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

现在,您正在search的input值与select元素的值完全匹配。

这也可以使用jQuery方法编写:

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

最后,作为一个插件,因为它们很容易制作:

 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]&lt;p>"); 

jQuery的论坛有一个很好的解决scheme:

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

他们build议的这个稍微修改过的版本也是没有问题的。

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

安全地转义CSSstring是不容易的,不能用简单的正则expression式来完成。

你可以使用CSS.escape()

这不是所有浏览器都支持的,但是存在一个polyfill 。