Quando brinquei <input type="range">
, o Firefox dispara um evento de troca apenas se colocarmos o controle deslizante em uma nova posição em que o Chrome e outros acionam eventos de troca enquanto o controle deslizante é arrastado.
Como posso fazer isso arrastando no Firefox?
function showVal(newVal){
document.getElementById("valBox").innerHTML=newVal;
}
<span id="valBox"></span>
<input type="range" min="5" max="10" step="1" onchange="showVal(this.value)">
onchange
não dispara. Foi na solução desse problema que encontrei esta pergunta.Respostas:
Aparentemente, o Chrome e o Safari estão errados:
onchange
só devem ser acionados quando o usuário soltar o mouse. Para obter atualizações contínuas, você deve usar ooninput
evento, que irá capturar atualizações ao vivo no Firefox, Safari e Chrome, tanto do mouse quanto do teclado.No entanto,
oninput
não é suportado no IE10, portanto, sua melhor aposta é combinar os dois manipuladores de eventos, assim:Confira este tópico do Bugzilla para obter mais informações.
fonte
$("#myelement").on("input change", function() { doSomething(); });
com jQuery.onchange()
não funciona na Web móvel comoAndroid Chrome
eiOS Safari
. Alguma sugestão alternativa?RESUMO:
Fornecemos aqui a capacidade de desktop e celular no navegador sem jQuery para responder consistentemente a interações de intervalo / controle deslizante, algo que não é possível nos navegadores atuais. É essencialmente obriga todos os navegadores para emular do IE11
on("change"...
evento, quer para os seuson("change"...
ouon("input"...
eventos. A nova função é ...... onde
r
está seu elemento de entrada de intervalo ef
é seu ouvinte. O ouvinte será chamado após qualquer interação que altere o valor do intervalo / controle deslizante, mas não após as interações que não alteram esse valor, incluindo as interações iniciais do mouse ou toque na posição atual do controle deslizante ou ao sair de qualquer extremidade do controle deslizante.Problema:
No início de junho de 2016, diferentes navegadores diferem em termos de como eles respondem ao uso do intervalo / controle deslizante. Cinco cenários são relevantes:
A tabela a seguir mostra como pelo menos três navegadores de desktop diferentes diferem em seu comportamento em relação a quais dos cenários acima eles respondem:
Solução:
A
onRangeChange
função fornece uma resposta consistente e previsível entre navegadores às interações de intervalo / controle deslizante. Força todos os navegadores a se comportarem de acordo com a tabela a seguir:No IE11, o código essencialmente permite que tudo opere conforme o status quo, ou seja, permite que o
"change"
evento funcione da maneira padrão e o"input"
evento é irrelevante, pois nunca é acionado. Em outros navegadores, o"change"
evento é efetivamente silenciado (para impedir que eventos extras e às vezes não-aparentes sejam disparados). Além disso, o"input"
evento aciona seu ouvinte apenas quando o valor do intervalo / controle deslizante é alterado. Para alguns navegadores (por exemplo, Firefox), isso ocorre porque o ouvinte é efetivamente silenciado nos cenários 1, 4 e 5 da lista acima.(Se você realmente deseja que um ouvinte seja ativado nos cenários 1, 4 e / ou 5, tente incorporar
"mousedown"
/"touchstart"
,"mousemove"
/"touchmove"
e / ou"mouseup"
/"touchend"
eventos. Essa solução está além do escopo desta resposta.)Funcionalidade em navegadores móveis:
Testei esse código em navegadores de desktop, mas não em navegadores móveis. No entanto, em outra resposta desta página, o MBourne mostrou que minha solução aqui "... parece funcionar em todos os navegadores que eu encontrei (Win desktop: IE, Chrome, Opera, FF; Android Chrome, Opera e FF, iOS Safari) " . (Obrigado MBourne.)
Uso:
Para usar esta solução, inclua a
onRangeChange
função do resumo acima (simplificado / minificado) ou o trecho de código de demonstração abaixo (funcionalmente idêntico, mas mais auto-explicativo) em seu próprio código. Chame da seguinte maneira:onde
myRangeInputElmt
está o<input type="range">
elemento DOM desejado emyListener
é a função de ouvinte / manipulador que você deseja chamar em"change"
eventos semelhantes.Seu ouvinte pode ter menos parâmetros, se desejado, ou pode usar o
event
parâmetro, ou seja, qualquer um dos seguintes procedimentos funcionará, dependendo de suas necessidades:ou
(Remover o ouvinte de evento do
input
elemento (por exemplo, usarremoveEventListener
) não é abordado nesta resposta.)Descrição da demonstração:
No trecho de código abaixo, a função
onRangeChange
fornece a solução universal. O restante do código é simplesmente um exemplo para demonstrar seu uso. Qualquer variável que comece commy...
é irrelevante para a solução universal e está presente apenas para fins de demonstração.Os shows de demonstração do valor / intervalo de controle deslizante, bem como o número de vezes que o padrão
"change"
,"input"
e personalizados"onRangeChange"
eventos têm disparados (linhas A, B e C, respectivamente). Ao executar esse snippet em diferentes navegadores, observe o seguinte ao interagir com o intervalo / controle deslizante:Código de demonstração:
Crédito:
Embora a implementação aqui seja em grande parte minha, foi inspirada na resposta de MBourne . Essa outra resposta sugeriu que os eventos "input" e "change" pudessem ser mesclados e que o código resultante funcionaria nos navegadores de desktop e móvel. No entanto, o código nessa resposta resulta no acionamento de eventos "extras" ocultos, o que por si só é problemático e os eventos acionados diferem entre os navegadores, um problema adicional. Minha implementação aqui resolve esses problemas.
Palavras-chave:
Eventos de controle deslizante de intervalo do tipo de entrada JavaScript alteram a compatibilidade do navegador de entrada desktop no navegador móvel no-jQuery
fonte
Estou postando isso como uma resposta, porque merece ser sua própria resposta, em vez de um comentário em uma resposta menos útil. Acho esse método muito melhor do que a resposta aceita, pois pode manter todos os js em um arquivo separado do HTML.
Resposta fornecida por Jamrelian em seu comentário sob a resposta aceita.
Apenas esteja ciente deste comentário de Jaime
Como ele disparará o evento quando você parar de mover o mouse e, novamente, quando você soltar o botão do mouse.
Atualizar
Em relação ao
change
evento e aoinput
evento que causou o acionamento da funcionalidade duas vezes, isso é praticamente um problema.Se você tiver uma função ativando
input
, é extremamente improvável que haja um problema quando ochange
evento for disparado.input
dispara rapidamente quando você arrasta um controle deslizante de entrada de alcance. Preocupar-se com mais um disparo de chamada de função no final é como se preocupar com uma única gota de água em comparação com o oceano de água que é oinput
evento.O motivo de incluir o
change
evento mesmo é por uma questão de compatibilidade do navegador (principalmente com o IE).fonte
ATUALIZAÇÃO: Estou deixando esta resposta aqui como um exemplo de como usar eventos de mouse para usar interações de intervalo / controle deslizante em navegadores de desktop (mas não em dispositivos móveis). No entanto, agora também escrevi uma resposta completamente diferente e, acredito, melhor em outras partes desta página que usa uma abordagem diferente para fornecer uma solução de desktop e móvel em vários navegadores para esse problema.
Resposta original:
Resumo: Uma solução JavaScript simples para vários navegadores (isto é, no-jQuery) para permitir a leitura dos valores de entrada do intervalo sem usar
on('input'...
e / ouon('change'...
que funcionam inconsistentemente entre navegadores.A partir de hoje (final de fevereiro de 2016), ainda há inconsistência no navegador, portanto estou fornecendo uma nova solução alternativa aqui.
O problema: ao usar uma entrada de intervalo, ou seja, um controle deslizante,
on('input'...
fornece valores de intervalo atualizados continuamente no Mac e Windows Firefox, Chrome e Opera, bem como no Mac Safari, enquantoon('change'...
apenas informa o valor do intervalo após o mouse. Por outro lado, no Internet Explorer (v11),on('input'...
não funciona eon('change'...
é atualizado continuamente.Relato aqui duas estratégias para obter relatórios de valores de faixa contínua idênticos em todos os navegadores usando JavaScript vanilla (isto é, sem jQuery) usando os eventos mousedown, mousemove e (possivelmente) mouseup.
Estratégia 1: Mais curta, mas menos eficiente
Se você preferir um código mais curto do que um código mais eficiente, poderá usar esta primeira solução que usa mousesdown e mousemove, mas não mouseup. Isso lê o controle deslizante conforme necessário, mas continua disparando desnecessariamente durante eventos de mouse-over, mesmo quando o usuário não clicou e, portanto, não está arrastando o controle deslizante. Ele basicamente lê o valor do intervalo depois dos eventos 'mousedown' e durante 'mousemove', atrasando levemente cada uso
requestAnimationFrame
.Estratégia 2: Mais longa, mas mais eficiente
Se você precisar de um código mais eficiente e puder tolerar um tamanho maior, poderá usar a solução a seguir, que usa redução de mouse, remoção de mouse e mouse. Isso também lê o controle deslizante, conforme necessário, mas interrompe-o adequadamente assim que o botão do mouse é liberado. A diferença essencial é que isso só começa a ouvir 'mousemove' após 'mousedown' e para de ouvir 'mousemove' após 'mouseup'.
Demonstração: explicação mais completa da necessidade e implementação das soluções alternativas acima
O código a seguir demonstra mais detalhadamente vários aspectos dessa estratégia. As explicações são incorporadas na demonstração:
Mostrar snippet de código
fonte
touchmove
deve ser suficiente e acho que pode ser tratado comomousemove
neste caso.As soluções de Andrew Willem não são compatíveis com dispositivos móveis.
Aqui está uma modificação de sua segunda solução que funciona no Edge, IE, Opera, FF, Chrome, iOS Safari e equivalentes móveis (que eu poderia testar):
Atualização 1: Remoção da parte "requestAnimationFrame", pois concordo que não é necessário:
Atualização 2: resposta à resposta atualizada de 2 de junho de 2016 de Andrew:
Obrigado, Andrew - que parece funcionar em todos os navegadores que pude encontrar (Win desktop: IE, Chrome, Opera, FF; Android Chrome, Opera e FF, iOS Safari).
Atualização 3: solução if ("oninput in slider)
O seguinte parece funcionar em todos os navegadores acima. (Não consigo encontrar a fonte original agora.) Eu estava usando isso, mas posteriormente falhou no IE e, portanto, procurei uma fonte diferente, portanto acabei aqui.
Porém, antes de verificar sua solução, notei que isso estava funcionando novamente no IE - talvez houvesse algum outro conflito.
fonte
Para um bom comportamento entre navegadores e código compreensível, o melhor é usar o atributo onchange na combinação de um formulário:
O mesmo usando oninput , o valor é alterado diretamente.
fonte
Ainda outra abordagem - basta definir um sinalizador em um elemento sinalizando que tipo de evento deve ser tratado:
fonte
Você pode usar o evento "ondrag" do JavaScript para disparar continuamente. É melhor que "input" devido aos seguintes motivos:
Suporte ao navegador.
Pode diferenciar entre o evento "ondrag" e "change". "input" é acionado para arrastar e alterar.
No jQuery:
Referência: http://www.w3schools.com/TAgs/ev_ondrag.asp
fonte