Самый безопасный способ выбора всех переключателей без атрибута value

http://jsfiddle.net/CuURK/

У меня есть несколько переключателей вроде:

<input type='radio' name='myradio' id='myradio' />

Мне нужно выбрать все переключатели без атрибута value в разметке, а затем установить для них атрибут. Следующие тесты не работают:

$('#myradio').val() // returns 'on'
$('#myradio').attr('value') // returns 'on'

Это работает в Chrome, но не в IE8:

$('#myradio').is('[value]'); //doesn't work in IE8

Какой самый безопасный способ определить, имеет ли элемент атрибут значения? Есть ли объяснение описанного выше поведения?

Ответы

Ответ 1

Лучшим и быстрым способом является использование селекторов CSS:

$('input[type="radio"]:not([value])')

вернет все элементы < input radio без атрибута value present - См. этот скрипт.

Так как он возвращает коллекцию, вы можете делать все, что хотите, например, добавление отсутствующего атрибута, добавление класса, скрытие или удаление элементов без необходимости цикла .each(), поскольку большинство методов jQuery могут работать с коллекциями - Посмотрите эту скрипту.

Итак, в вашем случае добавить отсутствующий атрибут:

$('input[type="radio"]:not([value])').attr('value', 'foobar');

Помните, что селектор является допустимым селектором CSS3.


Update:

В соответствии с этим наш селектор никогда не будет соответствовать в IE8, поскольку IE8 не может сравниться с [attr], если данный attr пуст ( и мы пытаемся это сопоставить).

Итак, мы должны перебрать input и проверить, равен ли атрибут value '', так как если он отсутствует, jQuery возвращает пустую строку.

Здесь скрипка, которая работает на IE8 (я смог попробовать ее на реальном IE8).

$('input[type="radio"]').each(function (index, element) {
    var $this = $(this);
    if ($this.get(0).outerHTML.indexOf('value') === -1) {
        $this.addClass('found');
    }
});

Для каждого элемента мы проверяем, содержит ли его свойство outerHTML строку value. Если он не содержит, содержащую строку, мы ее нашли. Как вы увидите, он только терпит неудачу с node следующим образом:

<input type="radio" value />

потому что IE анализирует его как:

<input type="radio" />

Это не эффективное решение, но оно работает.

Кстати, как я сказал в комментариях, input с type="radio" должен иметь атрибут value, Если это не так, документ недействителен, и браузер может попытаться исправить дерево документа - Firefox, похоже, добавит значение по умолчанию on, а Safari - нет.

Наконец, jQuery .attr() возвращает undefined, если искомый атрибут не существует (см. источник): обычно вы можете проверить

typeof $('#foo').attr('attributeName') === 'undefined'

чтобы увидеть, имеет ли элемент атрибут attributeName.

Ответ 2

Следующее будет работать:

$('input[type="radio"]:not([value])')

Как показано здесь: http://jsfiddle.net/4sLzc/1/

Причина, по которой .val() возвращает "on", заключается в том, что по умолчанию для переключателя без атрибута value возвращается значение по умолчанию "on". Это не вещь jQuery: то же самое происходит с обычным JavaScript, если вы говорите document.getElementById("myradio").value, или когда форма отправлена, вы найдете серверную сторону, которая "on" является фактическим представленным значением.

Ответ 3

Это будет соответствовать элементам, которые имеют атрибут value

$('input[value]');

и это для тех, которые не

$('!input[value]');