UFO ET IT

jQuery 선택기 값 이스케이프

ufoet 2021. 1. 11. 21:12
반응형

jQuery 선택기 값 이스케이프


일련의 옵션이 포함 된 드롭 다운 목록이 있습니다.

<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 ="선택기를 사용할 때 값을 이스케이프하는 올바른 방법은 무엇입니까?


나는 당신이 할 수 있다고 생각하지 않습니다. 다음과 같아야 합니다.

#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에 힘들게 선택기를 구문 분석하고 구현하도록 요청하는 것보다 훨씬 간단하고 빠르며, 특수 문자 이스케이프에 대해 걱정할 필요없이 원하는 값 문자열을 사용할 수 있습니다.


이 함수를 사용하여 jquery 선택기를 이스케이프합니다. 기본적으로 의심스러운 모든 것을 피하지만 너무 공격적 일 수 있습니다.

escapeStr (str) 함수 
{
    if (str)
        return str.replace (/ ([#;? % &,. + * ~ \ ': "! ^ $ [\] () => | \ / @]) / g,'\\ $ 1 ');      

    반환 str;
}

.filter()사용자 정의 함수와 함께 사용하십시오 . txt불쾌한 문자열을 포함하거나 indexOf선택한 다른 기능으로 대체 할 수 있습니다.

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

\ \를 사용하여 선택자를 이스케이프 할 수 있습니다. 정규식에 대한 \와 정규식에서 탈출하는 것으로 생각하십시오.

예:

$(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\\]]');

이 자바 스크립트를 사용하여 올바르게 이스케이프 된 선택기를 만들 수 있습니다.

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

다음은 이상한 동작을 보여주는 JS Fiddle입니다.

http://jsfiddle.net/dH3cV/


The problem is due to HTML entities; the "&lt;" is seen by the browser as "<".

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:

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

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]&lt;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.

This can also be written using jQuery methods:

var srcValue = html_entity_decode("a'b]&lt;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]&lt;p>");

jQuery's forum has a nice solution for this:

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

This slightly modified version of what they suggest is also nullsafe.

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

Safely escaping CSS string is not easy and can't be done with simple regex.

You can use CSS.escape() .

this is not supported by all browsers but a polyfill exist.

ReferenceURL : https://stackoverflow.com/questions/739695/jquery-selector-value-escaping

반응형