Uruchamianie jQuery w celu rozpoznania .change () w IE

131

Używam jQuery do ukrywania i pokazywania elementów, gdy grupa przycisków opcji zostanie zmieniona / kliknięta. Działa dobrze w przeglądarkach takich jak Firefox, ale w IE 6 i 7 akcja ma miejsce tylko wtedy, gdy użytkownik kliknie gdzie indziej na stronie.

Mówiąc dokładniej, po załadowaniu strony wszystko wygląda dobrze. W przeglądarce Firefox, jeśli klikniesz przycisk opcji, jeden wiersz tabeli zostanie ukryty, a drugi zostanie natychmiast wyświetlony. Jednak w IE 6 i 7 klikasz przycisk opcji i nic się nie stanie, dopóki nie klikniesz gdzieś na stronie. Dopiero wtedy IE przerysowuje stronę, ukrywając i pokazując odpowiednie elementy.

Oto jQuery, którego używam:

$(document).ready(function () {
  $(".hiddenOnLoad").hide();

  $("#viewByOrg").change(function () {
    $(".visibleOnLoad").show();
    $(".hiddenOnLoad").hide();
  });

  $("#viewByProduct").change(function () {
    $(".visibleOnLoad").hide();
    $(".hiddenOnLoad").show();
  });
});

Oto część XHTML, na którą wpływa. Cała strona jest weryfikowana jako 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>

Jeśli ktoś ma jakieś pomysły, dlaczego tak się dzieje i jak to naprawić, byłby bardzo wdzięczny!

Philip Morton
źródło

Odpowiedzi:

96

Spróbuj użyć .clickzamiast .change.

Paolo Bergantino
źródło
3
@samjudson, w moich testach nie jest to poprawne i kliknięcie jquery jest wyzwalane, gdy wybieram następny przycisk opcji za pomocą klawiszy strzałek. (Vista, ie7)
svandragt
1
@Pacifika: Nie dla mnie w IE7. Przynajmniej ma rację. „kliknięcie” to zupełnie inne zdarzenie od „zmiany” i przynajmniej w niektórych przypadkach (jeśli nie we wszystkich) jest ono niewłaściwym zamiennikiem.
Bobby Jack,
3
@samjudson: zdarzenia kliknięć na przyciskach radiowych i pola wyboru również uruchamiają się podczas wybierania ich za pomocą klawiatury. Działa we wszystkich przeglądarkach
Philippe Leybaert
4
Stoję poprawiony - wydaje się, że tak jest, jakkolwiek mogłoby to być sprzeczne z intuicją!
Bobby Jack,
2
Wydaje się, że jest to najpopularniejsza odpowiedź na to pytanie, ale nie jest do końca poprawna! clickróżni się changetym, że jego eventhandler zostanie również wywołany po kliknięciu już wybranej opcji, a changenie. Ta odpowiedź zawiera przykład użycia jQuery .datado porównania starych i nowych wartości.
Laoujin
54

Problem z używaniem clickzdarzenia zamiast zdarzenia changepolega na tym, że otrzymujesz zdarzenie, jeśli wybrano to samo pole radiowe (tj. Nie zmieniło się). Można to odfiltrować, jeśli sprawdzisz, czy nowa wartość różni się od starej. Uważam to za trochę denerwujące.

Jeśli korzystasz z changewydarzenia, możesz zauważyć, że rozpozna ono zmianę po kliknięciu dowolnego innego elementu w IE. Jeśli zadzwonisz blur()do clickzdarzenia, spowoduje to uruchomienie changezdarzenia (tylko jeśli skrzynki radiowe faktycznie się zmieniły).

Oto jak to robię:

// This is the hack for IE
if ($.browser.msie) {
  $("#viewByOrg").click(function() {
    this.blur();
    this.focus();
  });
}

$("#viewByOrg").change(function() {
  // Do stuff here
});

Teraz możesz normalnie używać zdarzenia zmiany.

Edycja: Dodano wywołanie fokusa (), aby zapobiec problemom z dostępnością (zobacz komentarz Bobby'ego poniżej).

Mark A. Nicolosi
źródło
2
To bardzo zły hack, ponieważ uniemożliwia użytkownikom nawigację za pomocą klawiatury, ponieważ fokus znika po wybraniu przycisku opcji.
Philippe Leybaert
5
To jest świetne, ale powoduje problemy z dostępnością klawiatury. Po uruchomieniu zdarzenia blur () przycisk opcji nie jest już zogniskowany, więc poruszanie się między przyciskami radiowymi za pomocą klawiatury staje się niezwykle niewygodne. Moje obecne rozwiązanie polega na dodaniu wywołania do "this.focus ();" bezpośrednio po wyrażeniu blur ().
Bobby Jack,
1
Myślę, że jest to najgorsze przedstawione rozwiązanie ze względu na problemy z dostępnością.
Philippe Leybaert
11
Ale problem z dostępnością można rozwiązać za pomocą wywołania focus (). Jest co najmniej tak samo dobre, jak używanie do wszystkiego metody click ().
Bobby Jack,
Dzięki Bobby, dodam to do odpowiedzi.
Mark A. Nicolosi,
33

Czy próbowałeś zdarzenia onpropertychange w IE? Nie wiem, czy to robi różnicę, ale chyba warto spróbować. IE nie wyzwala zdarzenia zmiany, gdy wartości są aktualizowane za pomocą kodu JS, ale być może onpropertychange zadziała w tym przypadku.

$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
  e.preventDefault(); // Your code here 
}); 
Kevin
źródło
„kliknięcie” nie wydawało się działać, ale „właściwość zmiany” tak. Dzięki!
James Kingsbery
Próbowałem tego w IE8, ale nie działa. Nie pojawia się wewnątrz funkcji.
ARUN
14

