Я использую jQuery для скрытия и отображения элементов при изменении / нажатии группы переключателей. Он отлично работает в таких браузерах, как Firefox, но в IE 6 и 7 действие происходит только тогда, когда пользователь затем щелкает в другом месте страницы.
Чтобы уточнить, когда вы загружаете страницу, все выглядит нормально. В Firefox, если вы щелкнете радиокнопку, одна строка таблицы будет скрыта, а другая сразу же отобразится. Однако в IE 6 и 7 вы щелкаете переключатель, и ничего не произойдет, пока вы не нажмете где-нибудь на странице. Только после этого IE перерисовывает страницу, скрывая и показывая соответствующие элементы.
Вот jQuery, который я использую:
$(document).ready(function () {
$(".hiddenOnLoad").hide();
$("#viewByOrg").change(function () {
$(".visibleOnLoad").show();
$(".hiddenOnLoad").hide();
});
$("#viewByProduct").change(function () {
$(".visibleOnLoad").hide();
$(".hiddenOnLoad").show();
});
});
Вот часть XHTML, на которую это влияет. Вся страница проверяется как XHTML 1.0 Strict.
<tr>
<td>View by:</td>
<td>
<p>
<input type = "radio" name = "viewBy" id = "viewByOrg" value = "organisation"
checked = "checked" />Organisation</p>
<p>
<input type = "radio" name = "viewBy" id = "viewByProduct" value = "product" />Product</p>
</td>
</tr>
<tr class = "visibleOnLoad">
<td>Organisation:</td>
<td>
<select name = "organisation" id = "organisation" multiple = "multiple" size = "10">
<option value = "1">Option 1</option>
<option value = "2">Option 2</option>
</select>
</td>
</tr>
<tr class = "hiddenOnLoad">
<td>Product:</td>
<td>
<select name = "product" id = "product" multiple = "multiple" size = "10">
<option value = "1">Option 1</option>
<option value = "2">Option 2</option>
</select>
</td>
</tr>
Если у кого-то есть идеи, почему это происходит и как это исправить, они были бы очень признательны!

