jQuery 选择器值转义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/739695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery selector value escaping
提问by user53794
I have a dropdown list that contains a series of options:
我有一个包含一系列选项的下拉列表:
<select id=SomeDropdown>
<option value="a'b]<p>">a'b]<p></option>
<option value="easy">easy</option>
<select>
Notice that the option value/text contains some nasty stuff:
请注意,选项值/文本包含一些讨厌的东西:
- single quotes
- closing square bracket
- escaped html
- 单引号
- 右方括号
- 转义 html
I need to remove the a'b]<p> option but I'm having no luck writing the selector. Neither:
我需要删除 a'b]<p> 选项,但我没有写好选择器。两者都不:
$("#SomeDropdown >option[value='a''b]<p>']");
or
或者
$("#SomeDropdown >option[value='a\'b]<p>']");
are returning the option.
正在返回选项。
What is the correct way to escape values when using the "value=" selector?
使用“value=”选择器时转义值的正确方法是什么?
采纳答案by bobince
I don't think you can. It shouldbe:
我不认为你可以。它应该是:
#SomeDropdown >option[value='a\'b]<p>']
And this does work as a CSS selector (in modern browsers). Expressed in a JavaScript string literal you would naturally need another round of escaping:
这确实可以用作 CSS 选择器(在现代浏览器中)。用 JavaScript 字符串文字表示,您自然需要另一轮转义:
$("#SomeDropdown >option[value='a\'b]<p>']")
But this doesn't work in jQuery because its selector parser is not completely standards-compliant. It uses this regex to parse the value
part of an [attr=value]
condition:
但这在 jQuery 中不起作用,因为它的选择器解析器并不完全符合标准。它使用这个正则表达式来解析条件的value
一部分[attr=value]
:
(['"]*)(.*?)|)\s*\]
\3 being the group containing the opening quotes, which weirdly are allowed to be multiple opening quotes, or no opening quotes at all. The .*? then can parse any character, including quotesuntil it hits the first ‘]' character, ending the match. There is no provision for backslash-escaping CSS special characters, so you can't match an arbitrary string value in jQuery.
\3 是包含开头引号的组,奇怪的是允许是多个开头引号,或者根本没有开头引号。这 。*?然后可以解析任何字符,包括引号,直到它遇到第一个 ']' 字符,结束匹配。没有提供反斜杠转义 CSS 特殊字符的规定,因此您无法匹配 jQuery 中的任意字符串值。
(Once again, regex parsers lose.)
(再一次,正则表达式解析器失败了。)
But the good news is you don't have to rely on jQuery selectors; there are perfectly good DOM methods you can use, in particular HTMLSelectElement.options:
但好消息是您不必依赖 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
} }
This is many times simpler and faster than asking jQuery to laboriously parse and implement your selector, and you can use any value string you like without having to worry about escaping special characters.
这比要求 jQuery 费力地解析和实现您的选择器要简单和快速许多倍,并且您可以使用任何您喜欢的值字符串而不必担心转义特殊字符。
回答by Sam Hendley
I use this function to escape jquery selectors. It escapes basically everything questionable but may be too aggressive.
我使用这个函数来转义 jquery 选择器。它基本上避开了所有可疑的问题,但可能过于激进。
function escapeStr(str) { if (str) return str.replace(/([ #;?%&,.+*~\':"!^$[\]()=>|\/@])/g,'\'); return str; }
回答by brainsucker
use .filter()
with a custom function. txt
should contain your nasty string, or you could just replace indexOf
with any other function you choose.
使用.filter()
带有自定义功能。txt
应该包含你讨厌的字符串,或者你可以indexOf
用你选择的任何其他函数替换。
$("#SomeDropdown option")
.filter(function(i){
return $(this).attr("value").indexOf(txt) != -1;
})
.remove();
回答by Strixy
I find that you can use \ \ to escape selectors. Think of it as one \ for the regex and one to escape from the regex.
我发现您可以使用 \\ 来转义选择器。把它想象成正则表达式的一个 \ 和一个从正则表达式中逃脱的。
Example:
例子:
$(this).find('input[name=user\[1\]\[name\]]').val();
回答by Steve Tauber
If you are trying to do the escaping programmatically, you only need one set of slashes. This won't work:
如果您尝试以编程方式进行转义,则只需要一组斜杠。这行不通:
var key = 'user[1][name]';
$(this).find('select[name=' + key + ']');
But this will:
但这将:
var key = 'user\[1\]\[name\]';
$(this).find('select[name=' + key + ']');
And so will this:
这也是:
$(this).find('select[name=user\[1\]\[name\]]');
You can use this javascript to build a correctly escaped selector:
你可以使用这个 javascript 来构建一个正确转义的选择器:
if(key.indexOf('[') !== -1) {
key = key.replace(/([\[\]])/g, "\");
}
Here's a JS Fiddle that shows some of the weird behavior:
这是一个 JS Fiddle,显示了一些奇怪的行为:
回答by ken
The problem is due to HTML entities; the "<
" is seen by the browser as "<
".
问题是由 HTML 实体引起的;“ <
”被浏览器视为“ <
”。
The same could be said for the example provided by bobince; please note that the following does not work with jQuery 1.32 on Win + FF3:
对于 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');
}
}
However, changing the entity to a literal will indeed find the desired value:
但是,将实体更改为文字确实会找到所需的值:
var select= document.getElementById('SomeDropdown');
for (var i= select.options.length; i-->0;) {
if (select.options[i].value=="a'b]<p>") {
alert('found it');
}
}
Of course, there is a problem here, as the value that you're specifying is not the exact value that you're looking for. This can also be corrected with the addition of a helper function:
当然,这里有一个问题,因为您指定的值不是您要查找的确切值。这也可以通过添加辅助函数来纠正:
function html_entity_decode(str) {
var decoder = document.createElement('textarea');
decoder.innerHTML = str;
return decoder.value;
}
All together now:
现在都在一起了:
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');
}
}
Any now, the input value that you're searching for exactly matches the value of the select element.
现在,您要搜索的输入值与 select 元素的值完全匹配。
This can also be written using jQuery methods:
这也可以使用 jQuery 方法编写:
var srcValue = html_entity_decode("a'b]<p>");
$($('#SomeDropdown').attr('options')).each(function() {
if (this.value == srcValue)
{
$(this).remove();
}
});
And then finally, as a plugin since they are so easy to make:
最后,作为插件,因为它们很容易制作:
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>");
回答by theUtherSide
jQuery's forum has a nice solution for this:
jQuery 的论坛对此有一个很好的解决方案:
This slightly modified version of what they suggest is also nullsafe.
他们建议的这个稍微修改的版本也是空安全的。
function jqid (id) {
return (!id) ? null : '#' + id.replace(/(:|\.|\[|\]|,)/g, '\');
}
回答by Yukulélé
Safely escaping CSS stringis not easy and can't be done with simple regex.
安全地转义 CSS 字符串并不容易,并且无法使用简单的正则表达式来完成。
You can use CSS.escape()
.
您可以使用CSS.escape()
.
this is not supported by all browsers but a polyfill exist.
并非所有浏览器都支持此功能,但存在 polyfill。