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.


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.


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

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


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

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