我有一个包含一系列选项的下拉列表:
<select id=SomeDropdown>
<option value="a'b]<p>">a'b]<p></option>
<option value="easy">easy</option>
<select>
请注意,选项值/文本包含一些讨厌的东西:
我需要删除a'b]&lt; p&gt;选项,但我没有运气写选择器。既不:
$("#SomeDropdown >option[value='a''b]<p>']");
或
$("#SomeDropdown >option[value='a\'b]<p>']");
正在返回选项。
使用“value =”选择器时,转义值的正确方法是什么?
答案 0 :(得分:51)
我使用此函数来转义jquery选择器。它基本上逃脱了一切可疑但可能过于激进。
function escapeStr(str) { if (str) return str.replace(/([ #;?%&,.+*~\':"!^$[\]()=>|\/@])/g,'\\$1'); return str; }
答案 1 :(得分:38)
我认为你不能。 应该:
#SomeDropdown >option[value='a\'b]<p>']
这确实可以用作CSS选择器(在现代浏览器中)。在JavaScript字符串文字中表示,您自然需要进行另一轮转义:
$("#SomeDropdown >option[value='a\\'b]<p>']")
但是这在jQuery中不起作用,因为它的选择器解析器并不完全符合标准。它使用此正则表达式来解析value
条件的[attr=value]
部分:
(['"]*)(.*?)\3|)\s*\]
\ 3是包含开头报价的组,奇怪的是允许多个开盘报价,或根本没有开盘报价。 。*?然后可以解析任何字符,包括引号,直到它击中第一个']'字符,结束匹配。没有提供反斜杠转义的CSS特殊字符,因此您无法在jQuery中匹配任意字符串值。
(再一次,正则表达式解析器丢失了。)
但好消息是你不必依赖jQuery选择器;你可以使用非常好的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费力地解析和实现你的选择器要简单快多倍,你可以使用你喜欢的任何值字符串,而不必担心转义特殊字符。
答案 2 :(得分:9)
将.filter()
与自定义函数一起使用。 txt
应该包含令人讨厌的字符串,或者您可以将indexOf
替换为您选择的任何其他函数。
$("#SomeDropdown option")
.filter(function(i){
return $(this).attr("value").indexOf(txt) != -1;
})
.remove();
答案 3 :(得分:5)
我发现你可以使用\ \来逃避选择器。可以把它想象成正则表达式,一个逃离正则表达式。
示例:
$(this).find('input[name=user\\[1\\]\\[name\\]]').val();
答案 4 :(得分:3)
如果您尝试以编程方式进行转义,则只需要一组斜杠。这不起作用:
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构建正确转义的选择器:
if(key.indexOf('[') !== -1) {
key = key.replace(/([\[\]])/g, "\\$1");
}
这是一个JS小提琴,它展示了一些奇怪的行为:
答案 5 :(得分:2)
问题是由于HTML实体造成的;浏览器将“ <
”视为“ <
”。
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]<p>") {
alert('found it');
}
}
但是,将实体更改为文字确实会找到所需的值:
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]<p>");
var select= document.getElementById('SomeDropdown');
for (var i= select.options.length; i-->0;) {
if (select.options[i].value == srcValue) {
alert('found it');
}
}
现在,您要搜索的输入值与select元素的值完全匹配。
这也可以使用jQuery方法编写:
var srcValue = html_entity_decode("a'b]<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]<p>");
答案 6 :(得分:1)
jQuery的论坛有一个很好的解决方案:
他们建议的这个稍微修改过的版本也是无关紧要的。
function jqid (id) {
return (!id) ? null : '#' + id.replace(/(:|\.|\[|\]|,)/g, '\\$1');
}
答案 7 :(得分:1)
答案 8 :(得分:1)
jQuery.escapeSelector()
是jQuery 3中引入的。要使问题中的选项与值a'b]<p>
相匹配,可以使用:
$("#SomeDropdown > option[value='" + $.escapeSelector("a'b]<p>") + "']")
通常,对于jQuery.escapeSelector()
之类的事物,使用$('#' + $.escapeSelector(id))
是一个好习惯,其中变量id
可能包含特殊的CSS符号。