Lorsque je jouais avec <input type="range">
, Firefox déclenche un événement onchange uniquement si nous déposons le curseur dans une nouvelle position où Chrome et d'autres déclenchent des événements onchange pendant que le curseur est déplacé.
Comment puis-je y arriver en faisant glisser dans 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
ne se déclenche pas. C'est en résolvant ce problème que j'ai trouvé cette question.Réponses:
Apparemment, Chrome et Safari ont tort:
onchange
ne doivent être déclenchés que lorsque l'utilisateur relâche la souris. Pour obtenir des mises à jour continues, vous devez utiliser l'oninput
événement, qui capturera les mises à jour en direct dans Firefox, Safari et Chrome, à la fois à partir de la souris et du clavier.Cependant,
oninput
n'est pas pris en charge dans IE10, donc votre meilleur pari est de combiner les deux gestionnaires d'événements, comme ceci:Consultez ce fil Bugzilla pour plus d'informations.
la source
$("#myelement").on("input change", function() { doSomething(); });
avec jQuery.onchange()
ne fonctionne pas sur le Web mobile commeAndroid Chrome
etiOS Safari
. Une autre suggestion?RÉSUMÉ:
Je fournis ici une capacité de bureau et mobile multi-navigateur sans jQuery pour répondre de manière cohérente aux interactions plage / curseur, ce qui n'est pas possible dans les navigateurs actuels. Il oblige essentiellement tous les navigateurs à émuler l'
on("change"...
événement IE11 pour leuron("change"...
ou leurson("input"...
événements. La nouvelle fonction est ...... où
r
est votre élément d'entrée de plage etf
votre auditeur. L'auditeur sera appelé après toute interaction qui modifie la valeur de la plage / du curseur, mais pas après les interactions qui ne modifient pas cette valeur, y compris les interactions initiales de la souris ou du toucher à la position actuelle du curseur ou lors du déplacement de l'une ou l'autre extrémité du curseur.Problème:
Au début de juin 2016, les différents navigateurs diffèrent en termes de réponse à l'utilisation de la plage / du curseur. Cinq scénarios sont pertinents:
Le tableau suivant montre comment au moins trois navigateurs de bureau différents diffèrent dans leur comportement en ce qui concerne les scénarios ci-dessus auxquels ils répondent:
Solution:
La
onRangeChange
fonction fournit une réponse inter-navigateur cohérente et prévisible aux interactions plage / curseur. Il oblige tous les navigateurs à se comporter conformément au tableau suivant:Dans IE11, le code permet essentiellement à tout de fonctionner selon le statu quo, c'est-à-dire qu'il permet à l'
"change"
événement de fonctionner de manière standard et que l'"input"
événement n'a pas d'importance car il ne se déclenche jamais de toute façon. Dans d'autres navigateurs, l'"change"
événement est effectivement réduit au silence (pour empêcher le déclenchement d'événements supplémentaires et parfois non apparents). De plus, l'"input"
événement ne déclenche son écouteur que lorsque la valeur de la plage / du curseur change. Pour certains navigateurs (par exemple Firefox), cela se produit car l'auditeur est effectivement désactivé dans les scénarios 1, 4 et 5 de la liste ci-dessus.(Si vous avez vraiment besoin qu'un écouteur soit activé dans les scénarios 1, 4 et / ou 5, vous pouvez essayer d'incorporer les événements
"mousedown"
/"touchstart"
,"mousemove"
/"touchmove"
et / ou"mouseup"
/"touchend"
. Une telle solution dépasse le cadre de cette réponse.)Fonctionnalité dans les navigateurs mobiles:
J'ai testé ce code dans les navigateurs de bureau mais pas dans les navigateurs mobiles. Cependant, dans une autre réponse sur cette page, MBourne a montré que ma solution ici "... semble fonctionner dans tous les navigateurs que j'ai pu trouver (bureau Win: IE, Chrome, Opera, FF; Android Chrome, Opera et FF, iOS Safari) " . (Merci MBourne.)
Usage:
Pour utiliser cette solution, incluez la
onRangeChange
fonction du résumé ci-dessus (simplifiée / minifiée) ou l'extrait de code de démonstration ci-dessous (fonctionnellement identique mais plus explicite) dans votre propre code. Appelez-le comme suit:où
myRangeInputElmt
est votre<input type="range">
élément DOM souhaité etmyListener
est la fonction d'écoute / gestionnaire que vous souhaitez invoquer lors d'"change"
événements similaires.Votre auditeur peut être sans paramètre si vous le souhaitez ou peut utiliser le
event
paramètre, c'est-à-dire que l'un des éléments suivants fonctionnerait, selon vos besoins:ou
(La suppression de l'écouteur d'événements de l'
input
élément (par exemple en utilisantremoveEventListener
) n'est pas traitée dans cette réponse.)Description de la démonstration:
Dans l'extrait de code ci-dessous, la fonction
onRangeChange
fournit la solution universelle. Le reste du code est simplement un exemple pour démontrer son utilisation. Toute variable qui commence parmy...
n'est pas pertinente pour la solution universelle et n'est présente que pour la démonstration.La démonstration montre la plage / valeur du curseur ainsi que le nombre de fois la norme
"change"
,"input"
et sur mesure des"onRangeChange"
événements ont tiré (lignes A, B et C respectivement). Lorsque vous exécutez cet extrait dans différents navigateurs, notez les points suivants lorsque vous interagissez avec la plage / le curseur:Code de démonstration:
Crédit:
Bien que l'implémentation ici soit largement la mienne, elle a été inspirée par la réponse de MBourne . Cette autre réponse suggérait que les événements «entrée» et «changement» pouvaient être fusionnés et que le code résultant fonctionnerait à la fois sur les navigateurs de bureau et mobiles. Cependant, le code dans cette réponse entraîne le déclenchement d'événements "supplémentaires" cachés, ce qui en soi est problématique, et les événements déclenchés diffèrent entre les navigateurs, un autre problème. Ma mise en œuvre ici résout ces problèmes.
Mots clés:
Événements du curseur de plage de type d'entrée JavaScript changer la compatibilité du navigateur d'entrée cross-browser desktop mobile no-jQuery
la source
Je poste cela comme une réponse, car il mérite d'être sa propre réponse plutôt qu'un commentaire sous une réponse moins utile. Je trouve cette méthode bien meilleure que la réponse acceptée car elle peut conserver tous les js dans un fichier séparé du HTML.
Réponse donnée par Jamrelian dans son commentaire sous la réponse acceptée.
Mais soyez conscient de ce commentaire de Jaime
Comme dans, il déclenchera l'événement lorsque vous aurez arrêté de déplacer la souris, puis à nouveau lorsque vous relâcherez le bouton de la souris.
Mettre à jour
En ce qui concerne l'
change
événement et l'input
événement provoquant le déclenchement de la fonctionnalité deux fois, il s'agit à peu près d'un problème.Si une fonction est activée
input
, il est extrêmement peu probable qu'il y ait un problème lorsque l'change
événement se déclenche.input
se déclenche rapidement lorsque vous faites glisser un curseur d'entrée de plage. S'inquiéter d'un appel de fonction supplémentaire à la fin, c'est comme s'inquiéter d'une seule goutte d'eau par rapport à l'océan d'eau qui est lesinput
événements.La raison de même d'inclure l'
change
événement est pour la compatibilité du navigateur (principalement avec IE).la source
MISE À JOUR: Je laisse cette réponse ici comme un exemple de la façon d'utiliser les événements de souris pour utiliser les interactions plage / curseur dans les navigateurs de bureau (mais pas mobiles). Cependant, j'ai également écrit une réponse complètement différente et, je crois, meilleure ailleurs dans cette page qui utilise une approche différente pour fournir une solution de bureau et mobile multi-navigateur à ce problème.
Réponse originale:
Résumé: Une solution JavaScript multi-navigateur simple (c'est-à-dire no-jQuery) pour permettre la lecture des valeurs d'entrée de plage sans utiliser
on('input'...
et / ouon('change'...
qui fonctionnent de manière incohérente entre les navigateurs.À ce jour (fin février 2016), il y a toujours une incohérence du navigateur, donc je propose une nouvelle solution ici.
Le problème: lorsque vous utilisez une entrée de plage, c'est-à-dire un curseur,
on('input'...
fournit des valeurs de plage mises à jour en continu dans Mac et Windows Firefox, Chrome et Opera ainsi que Mac Safari, tout enon('change'...
ne signalant la valeur de la plage qu'à la souris. En revanche, dans Internet Explorer (v11),on('input'...
ne fonctionne pas du tout eton('change'...
est continuellement mis à jour.Je rapporte ici 2 stratégies pour obtenir des rapports de valeurs de plage continue identiques dans tous les navigateurs utilisant JavaScript vanille (c'est-à-dire sans jQuery) en utilisant les événements mousedown, mousemove et (éventuellement) mouseup.
Stratégie 1: plus courte mais moins efficace
Si vous préférez un code plus court à un code plus efficace, vous pouvez utiliser cette 1ère solution qui utilise mousesdown et mousemove mais pas mouseup. Cela lit le curseur selon les besoins, mais continue de tirer inutilement pendant les événements de survol, même lorsque l'utilisateur n'a pas cliqué et ne fait donc pas glisser le curseur. Il lit essentiellement la valeur de la plage à la fois après «mousedown» et pendant les événements «mousemove», retardant légèrement chaque utilisation
requestAnimationFrame
.Stratégie 2: plus longue mais plus efficace
Si vous avez besoin d'un code plus efficace et pouvez tolérer une longueur de code plus longue, vous pouvez utiliser la solution suivante qui utilise mousedown, mousemove et mouseup. Cela lit également le curseur selon les besoins, mais arrête correctement sa lecture dès que le bouton de la souris est relâché. La différence essentielle est qu'il ne commence à écouter «mousemove» qu'après «mousedown», et qu'il arrête d'écouter «mousemove» après «mouseup».
Démo: Explication plus complète de la nécessité et de la mise en œuvre des solutions de contournement ci-dessus
Le code suivant illustre plus en détail de nombreux aspects de cette stratégie. Des explications sont intégrées dans la démonstration:
Afficher l'extrait de code
la source
touchmove
devrait être suffisant, et je pense qu'il peut être traité commemousemove
dans ce cas.Les solutions d'Andrew Willem ne sont pas compatibles avec les appareils mobiles.
Voici une modification de sa deuxième solution qui fonctionne dans Edge, IE, Opera, FF, Chrome, iOS Safari et équivalents mobiles (que j'ai pu tester):
Mise à jour 1: Suppression de la partie "requestAnimationFrame", car je reconnais que ce n'est pas nécessaire:
Mise à jour 2: réponse à la réponse mise à jour du 2 juin 2016 d'Andrew:
Merci, Andrew - cela semble fonctionner dans tous les navigateurs que j'ai pu trouver (bureau Win: IE, Chrome, Opera, FF; Android Chrome, Opera et FF, iOS Safari).
Mise à jour 3: solution if ("oninput in slider)
Les éléments suivants semblent fonctionner sur tous les navigateurs ci-dessus. (Je ne trouve pas la source d'origine maintenant.) J'utilisais cela, mais cela a échoué par la suite sur IE et j'ai donc cherché une autre, donc je me suis retrouvé ici.
Mais avant de vérifier votre solution, j'ai remarqué que cela fonctionnait à nouveau dans IE - il y avait peut-être un autre conflit.
la source
Pour un bon comportement entre navigateurs et un code compréhensible, le mieux est d'utiliser l'attribut onchange en combinaison d'un formulaire:
De même en utilisant oninput , la valeur est modifiée directement.
la source
Encore une autre approche - il suffit de définir un indicateur sur un élément pour signaler le type d'événement à gérer:
la source
Vous pouvez utiliser l'événement JavaScript "ondrag" pour tirer en continu. C'est mieux que "entrée" pour les raisons suivantes:
Prise en charge du navigateur.
Pourrait faire la différence entre l'événement «ondrag» et l'événement «change». "input" se déclenche à la fois par glisser-déplacer.
Dans jQuery:
Référence: http://www.w3schools.com/TAgs/ev_ondrag.asp
la source