代码之家  ›  专栏  ›  技术社区  ›  user53794

jquery选择器值转义

  •  54
  • user53794  · 技术社区  · 15 年前

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

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

    注意,选项值/文本包含一些讨厌的内容:

    • 单引号
    • 封闭方括号
    • 转义HTML

    我需要删除a'b]<p>选项,但我写选择器时运气不佳。既不:

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

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

    正在返回选项。

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

    8 回复  |  直到 8 年前
        1
  •  38
  •   bobince    15 年前

    我觉得你做不到。它 应该 铍:

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

    这确实是一个CSS选择器(在现代浏览器中)。用javascript字符串文字表示,您自然需要另一轮转义:

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

    但这在jquery中不起作用,因为它的选择器解析器并不完全符合标准。它使用这个regex来解析 value 一部分 [attr=value] 条件:

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

    \三是含有开场白的组,奇怪的是允许有多个开场白,或者根本没有开场白。*?然后可以解析任何字符, 包括引号 直到它碰到第一个字符,结束匹配。没有反斜杠转义CSS特殊字符的规定,因此在jquery中不能匹配任意字符串值。

    (再次,regex解析器丢失。)

    但好消息是,您不必依赖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
  •  51
  •   Rob Pranay Rana    11 年前

    我使用这个函数来转义jquery选择器。它基本上可以避开所有可疑的问题,但可能过于激进。

    function escapeStr(str) 
    {
        if (str)
            return str.replace(/([ #;?%&,.+*~\':"!^$[\]()=>|\/@])/g,'\\$1');      
    
        return str;
    }
    
        3
  •  9
  •   Mohammed H    12 年前

    使用 .filter() 具有自定义功能。 txt 应该包含你讨厌的字符串,或者你可以直接替换 indexOf 你可以选择其他功能。

    $("#SomeDropdown option")
       .filter(function(i){
           return $(this).attr("value").indexOf(txt) != -1;
       })
       .remove();
    
        4
  •  5
  •   Strixy    12 年前

    我发现您可以使用\\来转义选择器。把它想象成一个\对regex和一个逃避regex。

    例子:

    $(this).find('input[name=user\\[1\\]\\[name\\]]').val();
    
        5
  •  3
  •   Steve Tauber    11 年前

    如果您试图以编程方式进行转义,则只需要一组斜杠。这行不通:

    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小提琴,它显示了一些奇怪的行为:

    http://jsfiddle.net/dH3cV/

        6
  •  2
  •   ken    8 年前

    问题是由HTML实体引起的;该“ &lt; “被浏览器视为” < “。

    Bobines提供的示例也可以这样说;请注意,以下内容不适用于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');
        }   
    }
    

    但是,将实体更改为文本确实会找到所需的值:

    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');
        }   
    }
    

    现在,您正在搜索的输入值与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>");
    
        7
  •  1
  •   theUtherSide adragom    9 年前

    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/

    他们建议的这个稍微修改过的版本也是空安全的。

    function jqid (id) {
      return (!id) ? null : '#' + id.replace(/(:|\.|\[|\]|,)/g, '\\$1');
    }
    
        8
  •  1
  •   Yukulélé    8 年前

    安全地 escaping CSS string 不容易,不能用简单的regex来完成。

    你可以使用 CSS.escape() .

    并非所有浏览器都支持此功能,但 a polyfill exist .