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!

Respostas:


96

Tente usar em .clickvez de .change.


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


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

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


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

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

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!


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

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

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

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



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

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

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

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)


0

Tente o seguinte:

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

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


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

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

});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.