JQuery проблема с событием изменения и IE8 - PullRequest
5 голосов
/ 17 июня 2010

В jQuery 1.4.2 есть ошибка, из-за которой событие change для элемента select срабатывает дважды при использовании DOM-события и события jQuery, и это только в IE7 / 8.Вот тестовый код:

<html>

<head>
    <script src="http://code.jquery.com/jquery-1.4.2.js" type="text/javascript"></script>

    <script type="text/javascript">

       jQuery(document).ready(function() {

         jQuery(".myDropDown").change(function() {


         });

       });

    </script>

</head>

<body>
    <select class="myDropDown" onchange="alert('hello');">
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
        </select>
</body>

</html>

Обновление : еще один взгляд на проблему, на самом деле это реальная проблема, с которой мы столкнулись в нашем приложении.Привязка события прямого изменения к селектору, который даже не касается элемента select с DOM-событием, также вызывает двойное срабатывание.

<html>

<head>
    <script src="http://code.jquery.com/jquery-1.4.2.js" type="text/javascript"></script>

    <script type="text/javascript">

       jQuery(document).ready(function() {

         jQuery(".someSelectThatDoesNotExist").live("change", function() {


         });

       });

    </script>

</head>

<body>
    <select class="myDropDown" onchange="alert('hello');">
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
        </select>
</body>

</html>

Билет на фактическую ошибку: http://dev.jquery.com/ticket/6593

Это вызывает у нас много проблем в нашем приложении, потому что мы используем оба ASP.NET-события, смешанные с jQuery, и как только вы подключаете событие изменения к любому элементу, каждый выбор (выпадающий список) получает эту проблему двойного срабатывания.Есть ли кто-нибудь, кто знает способ обойти это, пока эта проблема не будет исправлена?

Ответы [ 5 ]

2 голосов
/ 10 ноября 2011

Я не хочу поднимать этот вопрос из мертвых, но jquery, наконец, исправил эту ошибку в версии 1.7, которая была недавно выпущена.

1 голос
/ 25 апреля 2012

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

if ($.browser.msie && (parseInt($.browser.version, 10) == 8 || parseInt($.browser.version, 10) == 7)) {
    var btn2 = $(btn).clone();
    $(btn).after(btn2);
    $(btn).remove();
    $(btn2).bind("click", function () {
        //your function here
    });
}
1 голос
/ 17 июня 2010

Я поэкспериментировал с ошибкой, и очевидного обходного пути не существует. В моем тестировании я обнаружил, что второе событие изменения инициируется jQuery, поэтому мне удалось собрать быстрое решение, которое включает удаление обработчика события DOM 0 и применение его снова к таймеру, который выполняется сразу после завершения потока:

     jQuery(".myDropDown").change(function() {
         if ($.browser.msie) {
             var dd = $(this)[0], 
                 oc = dd.onchange;
             dd.onchange = null;
             window.setTimeout(function () {
               dd.onchange = oc;
             }, 0);
          }
     });

Это нормально работает в IE8, появляется только одно предупреждение, хотя вы можете добавить туда проверку IE. Или нет, это, вероятно, не будет иметь значения Это определенно нуждается в этой проверке, и я добавил ее к образцу. Вот моя скрипка .

Единственное другое решение - удалить обработчик DOM 0 и использовать только обработчик jQuery.

0 голосов
/ 08 июля 2011

Мы на самом деле решаем проблему другим способом, поскольку это характерно для IE, ASP.NET и элемента select, мы используем следующий код:

$(function () {
if ($.browser.msie) {
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_pageLoaded(function() {
        $('select[onchange]:not(.iefixed)')
            .addClass('iefixed')
            .each(function () {
                var self = $(this), dd = self[0], action = self.attr('onchange');
                self.removeAttr('onchange').change(action);
                dd.onpropertychange = function() { dd.blur(); };
            });
    });
}
});
  1. Убедитесь, что исправление применяется только к элементу select, для которого autopostback установлен в true (onchange) один раз.
  2. По сути, мы полагаемся на jQuery для запуска события change для нас, но для того, чтобы IE сделал это, нам нужно вызвать событие blur элемента, когда происходит onpropertychange.
0 голосов
/ 17 июня 2010

как то так?

jQuery(".myDropDown").removeAttr('onchange').change(function() {

 alert(0);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...