Получение jQuery для распознавания .change () в IE

Я использую 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>

Если у кого-то есть идеи, почему это происходит и как это исправить, они были бы очень признательны!

Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
131
0
93 550
20
Перейти к ответу Данный вопрос помечен как решенный

Ответы 20

Ответ принят как подходящий

Попробуйте использовать .click вместо .change.

Событие Click работает только в том случае, если вы изменяете значение с помощью мыши - если вы используете клавиатуру, то щелчок не срабатывает, но срабатывает изменение.

samjudson 16.10.2008 18:24

@samjudson, в моем тестировании это неверно, и щелчок jquery срабатывает, когда я выбираю следующий переключатель с помощью клавиш со стрелками. (Виста, IE7)

svandragt 07.11.2008 16:51

@Pacifika: Не для меня в IE7. По крайней мере, это правильно. «щелчок» - это совершенно иное событие, чем «изменение», и есть, по крайней мере, некоторые (если не все) случаи, когда это неуместная замена.

Bobby Jack 09.07.2009 15:27

@samjudson: события щелчка на переключателях и флажках также срабатывают при их выборе с помощью клавиатуры. Работает во всех браузерах

Philippe Leybaert 09.07.2009 15:40

Я поправляюсь - это действительно так, как бы нелогично это ни было!

Bobby Jack 09.07.2009 16:26

Кажется, это самый популярный ответ на этот конкретный вопрос, но он не совсем правильный! click отличается от change тем, что его обработчик событий также будет вызываться при нажатии на уже выбранную опцию, тогда как change - нет. Этот ответ имеет пример того, как использовать jQuery .data для сравнения старых и новых значений.

Laoujin 14.09.2012 17:13

Это НЕ правильный ответ. IE распознает $.click(), но он не будет работать, если вы измените значение ввода и щелкните снаружи. Я предлагаю использовать .blur (), но еще не тестировал.

Andre Figueiredo 31.01.2014 16:37

Я почти уверен, что это известная проблема с 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, чтобы добавить поддержку клавиатуры.

aloisdg 21.11.2016 20:11

Это тоже должно сработать:

$(document).ready(function(){
   $(".hiddenOnLoad").hide();
   $("#viewByOrg, #viewByProduct").bind(($.browser.msie ? "click" : "change"), function () {
                        $(".visibleOnLoad").show();
                        $(".hiddenOnLoad").hide();
                    });
});

Спасибо, Пьер. Это было очень полезно.

Это, по крайней мере, гораздо лучший ответ, чем текущий принятый / получивший наибольшее количество голосов. Это "только" нарушает доступность клавиатуры в IE, а не во всех хороших браузерах.

Bobby Jack 09.07.2009 15:28

... хотя, разве это не просто копия ответа Пьера?

Bobby Jack 09.07.2009 15:29

Согласен, это чуть менее читаемая версия Пьера, но оба селектора связаны за один вызов.

Tristan Warner-Smith 02.09.2009 17:53

Замените click на click keyup keypress, чтобы добавить поддержку клавиатуры.

aloisdg 21.11.2016 20:11

Проблема с использованием события 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 () для предотвращения проблем с доступностью (см. Комментарий Бобби ниже).

Это очень злой хакер, потому что он не позволяет вашим пользователям перемещаться с помощью клавиатуры, потому что фокус исчезает после выбора переключателя.

Philippe Leybaert 09.07.2009 15:35

Это здорово, но вызывает проблемы с доступностью клавиатуры. После срабатывания события blur () переключатель больше не фокусируется, поэтому перемещение между переключателями с помощью клавиатуры становится чрезвычайно неудобным. Мое текущее решение - добавить вызов this.focus (); сразу после оператора blur ().

Bobby Jack 09.07.2009 16:23

Я думаю, что это худшее из представленных решений из-за проблем с доступностью.

Philippe Leybaert 09.07.2009 16:35

Но проблему доступности можно решить с помощью вызова focus (). По крайней мере, это так же хорошо, как использовать click () для всего.

Bobby Jack 09.07.2009 17:06

Спасибо, Бобби, я добавлю это к ответу.

Mark A. Nicolosi 10.07.2009 05:08

У меня была эта проблема сегодня рано, и я собираюсь попробовать это завтра. Мне это кажется лучше, чем использовать "щелчок". Если бы я использовал «щелчок», я бы в основном сам реализовал событие «изменение». Спасибо IE за то, что потратил больше времени на работу вокруг вас.

delux247 17.02.2010 06:47

Это лучше, чем решение "щелчок".

Moe Sweet 04.08.2011 11:29

Вызов if ($ .browser.msie) больше не работает с jQuery 1.10

TheAlbear 08.10.2013 14:23

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

эго ... немного деспотичный, нет?

orip 18.08.2010 15:47

Вы пробовали событие IE onpropertychange? Не знаю, имеет ли это значение, но, наверное, стоит попробовать. IE не запускает событие изменения, когда значения обновляются с помощью JS-кода, но, возможно, в этом случае будет работать onpropertychange.

$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
  e.preventDefault(); // Your code here 
}); 

Похоже, что «щелкнуть» не сработало, а «изменение свойства» - сработало. Спасибо!

James Kingsbery 08.11.2010 19:59

Я пробовал это в IE8, это не работает. Это не входит в функцию.

ARUN 10.12.2014 11:39

У меня была такая же проблема с вводимым текстом.

Я изменился:

$("#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
});

http://code.jquery.com/jquery-1.5.1.min.js

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

(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 () {

});

Другие вопросы по теме