To też powinno działać:

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

Dzięki, Pier. To było bardzo pomocne.


źródło
Jest to przynajmniej znacznie lepsza odpowiedź niż ta, która jest obecnie akceptowana / najwyżej głosowana. Łamie to „tylko” dostępność klawiatury pod IE, a nie we wszystkich dobrych przeglądarkach.
Bobby Jack,
... chociaż, czy to nie jest tylko kopia odpowiedzi Pier?
Bobby Jack,
Zgoda, jest to nieco mniej czytelna wersja Piers, ale z obiema selektorami związanymi w jednej rozmowie.
Tristan Warner-Smith
Wymień clicksię click keyup keypressdodać obsługę klawiatury.
aloisdg przenosi się na codidact.com
6

W IE musisz użyć zdarzenia kliknięcia, w innych przeglądarkach na zmianę. Twoja funkcja może się stać

$(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();
                    });     
});
Pier Luigi
źródło
Wymień clicksię click keyup keypressdodać obsługę klawiatury.
aloisdg przenosi się na codidact.com
6

dodaj tę wtyczkę

jQuery.fn.radioChange = function(newFn){
    this.bind(jQuery.browser.msie? "click" : "change", newFn);
}

następnie

$(function(){
    $("radioBtnSelector").radioChange(function(){
        //do stuff
    });
});
dovidweisz
źródło
4

Miałem ten sam problem z tekstem wejściowym.

Zmieniłam:

$("#myinput").change(function() { "alert('I changed')" });

do

$("#myinput").attr("onChange", "alert('I changed')");

i u mnie wszystko działa dobrze!

fabrice
źródło
2

Jest to prosty sposób na poinformowanie IE, aby uruchamiał zdarzenie zmiany po kliknięciu elementu:

if($.browser.msie) {
    $("#viewByOrg").click(function() {
        $(this).change();
    });
}

Możesz rozszerzyć to na coś bardziej ogólnego, aby pracować z większą liczbą elementów formularza:

if($.browser.msie) {
    $("input, select").click(function() {
        $(this).change();
    });
    $("input, textarea").keyup(function() {
        $(this).change();
    });
}
Paweł
źródło
1

Jestem prawie pewien, że jest to znany problem z IE. Dodanie modułu obsługi onclickzdarzenia powinno rozwiązać problem:

$(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();
    });     
});
Chris Zwiryk
źródło
1

W IE wymuś, aby radio i pola wyboru wywoływały zdarzenie „zmiana”:

if($.browser.msie && $.browser.version < 8)
  $('input[type=radio],[type=checkbox]').live('click', function(){
    $(this).trigger('change');
  });
Jeoff Wilks
źródło
1

od wersji 1.6 jQuery nie jest to już problem ... nie jestem pewien, kiedy został naprawiony ... Dzięki Bogu za to

Baz1nga
źródło
1

Jeśli zmienisz wersję jQuery na 1.5.1, nie będziesz musiał dostosowywać swojego kodu. W takim razie IE9 doskonale posłucha:

$(SELECTOR).change(function() {
    // Shizzle
});

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

Bas Matthee
źródło
1

sztuczka z kliknięciem działa ... ale jeśli chcesz uzyskać poprawny stan radia lub pole wyboru, możesz użyć tego:

(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
})
Bez przerwy
źródło
0

imo użycie kliknięcia zamiast zmiany powoduje, że zachowanie ie jest inne. Wolałbym raczej emulować zachowanie zdarzenia zmiany przy użyciu licznika czasu (setTimout).

coś takiego (ostrzeżenie - kod notatnika):

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
});
Ken Egozi
źródło
whoah ... trochę ciężkoręki, nie?
orip
0

spróbuj tego, to działa dla mnie

$("#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')});
RainChen
źródło
0

To może komuś pomóc: Zamiast zaczynać od identyfikatora formularza, wybierz identyfikator wyboru i prześlij formularz w przypadku zmiany, na przykład:

<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>

oraz jQuery:

$('#val').change(function(){
  $('#filterIt').submit();
});

(Oczywiście przycisk przesyłania jest opcjonalny, jeśli javascript jest wyłączony)

Jongosi
źródło
0

Spróbuj wykonać następujące czynności:

.bind($.browser.msie ? 'click' : 'change', function(event) {
Bilal Jalil
źródło
0

Unikaj używania .focus () lub .Wybrać () przed .change () funkcji jQuery dla IE, to działa dobrze, im go używać w moim miejscu.

Dzięki

muhammadanish
źródło
0
//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;
       });
}
Kijów
źródło
0

Spróbuj użyć każdego zamiast zmiany / kliknięcia , co działa dobrze nawet za pierwszym razem w IE, a także w innych przeglądarkach

Nie działa za pierwszym razem

$("#checkboxid").**change**(function () {

});

Działa dobrze nawet za pierwszym razem

$("#checkboxid").**each**(function () {

});
Dayanand Rupanavar
źródło