Попробуйте использовать .click вместо .change.
@samjudson, в моем тестировании это неверно, и щелчок jquery срабатывает, когда я выбираю следующий переключатель с помощью клавиш со стрелками. (Виста, IE7)
@Pacifika: Не для меня в IE7. По крайней мере, это правильно. «щелчок» - это совершенно иное событие, чем «изменение», и есть, по крайней мере, некоторые (если не все) случаи, когда это неуместная замена.
@samjudson: события щелчка на переключателях и флажках также срабатывают при их выборе с помощью клавиатуры. Работает во всех браузерах
Я поправляюсь - это действительно так, как бы нелогично это ни было!
Кажется, это самый популярный ответ на этот конкретный вопрос, но он не совсем правильный! click отличается от change тем, что его обработчик событий также будет вызываться при нажатии на уже выбранную опцию, тогда как change - нет. Этот ответ имеет пример того, как использовать jQuery .data для сравнения старых и новых значений.
Это НЕ правильный ответ. IE распознает $.click(), но он не будет работать, если вы измените значение ввода и щелкните снаружи. Я предлагаю использовать .blur (), но еще не тестировал.
Я почти уверен, что это известная проблема с IE. Добавление обработчика события onclick должно решить проблему:
$(document).ready(function(){
$(".hiddenOnLoad").hide();
$("#viewByOrg").change(function () {
$(".visibleOnLoad").show();
$(".hiddenOnLoad").hide();
});
$("#viewByOrg").click(function () {
$(".visibleOnLoad").show();
$(".hiddenOnLoad").hide();
});
$("#viewByProduct").change(function () {
$(".visibleOnLoad").hide();
$(".hiddenOnLoad").show();
});
$("#viewByProduct").click(function () {
$(".visibleOnLoad").hide();
$(".hiddenOnLoad").show();
});
});
В IE вы должны использовать событие click, в других браузерах onchange. Ваша функция может стать
$(document).ready(function(){
$(".hiddenOnLoad").hide();
var evt = $.browser.msie ? "click" : "change";
$("#viewByOrg").bind(evt, function () {
$(".visibleOnLoad").show();
$(".hiddenOnLoad").hide();
});
$("#viewByProduct").bind(evt, function () {
$(".visibleOnLoad").hide();
$(".hiddenOnLoad").show();
});
});
Замените click на click keyup keypress, чтобы добавить поддержку клавиатуры.
Это тоже должно сработать:
$(document).ready(function(){
$(".hiddenOnLoad").hide();
$("#viewByOrg, #viewByProduct").bind(($.browser.msie ? "click" : "change"), function () {
$(".visibleOnLoad").show();
$(".hiddenOnLoad").hide();
});
});
Спасибо, Пьер. Это было очень полезно.
Это, по крайней мере, гораздо лучший ответ, чем текущий принятый / получивший наибольшее количество голосов. Это "только" нарушает доступность клавиатуры в IE, а не во всех хороших браузерах.
... хотя, разве это не просто копия ответа Пьера?
Согласен, это чуть менее читаемая версия Пьера, но оба селектора связаны за один вызов.
Замените click на click keyup keypress, чтобы добавить поддержку клавиатуры.
Проблема с использованием события click вместо change заключается в том, что вы получаете событие, если выбран тот же переключатель (т.е. фактически не изменился). Это можно отфильтровать, если вы проверите, что новое значение отличается от старого. Меня это немного раздражает.
Если вы используете событие change, вы можете заметить, что оно распознает изменение после того, как вы щелкнете любой другой элемент в IE. Если вы вызовете blur() в событии click, это вызовет срабатывание события change (только если радиобоксы действительно изменились).
Вот как я это делаю:
// This is the hack for IE
if ($.browser.msie) {
$("#viewByOrg").click(function() {
this.blur();
this.focus();
});
}
$("#viewByOrg").change(function() {
// Do stuff here
});
Теперь вы можете использовать событие изменения как обычно.
Обновлено: добавлен вызов focus () для предотвращения проблем с доступностью (см. Комментарий Бобби ниже).
Это очень злой хакер, потому что он не позволяет вашим пользователям перемещаться с помощью клавиатуры, потому что фокус исчезает после выбора переключателя.
Это здорово, но вызывает проблемы с доступностью клавиатуры. После срабатывания события blur () переключатель больше не фокусируется, поэтому перемещение между переключателями с помощью клавиатуры становится чрезвычайно неудобным. Мое текущее решение - добавить вызов this.focus (); сразу после оператора blur ().
Я думаю, что это худшее из представленных решений из-за проблем с доступностью.
Но проблему доступности можно решить с помощью вызова focus (). По крайней мере, это так же хорошо, как использовать click () для всего.
Спасибо, Бобби, я добавлю это к ответу.
У меня была эта проблема сегодня рано, и я собираюсь попробовать это завтра. Мне это кажется лучше, чем использовать "щелчок". Если бы я использовал «щелчок», я бы в основном сам реализовал событие «изменение». Спасибо IE за то, что потратил больше времени на работу вокруг вас.
Это лучше, чем решение "щелчок".
Вызов if ($ .browser.msie) больше не работает с jQuery 1.10
imo использование щелчка вместо изменения делает поведение IE другим. Я бы предпочел эмулировать поведение события изменения с помощью таймера (setTimout).
что-то вроде (предупреждение - код блокнота):
if ($.browser.msie) {
var interval = 50;
var changeHack = 'change-hac';
var select = $("#viewByOrg");
select.data(changeHack) = select.val();
var checkVal=function() {
var oldVal = select.data(changeHack);
var newVal = select.val();
if (oldVal !== newVal) {
select.data(changeHack, newVal);
select.trigger('change')
}
setTimeout(changeHack, interval);
}
setTimeout(changeHack, interval);
}
$("#viewByOrg").change(function() {
// Do stuff here
});
эго ... немного деспотичный, нет?
Вы пробовали событие IE onpropertychange? Не знаю, имеет ли это значение, но, наверное, стоит попробовать. IE не запускает событие изменения, когда значения обновляются с помощью JS-кода, но, возможно, в этом случае будет работать onpropertychange.
$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
e.preventDefault(); // Your code here
});
Похоже, что «щелкнуть» не сработало, а «изменение свойства» - сработало. Спасибо!
Я пробовал это в IE8, это не работает. Это не входит в функцию.
У меня была такая же проблема с вводимым текстом.
Я изменился:
$("#myinput").change(function() { "alert('I changed')" });
к
$("#myinput").attr("onChange", "alert('I changed')");
и у меня все работает нормально!
Это простой способ указать IE запускать событие изменения при щелчке по элементу:
if ($.browser.msie) {
$("#viewByOrg").click(function() {
$(this).change();
});
}
Вы можете расширить это до чего-то более общего, чтобы работать с большим количеством элементов формы:
if ($.browser.msie) {
$("input, select").click(function() {
$(this).change();
});
$("input, textarea").keyup(function() {
$(this).change();
});
}
попробуйте это, это работает для меня
$("#viewByOrg")
.attr('onChange', $.browser.msie ? "$(this).data('onChange').apply(this)" : "")
.change( function(){if (!$.browser.msie)$(this).data('onChange').apply(this)} )
.data('onChange',function(){alert('put your codes here')});
добавить этот плагин
jQuery.fn.radioChange = function(newFn){
this.bind(jQuery.browser.msie? "click" : "change", newFn);
}
потом
$(function(){
$("radioBtnSelector").radioChange(function(){
//do stuff
});
});
В IE принудительно активируйте радио и флажки, чтобы вызвать событие «изменения»:
if ($.browser.msie && $.browser.version < 8)
$('input[type=radio],[type=checkbox]').live('click', function(){
$(this).trigger('change');
});
Это может кому-то помочь: Вместо того, чтобы начинать с идентификатора формы, настройте таргетинг на идентификатор выбора и отправьте форму при изменении, например:
<form id='filterIt' action='' method='post'>
<select id='val' name='val'>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='6'>Six</option>
</select>
<input type = "submit" value = "go" />
</form>
и jQuery:
$('#val').change(function(){
$('#filterIt').submit();
});
(Очевидно, что кнопка отправки необязательна, если javascript отключен)
//global
var prev_value = "";
$(document).ready(function () {
if (jQuery.browser.msie && $.browser.version < 8)
$('input:not(:submit):not(:button):not(:hidden), select, textarea').bind("focus", function () {
prev_value = $(this).val();
}).bind("blur", function () {
if ($(this).val() != prev_value)
has_changes = true;
});
}
с jquery 1.6 это больше не проблема .. не уверен, когда это было исправлено .. Слава богу, хотя
Если вы измените версию jQuery на 1.5.1, вам не придется корректировать код. Тогда IE9 будет идеально слушать:
$(SELECTOR).change(function() {
// Shizzle
});
трюк с щелчком работает ... но если вы хотите получить правильное состояние радио или флажка, вы можете использовать это:
(function($) {
$('input[type=checkbox], input[type=radio]').live('click', function() {
var $this = $(this);
setTimeout(function() {
$this.trigger('changeIE');
}, 10)
});
})(jQuery);
$(selector).bind($.browser.msie && $.browser.version <= 8 ? 'changeIE' : 'change', function() {
// do whatever you want
})
Попробуйте следующее:
.bind($.browser.msie ? 'click' : 'change', function(event) {
Избегайте использования .focus () или .Выбрать() перед функцией .изменять()jquery для IE, тогда он работает нормально, я использую его на своем сайте.
Спасибо
Попробуйте использовать каждый вместо изменять / щелкнуть, который отлично работает даже в первый раз в IE, а также в других браузерах.
Не работает в первый раз
$("#checkboxid").**change**(function () {
});
Работает нормально даже с первого раза
$("#checkboxid").**each**(function () {
});
Событие Click работает только в том случае, если вы изменяете значение с помощью мыши - если вы используете клавиатуру, то щелчок не срабатывает, но срабатывает изменение.