Acione o evento change () ao definir o valor de <select> com a função val ()

132

Qual é a maneira mais fácil e melhor de acionar um evento de alteração ao definir o valor do elemento de seleção .

Eu esperava que a execução do código a seguir

$('select#some').val(10);

ou

$('select#some').attr('value',  10);

resultaria em desencadear o evento de mudança, que eu acho que é uma coisa bastante lógica a ser feita. Certo?

Bem, não é o caso. Você precisa alterar o evento change () fazendo isso

$('select#some').val(10).change();

ou

$('select#some').val(10).trigger('change');

mas estou procurando uma solução que desencadeie o evento de alteração assim que o valor do select for alterado por algum código javascript.

Goran Radulovic
fonte
javascript puro element.addEventListener?
Manuel Bitto
4
$ ('selecione # alguns'). val (10) .change (); é praticamente instantâneo para o usuário.
Dimitri
@ Manuel eu tentei isso. iv'e usou object.change = function (.... e object.addEventListener (... mas nenhum dos object.value, $ (object) .val () e $ (object) .attr ('value') acionaria esse ouvinte
Goran Radulovic

Respostas:

124

Eu tive um problema muito semelhante e não tenho muita certeza do que você está tendo um problema, pois o código sugerido funcionou muito bem para mim. Ele imediatamente (a exigência de seu) desencadeia o seguinte código mudança.

$('#selectField').change(function(){
    if($('#selectField').val() == 'N'){
        $('#secondaryInput').hide();
    } else {
        $('#secondaryInput').show();
}
});

Depois, pego o valor do banco de dados (usado em um formulário para entrada nova e edição de registros existentes), defino-o como o valor selecionado e adiciono a peça que estava faltando para acionar o código acima ".change () "

$('#selectField').val(valueFromDatabase).change();

Para que, se o valor existente no banco de dados for 'N', oculte imediatamente o campo de entrada secundário no meu formulário.

crítico
fonte
Isso é exatamente o que eu precisava. Qual é a melhor maneira de descobrir como acionar dinamicamente manipuladores de eventos DOM? O jQuery documenta isso bem? Obrigado!
Con Antonakos
2
$ ("# type_de_conto") .val (2) .trigger ('alteração');
Satanand Tiwari
$ ('# add_itp_spt_parent_id'). val (add_fpt_val) .trigger ('alteração'); $ ('# add_itp_spt_parent_id'). change (); ambas as soluções não estão funcionando.
Kamlesh
função de mudança definida ANTES de usar, resolveu meu problema. Obrigado.
Kamlesh
45

Uma coisa que eu descobri (da maneira mais difícil), é que você deveria ter

$('#selectField').change(function(){
  // some content ...
});

definido ANTES de usar

$('#selectField').val(10).trigger('change');

ou

 $('#selectField').val(10).change();
Dima R.
fonte
4
Post antigo, mas isso resolveu o meu problema, me salvou de uma longa quebra no cérebro ... Você deve definir o ouvinte antes de usá-lo. Mesmo em JavaScript puro.
Temitayo
Você pode elaborar um pouco? Não existe "change ()" por esse motivo?
Dima R.
Bem, vou dizer que talvez os ouvintes desse tipo não sejam içados no carregamento. No meu projeto, chamei o change()antes de definir o ouvinte e ele não funcionou até que eu movesse a change()chamada sob o ouvinte e funcionasse. Bem, vou dizer que isso não deve ser um problema, é apenas uma questão de como você estrutura seu código.
Temitayo
1
Era disso que eu precisava. Levei uma eternidade para resolver esse problema, obrigado.
Jamie M.
Bravo!!! "função de mudança definida ANTES de usar", resolveu meu problema. Obrigado querida.
precisa
17

A resposta direta já está em uma pergunta duplicada: Por que o evento jquery change não é acionado quando eu defino o valor de um select usando val ()?

Como você provavelmente sabe que definir o valor do select não aciona o evento change (), se você estiver procurando por um evento que é acionado quando o valor de um elemento foi alterado por JS, não existe um.

Se você realmente quer fazer isso, acho que a única maneira é escrever uma função que verifique o DOM em um intervalo e rastreie os valores alterados, mas definitivamente não faça isso a menos que você precise (não sei por que você precisaria)

Adicionada esta solução:
Outra solução possível seria criar sua própria .val()função de wrapper e fazer com que ele disparasse um evento personalizado depois de definir o valor .val(); quando você usar o wrapper .val () para definir o valor de, <select>ele disparará seu evento personalizado que você pode prender e manipular.

Certifique-se de return thisque ele possa ser encadeado em forma de jQuery

Clarence Liu
fonte
Eu li vários fóruns sobre esta questão e sua resposta foi a última conclusão que eu estava procurando. A idéia de rastrear funciona apenas como um experimento mental, obviamente seria totalmente impraticável, mas é ilustrativa; e a ideia do invólucro é incrível, e obrigado por apontar a parte "devolver isso". Saudações.
David L
Por que não $('select').val(value).change()funciona o tempo todo? Alguma explicação clara?
Istiaque Ahmed
2

Eu o separo e depois uso uma comparação de identidade para ditar o que será feito a seguir.

$("#selectField").change(function(){
  if(this.value === 'textValue1'){ $(".contentClass1").fadeIn(); }
  if(this.value === 'textValue2'){ $(".contentclass2").fadeIn(); }
});
Beaumont
fonte
2

Como o jQuery não acionará o evento de alteração nativo, mas somente o seu próprio evento de alteração. Se você vincular um evento sem jQuery e, em seguida, usar o jQuery para acioná-lo, os retornos de chamada vinculados não serão executados!

A solução é a seguinte (100% funcionando):

var sortBySelect = document.querySelector("select.your-class"); 
sortBySelect.value = "new value"; 
sortBySelect.dispatchEvent(new Event("change"));
Mohamed23gharbi
fonte