Wenn ich mit gespielt habe <input type="range">
, löst Firefox ein Onchange-Ereignis nur aus, wenn wir den Schieberegler an einer neuen Position ablegen, an der Chrome und andere Onchange-Ereignisse auslösen, während der Slider gezogen wird.
Wie kann ich dies beim Ziehen in Firefox erreichen?
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
feuert der nicht. Bei der Fehlerbehebung dieses Problems habe ich diese Frage gefunden.Antworten:
Anscheinend sind Chrome und Safari falsch:
onchange
sollten nur ausgelöst werden, wenn der Benutzer die Maus loslässt. Um fortlaufende Updates zu erhalten, sollten Sie dasoninput
Ereignis verwenden, mit dem Live-Updates in Firefox, Safari und Chrome sowohl über die Maus als auch über die Tastatur erfasst werden.Allerdings
oninput
wird nicht in IE10 unterstützt, so dass Sie am besten die beiden Event - Handler, wie diese zu kombinieren:Weitere Informationen finden Sie in diesem Bugzilla-Thread .
quelle
$("#myelement").on("input change", function() { doSomething(); });
mit jQuery.onchange()
nicht im mobilen Web wieAndroid Chrome
undiOS Safari
. Irgendein alternativer Vorschlag?ZUSAMMENFASSUNG:
Ich biete hier eine browserfreie Desktop- und Mobilfunktion ohne jQuery, um konsistent auf Interaktionen zwischen Bereich und Schieberegler zu reagieren, was in aktuellen Browsern nicht möglich ist. Es zwingt im Wesentlichen alle Browser, das IE11-
on("change"...
Ereignis entweder für ihreon("change"...
oder füron("input"...
Ereignisse zu emulieren . Die neue Funktion ist ...... wo
r
ist Ihr Bereichseingabeelement und wof
ist Ihr Listener? Der Listener wird nach jeder Interaktion aufgerufen, die den Bereich / Schiebereglerwert ändert, jedoch nicht nach Interaktionen, die diesen Wert nicht ändern, einschließlich anfänglicher Maus- oder Berührungsinteraktionen an der aktuellen Schiebereglerposition oder beim Verlassen eines Schiebereglers.Problem:
Ab Anfang Juni 2016 unterscheiden sich verschiedene Browser hinsichtlich ihrer Reaktion auf die Verwendung von Bereichen / Schiebereglern. Fünf Szenarien sind relevant:
Die folgende Tabelle zeigt, wie sich mindestens drei verschiedene Desktop-Browser in Bezug auf das oben genannte Szenario in ihrem Verhalten unterscheiden:
Lösung:
Die
onRangeChange
Funktion bietet eine konsistente und vorhersehbare browserübergreifende Reaktion auf Interaktionen zwischen Bereich und Schieberegler. Es zwingt alle Browser, sich gemäß der folgenden Tabelle zu verhalten:In IE11 erlaubt der Code im Wesentlichen, dass alles gemäß dem Status Quo
"change"
funktioniert , dh, dass das Ereignis auf seine Standardweise funktioniert und das"input"
Ereignis irrelevant ist, da es sowieso nie ausgelöst wird. In anderen Browsern wird das"change"
Ereignis effektiv stummgeschaltet (um zu verhindern, dass zusätzliche und manchmal nicht leicht erkennbare Ereignisse ausgelöst werden). Darüber hinaus löst das"input"
Ereignis seinen Listener nur aus, wenn sich der Wert des Bereichs / Schiebereglers ändert. Bei einigen Browsern (z. B. Firefox) tritt dies auf, weil der Listener in den Szenarien 1, 4 und 5 aus der obigen Liste effektiv stummgeschaltet ist.(Wenn Sie wirklich benötigen, dass ein Listener in Szenario 1, 4 und / oder 5 aktiviert wird, können Sie versuchen,
"mousedown"
/"touchstart"
,"mousemove"
/"touchmove"
und / oder"mouseup"
/"touchend"
Ereignisse einzubeziehen. Eine solche Lösung würde den Rahmen dieser Antwort sprengen.)Funktionalität in mobilen Browsern:
Ich habe diesen Code in Desktop-Browsern getestet, aber nicht in mobilen Browsern. In einer anderen Antwort auf dieser Seite hat MBourne jedoch gezeigt, dass meine Lösung hier "... in jedem Browser zu funktionieren scheint, den ich finden konnte (Win-Desktop: IE, Chrome, Opera, FF; Android Chrome, Opera und FF, iOS Safari). " . (Danke MBourne.)
Verwendung:
Um diese Lösung zu verwenden,
onRangeChange
fügen Sie die Funktion aus der obigen Zusammenfassung (vereinfacht / minimiert) oder das Demo-Code-Snippet unten (funktional identisch, aber selbsterklärender) in Ihren eigenen Code ein. Rufen Sie es wie folgt auf:Wo
myRangeInputElmt
ist Ihr gewünschtes<input type="range">
DOM-Element und welchemyListener
Listener / Handler-Funktion möchten Sie bei"change"
ähnlichen Ereignissen aufrufen ?Ihr Listener kann auf Wunsch parameterlos sein oder den
event
Parameter verwenden, dh je nach Ihren Anforderungen funktioniert eine der folgenden Möglichkeiten :oder
(Das Entfernen des Ereignis-Listeners aus dem
input
Element (z. B. Verwenden vonremoveEventListener
) wird in dieser Antwort nicht behandelt.)Demo Beschreibung:
Im folgenden Codeausschnitt bietet die Funktion
onRangeChange
die universelle Lösung. Der Rest des Codes ist lediglich ein Beispiel, um seine Verwendung zu demonstrieren. Jede Variable, die mit beginnt,my...
ist für die universelle Lösung irrelevant und nur für die Demo vorhanden.Die Demo zeigt den Bereich / Reglerwert sowie die Anzahl , wie oft den Standard
"change"
,"input"
und benutzerdefinierte"onRangeChange"
Ereignisse ausgelöst hat (Zeilen A, B und C jeweils). Beachten Sie beim Ausführen dieses Snippets in verschiedenen Browsern Folgendes, wenn Sie mit dem Bereich / Schieberegler interagieren:Demo-Code:
Anerkennung:
Während die Implementierung hier größtenteils meine eigene ist, wurde sie von MBournes Antwort inspiriert . Diese andere Antwort deutete darauf hin, dass die Ereignisse "Eingabe" und "Änderung" zusammengeführt werden könnten und der resultierende Code sowohl in Desktop- als auch in mobilen Browsern funktionieren würde. Der Code in dieser Antwort führt jedoch dazu, dass versteckte "zusätzliche" Ereignisse ausgelöst werden, was an und für sich problematisch ist, und die ausgelösten Ereignisse unterscheiden sich zwischen den Browsern, ein weiteres Problem. Meine Implementierung hier löst diese Probleme.
Schlüsselwörter:
Die Schiebereglerereignisse für den JavaScript-Eingabetyp ändern die Kompatibilität des Eingabebrowsers für browserübergreifende Desktop-Mobilgeräte ohne jQuery
quelle
Ich poste dies als Antwort, weil es verdient, eine eigene Antwort zu sein, anstatt einen Kommentar unter einer weniger nützlichen Antwort. Ich finde diese Methode viel besser als die akzeptierte Antwort, da sie alle js in einer vom HTML getrennten Datei speichern kann.
Antwort von Jamrelian in seinem Kommentar unter der akzeptierten Antwort.
Beachten Sie jedoch diesen Kommentar von Jaime
Wie in wird das Ereignis ausgelöst, wenn Sie die Maus nicht mehr bewegen, und dann erneut, wenn Sie die Maustaste loslassen.
Aktualisieren
In Bezug auf das
change
Ereignis und dasinput
Ereignis, bei denen die Funktionalität zweimal ausgelöst wird, ist dies so gut wie kein Problem.Wenn eine Funktion aktiviert ist
input
, ist es äußerst unwahrscheinlich, dass beim Auslösen deschange
Ereignisses ein Problem auftritt.input
Wird schnell ausgelöst, wenn Sie einen Schieberegler für die Bereichseingabe ziehen. Die Sorge um einen weiteren Funktionsaufruf, der am Ende ausgelöst wird, ist wie die Sorge um einen einzelnen Wassertropfen im Vergleich zum Ozean des Wassers, der dieinput
Ereignisse darstellt.Der Grund für die Aufnahme des
change
Ereignisses ist aus Gründen der Browserkompatibilität (hauptsächlich mit dem Internet Explorer).quelle
UPDATE: Ich lasse diese Antwort hier als Beispiel für die Verwendung von Mausereignissen zur Verwendung von Bereichs- / Schieberegler-Interaktionen in Desktop-Browsern (aber nicht in mobilen Browsern). Jetzt habe ich jedoch auch eine völlig andere und meiner Meinung nach bessere Antwort an anderer Stelle auf dieser Seite geschrieben, die einen anderen Ansatz verwendet, um eine browserübergreifende Desktop- und Mobillösung für dieses Problem bereitzustellen .
Ursprüngliche Antwort:
Zusammenfassung: Eine browserübergreifende, einfache JavaScript-Lösung (dh no-jQuery), mit der Eingabewerte für den Lesebereich ohne Verwendung
on('input'...
und / oderon('change'...
inkonsistent zwischen Browsern verwendet werden können.Ab heute (Ende Februar 2016) gibt es immer noch Browser-Inkonsistenzen, daher biete ich hier eine neue Problemumgehung an.
Das Problem: Bei Verwendung einer Bereichseingabe, dh eines Schiebereglers,
on('input'...
werden kontinuierlich aktualisierte Bereichswerte in Mac und Windows Firefox, Chrome und Opera sowie Mac Safari bereitgestellt, währendon('change'...
der Bereichswert nur beim Hochfahren mit der Maus gemeldet wird. Im Gegensatz dazu funktioniert Internet Explorer (v11)on('input'...
überhaupt nicht undon('change'...
wird kontinuierlich aktualisiert.Ich berichte hier über 2 Strategien, um in allen Browsern mit Vanilla JavaScript (dh ohne jQuery) identische kontinuierliche Wertewerte zu erhalten, indem die Ereignisse mousedown, mousemove und (möglicherweise) mouseup verwendet werden.
Strategie 1: Kürzer aber weniger effizient
Wenn Sie kürzeren Code gegenüber effizienterem Code bevorzugen, können Sie diese erste Lösung verwenden, die mousesdown und mousemove verwendet, jedoch nicht mouseup. Dadurch wird der Schieberegler nach Bedarf gelesen, aber während eines Mouseover-Ereignisses wird unnötig weiter ausgelöst, selbst wenn der Benutzer nicht geklickt hat und daher den Schieberegler nicht zieht. Es liest im Wesentlichen den Bereichswert sowohl nach "Mousedown" als auch während "Mousemove" -Ereignissen und verzögert jede Verwendung geringfügig
requestAnimationFrame
.Strategie 2: Länger aber effizienter
Wenn Sie effizienteren Code benötigen und eine längere Codelänge tolerieren können, können Sie die folgende Lösung verwenden, die Mousedown, Mousemove und Mouseup verwendet. Dadurch wird auch der Schieberegler nach Bedarf gelesen, der Lesevorgang wird jedoch entsprechend beendet, sobald die Maustaste losgelassen wird. Der wesentliche Unterschied besteht darin, dass erst nach "Mousedown" auf "Mousemove" gewartet wird und nach "Mouseup" nicht mehr auf "Mousemove" gewartet wird.
Demo: Ausführlichere Erklärung der Notwendigkeit und Implementierung der oben genannten Problemumgehungen
Der folgende Code veranschaulicht zahlreiche Aspekte dieser Strategie ausführlicher. Erklärungen sind in die Demonstration eingebettet:
Code-Snippet anzeigen
quelle
touchmove
sollte ausreichen, und ich denke, es kann genauso behandelt werden wiemousemove
in diesem Fall.Die Lösungen von Andrew Willem sind nicht mit Mobilgeräten kompatibel.
Hier ist eine Modifikation seiner zweiten Lösung, die in Edge, IE, Opera, FF, Chrome, iOS Safari und mobilen Entsprechungen funktioniert (die ich testen konnte):
Update 1: Der Teil "requestAnimationFrame" wurde entfernt, da ich damit einverstanden bin, dass dies nicht erforderlich ist:
Update 2: Antwort auf Andrews aktualisierte Antwort vom 2. Juni 2016:
Danke, Andrew - das scheint in jedem Browser zu funktionieren, den ich finden konnte (Win Desktop: IE, Chrome, Opera, FF; Android Chrome, Opera und FF, iOS Safari).
Update 3: if-Lösung ("oninput in slider")
Das Folgende scheint in allen oben genannten Browsern zu funktionieren. (Ich kann die Originalquelle jetzt nicht finden.) Ich habe diese verwendet, aber sie ist anschließend im IE fehlgeschlagen, und so habe ich nach einer anderen gesucht, daher bin ich hier gelandet.
Aber bevor ich Ihre Lösung überprüfte, bemerkte ich, dass dies im IE wieder funktionierte - vielleicht gab es einen anderen Konflikt.
quelle
Für ein gutes browserübergreifendes Verhalten und verständlichen Code verwenden Sie am besten das onchange-Attribut in Kombination mit einem Formular:
Das gleiche mit Eingang wird der Wert direkt geändert.
quelle
Noch ein anderer Ansatz - setzen Sie einfach ein Flag auf ein Element, das signalisiert, welche Art von Ereignis behandelt werden soll:
quelle
Sie können das JavaScript-Ereignis "ondrag" verwenden, um kontinuierlich zu feuern. Es ist aus folgenden Gründen besser als "Eingabe":
Browser-Unterstützung.
Könnte zwischen "ondrag" und "change" Ereignis unterscheiden. "Eingabe" wird sowohl zum Ziehen als auch zum Ändern ausgelöst.
In jQuery:
Referenz: http://www.w3schools.com/TAgs/ev_ondrag.asp
quelle