Obtendo o jQuery para reconhecer .change () no IE

131

Estou usando o jQuery para ocultar e mostrar elementos quando um grupo de botões de opção é alterado / clicado. Funciona bem em navegadores como o Firefox, mas no IE 6 e 7, a ação ocorre apenas quando o usuário clica em outro lugar da página.

Para elaborar, quando você carrega a página, tudo parece bem. No Firefox, se você clicar em um botão de opção, uma linha da tabela é ocultada e a outra é mostrada imediatamente. No entanto, no IE 6 e 7, você clica no botão de opção e nada acontecerá até clicar em algum lugar da página. Somente então o IE redesenha a página, ocultando e mostrando os elementos relevantes.

Aqui está o jQuery que estou usando:

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

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

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

Aqui está a parte do XHTML que ele afeta. A página inteira valida como 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>

Se alguém tiver alguma idéia de por que isso está acontecendo e como corrigi-lo, seria muito apreciado!

Philip Morton
fonte

Respostas:

96

Tente usar em .clickvez de .change.

Paolo Bergantino
fonte
3
@ samjudson, no meu teste, isso não está correto e o clique do jquery é acionado quando eu seleciono o próximo botão de opção usando as teclas de seta. (Vista, ie7)
svandragt
1
@ Pacifika: Não é para mim no IE7. Pelo menos está certo. "click" é um evento totalmente diferente de "change" e há pelo menos alguns casos (se não todos) em que é um substituto inadequado.
Bobby Jack
3
@samjudson: clique em eventos nos botões de opção e as caixas de seleção também são acionadas ao selecioná-las usando o teclado. Funciona em todos os navegadores
Philippe Leybaert
4
Estou corrigido - esse parece ser o caso, por mais contra-intuitivo que seja!
Bobby Jack
2
Essa parece ser a resposta mais popular para essa pergunta em particular, mas não está completamente correta! clickdifere de changeque seu manipulador de eventos também será chamado ao clicar na opção já selecionada, ao contrário de changenão. Esta resposta tem um exemplo de como usar o jQuery .datapara comparar os valores antigos e novos.
Laoujin
54

O problema de usar o clickevento em vez dechange é obter o evento se a mesma caixa de rádio estiver selecionada (ou seja, na verdade não mudou). Isso pode ser filtrado se você verificar se o novo valor é diferente do antigo. Acho isso um pouco chato.

Se você usar o changeevento, poderá perceber que ele reconhecerá a alteração depois que você clicar em qualquer outro elemento no IE. Se você ligar blur()para o clickevento, o changeevento será acionado (apenas se as caixas de rádio realmente tiverem sido alteradas).

Aqui está como eu estou fazendo isso:

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

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

Agora você pode usar o evento de alteração normalmente.

Editar: adicionada uma chamada para o focus () para evitar problemas de acessibilidade (consulte o comentário de Bobby abaixo).

Mark A. Nicolosi
fonte
2
Esse é um truque muito maléfico, porque impede que os usuários naveguem usando o teclado, porque o foco desaparece após a seleção de um botão de opção.
Philippe Leybaert 9/07/2009
5
Isso é ótimo, mas causa problemas de acessibilidade no teclado. Depois que o evento blur () é acionado, o botão de opção não fica mais focado; portanto, mover-se entre os botões de opção com o teclado torna-se extremamente estranho. Minha solução atual é adicionar uma chamada para "this.focus ();" imediatamente após a declaração blur ().
Bobby Jack
1
Eu acho que é a pior solução apresentada, devido aos problemas de acessibilidade.
Philippe Leybaert 9/07/2009
11
Mas o problema da acessibilidade pode ser resolvido com uma chamada para o foco (). É pelo menos tão bom quanto usar click () para tudo.
Bobby Jack
Obrigado Bobby, vou acrescentar isso à resposta.
Mark A. Nicolosi
33

Você já experimentou o evento onpropertychange do IE? Não sei se faz diferença, mas provavelmente vale a pena tentar. O IE não aciona o evento de alteração quando os valores são atualizados via código JS, mas talvez a alteração de propriedade funcione nessa instância.

