jQuery选择器值转义
Posted
技术标签:
【中文标题】jQuery选择器值转义【英文标题】:jQuery selector value escaping 【发布时间】:2010-10-18 21:20:52 【问题描述】:我有一个包含一系列选项的下拉列表:
<select id=SomeDropdown>
<option value="a'b]<p>">a'b]<p></option>
<option value="easy">easy</option>
<select>
注意选项值/文本包含一些讨厌的东西:
单引号 右方括号 转义的html我需要删除 a'b]
选项,但我没有运气编写选择器。两者都没有:
$("#SomeDropdown >option[value='a''b]<p>']");
或
$("#SomeDropdown >option[value='a\'b]<p>']");
正在返回选项。
使用 "value=" 选择器时转义值的正确方法是什么?
【问题讨论】:
用户可以输入任何内容。他们不太可能......但如果他们这样做了,那么应用程序应该正确处理输入。 【参考方案1】:我使用这个函数来转义 jquery 选择器。它基本上避开了所有有问题的东西,但可能过于激进。
函数 escapeStr(str) 如果(字符串) return str.replace(/([ #;?%&,.+*~\':"!^$[\]()=>|\/@])/g,'\\$1'); 返回字符串;【讨论】:
你测试过吗?当我测试它时,它只在元字符前放了 1 个斜杠。这是我写的:str.replace(/([ !"#$%&'()*+,.\/:;<=>?@[\\\]^`|~])/g,'\\\\$1')
.
@Mark,使用答案中的代码可以很好地转义 jquery 选择器中的特殊字符。
@Justin:你可能是对的。医生欺骗了我。它说你需要两个斜杠,但一个只是用于转义 javascript 字符串中的斜杠,第二个是用于实际转义 CSS 选择器。
我修改了正则表达式以包含匹配 ?
: return str.replace(/([ #;?&,.+*~\':"!^$[\]()=>|\/@])/g,'\\$1');
百分号%
也需要转义。【参考方案2】:
我不认为你可以。它应该是:
#SomeDropdown >option[value='a\'b]<p>']
这确实可以用作 CSS 选择器(在现代浏览器中)。用 JavaScript 字符串文字表示,你自然需要另一轮转义:
$("#SomeDropdown >option[value='a\\'b]<p>']")
但这在 jQuery 中不起作用,因为它的选择器解析器不完全符合标准。它使用此正则表达式来解析 [attr=value]
条件的 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 费力地解析和实现你的选择器要简单和快速很多倍,你可以使用任何你喜欢的值字符串,而不必担心转义特殊字符。
【讨论】:
我建议将其作为纯 DOM 的 jQuery 替代品: $('option', '#SomeDropdown').filter(function() return $(this).val() == "a'b]"; );
@PaoloBergantino 您的回答是我的案例的完美解决方案。非常感谢您的评论。【参考方案3】:将.filter()
与自定义函数一起使用。 txt
应该包含您讨厌的字符串,或者您可以将 indexOf
替换为您选择的任何其他函数。
$("#SomeDropdown option")
.filter(function(i)
return $(this).attr("value").indexOf(txt) != -1;
)
.remove();
【讨论】:
很难阅读您的代码示例。请使用新行并以八个空格(不是制表符)开始下一行来格式化您的代码,以便读者不必滚动。 这比那些疯狂的正则表达式更好(我不是正则专家)。这在解决一个令人讨厌的问题时也派上了用场。所以我认为这个答案要好得多。【参考方案4】:我发现您可以使用 \\ 来转义选择器。将其视为正则表达式的一个 \ 和一个从正则表达式中逃脱的 \。
例子:
$(this).find('input[name=user\\[1\\]\\[name\\]]').val();
【讨论】:
我写了一个 .replace 正则表达式来为你转义选择器here【参考方案5】:如果您尝试以编程方式进行转义,则只需要一组斜杠。这行不通:
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 Fiddle,显示了一些奇怪的行为:
http://jsfiddle.net/dH3cV/
【讨论】:
【参考方案6】:问题是由于 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]<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');
现在,您正在搜索的输入值与选择元素的值完全匹配。
这也可以使用 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>");
【讨论】:
【参考方案7】:jQuery.escapeSelector()
是在 jQuery 3 中引入的。要匹配问题中值 a'b]&lt;p>
的选项,您可以使用:
$("#SomeDropdown > option[value='" + $.escapeSelector("a'b]<p>") + "']")
一般来说,使用jQuery.escapeSelector()
是一种很好的做法,例如$('#' + $.escapeSelector(id))
,其中变量id
可能包含特殊的CSS 符号。
【讨论】:
【参考方案8】:jQuery 的论坛对此有一个很好的解决方案:
https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/
他们建议的这个稍作修改的版本也是 nullsafe。
function jqid (id)
return (!id) ? null : '#' + id.replace(/(:|\.|\[|\]|,)/g, '\\$1');
【讨论】:
【参考方案9】:安全地escaping CSS string 并不容易,不能用简单的正则表达式来完成。
你可以使用CSS.escape()
。
除a polyfill exist外,并非所有浏览器都支持。
【讨论】:
以上是关于jQuery选择器值转义的主要内容,如果未能解决你的问题,请参考以下文章