Подтвердить что ты не робот

Выделение селектора jQuery

У меня есть раскрывающийся список, содержащий ряд опций:

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

Обратите внимание, что значение параметра/текст содержит некоторые неприятные вещи:

  • одинарные кавычки
  • закрывающая квадратная скобка
  • escaped html

Мне нужно удалить параметр a'b] <p> но мне не повезло записать селектор. Ни:

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

или

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

возвращает параметр.

Каков правильный способ избежать значений при использовании селектора "value ="?

4b9b3361

Ответ 1

Я не думаю, что ты можешь. Это должно быть:

#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

Я использую эту функцию для переключения селекторов jquery. Он избегает в основном всего сомнительного, но может быть слишком агрессивным.

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

    return str;
}

Ответ 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();

Ответ 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; обратите внимание, что следующее не работает с jQuery 1.32 в 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');
    }   
}

Однако изменение объекта в литерал действительно найдет нужное значение:

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>");