$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
  e.preventDefault(); // Your code here 
}); 
Kevin
fonte
"click" não parecia funcionar, mas "propertychange" funcionou. Obrigado!
James Kingsbery
Eu tentei isso no IE8 não está funcionando. Não está chegando dentro da função.
ARUN
14

Isso deve funcionar também:

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

Obrigado Pier. Isso foi muito útil.


fonte
Essa é, pelo menos, uma resposta muito melhor do que a atual aceita / com o voto mais alto. Ele 'apenas' quebra a acessibilidade do teclado no IE, e não para todos os bons navegadores também.
Bobby Jack
... embora isso não seja apenas uma cópia da resposta de Pier?
Bobby Jack
Concordado, é uma versão ligeiramente menos legível do Pier, mas com os dois seletores sendo vinculados em uma chamada.
Tristan Warner-Smith
Substitua clickpor click keyup keypresspara adicionar suporte ao teclado.
aloisdg movendo-se para codidact.com 21/11
6

No IE, você deve usar o evento click, em outros navegadores, na troca. Sua função pode se tornar

$(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
fonte
Substitua clickpor click keyup keypresspara adicionar suporte ao teclado.
aloisdg movendo-se para codidact.com 21/11
6

adicione este plugin

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

então

$(function(){
    $("radioBtnSelector").radioChange(function(){
        //do stuff
    });
});
dovidweisz
fonte
4

Eu tive o mesmo problema com o texto de entrada.

Eu mudei:

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

para

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

e tudo está funcionando bem para mim!

fabrice
fonte
2

Esta é uma maneira simples de dizer ao IE para disparar o evento de alteração quando o elemento é clicado:

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

Você pode expandir isso para algo mais genérico para trabalhar com mais elementos de formulário:

if($.browser.msie) {
    $("input, select").click(function() {
        $(this).change();
    });
    $("input, textarea").keyup(function() {
        $(this).change();
    });
}
Paulo
fonte
1

Tenho certeza de que esse é um problema conhecido no IE. A adição de um manipulador para o onclickevento deve corrigir o problema:

$(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
fonte
1

No IE, force o rádio e as caixas de seleção para acionar um evento de "alteração":

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

a partir do jquery 1.6 isso não é mais um problema .. não tenho certeza de quando foi corrigido .. Graças a Deus por isso

Baz1nga
fonte
1

Se você alterar sua versão do jQuery para 1.5.1, não precisará ajustar seu código. Então o IE9 ouvirá perfeitamente:

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

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

Bas Matthee
fonte
1

o truque com o clique funciona ... mas se você deseja obter o estado correto do rádio ou da caixa de seleção, pode usar isso:

(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
})
não pare
fonte
0

imo usando clique em vez de alterar torna o comportamento ie diferente. Prefiro emular o comportamento do evento de alteração usando um timer (setTimout).

algo como (aviso - código do bloco de notas):

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
fonte
whoah ... um pouco pesado, não?
orip 18/08/10
0

tente isso, funciona para mim

$("#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
fonte
0

Isso pode ajudar alguém: em vez de começar com o ID do formulário, segmente o ID de seleção e envie o formulário com alterações, desta forma:

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

e o jQuery:

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

(Obviamente, o botão enviar é opcional, caso o javascript esteja desativado)

Jongosi
fonte
0

Tente o seguinte:

.bind($.browser.msie ? 'click' : 'change', function(event) {
Bilal Jalil
fonte
0

Evite usar a função .focus () ou .select () antes da função .change () do jquery para o IE, pois funciona bem, estou usando no meu site.

obrigado

muhammadanish
fonte
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;
       });
}
Kiev
fonte
0

Tente usar cada um em vez de alterar / clicar , o que está funcionando bem mesmo na primeira vez no IE e em outros navegadores

Não está trabalhando pela primeira vez

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

});

Trabalhando bem mesmo na primeira vez

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

});
Dayanand Rupanavar
fonte