Cuando jugué con <input type="range">
, Firefox activa un evento de cambio solo si colocamos el control deslizante en una nueva posición donde Chrome y otros activan eventos de cambio mientras se arrastra el control deslizante.
¿Cómo puedo hacer que suceda arrastrando en 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
no dispara. Fue en la solución de problemas que encontré esta pregunta.Respuestas:
Aparentemente, Chrome y Safari están equivocados:
onchange
solo deberían activarse cuando el usuario suelta el mouse. Para obtener actualizaciones continuas, debe usar eloninput
evento, que capturará actualizaciones en vivo en Firefox, Safari y Chrome, tanto desde el mouse como desde el teclado.Sin embargo,
oninput
no es compatible con IE10, por lo que su mejor opción es combinar los dos controladores de eventos, de esta manera:Mira este hilo de Bugzilla para más información.
fuente
$("#myelement").on("input change", function() { doSomething(); });
con jQuery.onchange()
no funciona en la web móvil comoAndroid Chrome
yiOS Safari
. ¿Alguna sugerencia alternativa?RESUMEN:
Proporciono aquí una capacidad de escritorio y móvil de navegador cruzado sin jQuery para responder consistentemente a las interacciones de rango / control deslizante, algo que no es posible en los navegadores actuales. Básicamente obliga a todos los navegadores a emular el
on("change"...
evento de IE11 para sus eventoson("change"...
o para elloson("input"...
. La nueva función es ...... donde
r
está su elemento de entrada de rango yf
es su oyente. Se llamará al oyente después de cualquier interacción que cambie el valor del rango / control deslizante, pero no después de las interacciones que no cambian ese valor, incluidas las interacciones iniciales con el mouse o el toque en la posición actual del control deslizante o al salir de cualquier extremo del control deslizante.Problema:
A principios de junio de 2016, los diferentes navegadores difieren en términos de cómo responden al uso del rango / control deslizante. Cinco escenarios son relevantes:
La siguiente tabla muestra cómo al menos tres navegadores de escritorio diferentes difieren en su comportamiento con respecto a cuál de los escenarios anteriores responden:
Solución:
La
onRangeChange
función proporciona una respuesta coherente y predecible entre navegadores a las interacciones de rango / control deslizante. Obliga a todos los navegadores a comportarse de acuerdo con la siguiente tabla:En IE11, el código esencialmente permite que todo funcione según el status quo, es decir, permite que el
"change"
evento funcione de la manera estándar y el"input"
evento es irrelevante ya que nunca se dispara de todos modos. En otros navegadores, el"change"
evento se silencia efectivamente (para evitar que se disparen eventos adicionales y, a veces, no aparentes). Además, el"input"
evento activa su escucha solo cuando cambia el valor del rango / control deslizante. Para algunos navegadores (por ejemplo, Firefox) esto ocurre porque el oyente está silenciado efectivamente en los escenarios 1, 4 y 5 de la lista anterior.(Si realmente necesita que se active un oyente en los escenarios 1, 4 y / o 5, puede intentar incorporar
"mousedown"
/"touchstart"
,"mousemove"
/"touchmove"
y / o"mouseup"
/"touchend"
eventos. Tal solución está más allá del alcance de esta respuesta).Funcionalidad en navegadores móviles:
He probado este código en navegadores de escritorio pero no en ningún navegador móvil. Sin embargo, en otra respuesta en esta página, MBourne ha demostrado que mi solución aquí "... parece funcionar en todos los navegadores que pude encontrar (escritorio de Win: IE, Chrome, Opera, FF; Android Chrome, Opera y FF, iOS Safari) " . (Gracias MBourne)
Uso:
Para usar esta solución, incluya la
onRangeChange
función del resumen anterior (simplificado / minimizado) o el fragmento de código de demostración a continuación (funcionalmente idéntico pero más explicativo) en su propio código. Invocarlo de la siguiente manera:donde
myRangeInputElmt
está el<input type="range">
elemento DOM deseado ymyListener
es la función de escucha / controlador que desea invocar en"change"
eventos similares.Su oyente puede no tener parámetros si lo desea o puede usar el
event
parámetro, es decir, cualquiera de los siguientes funcionaría, dependiendo de sus necesidades:o
(La eliminación del detector de eventos del
input
elemento (p. Ej., El usoremoveEventListener
) no se aborda en esta respuesta).Descripción de demostración:
En el fragmento de código a continuación, la función
onRangeChange
proporciona la solución universal. El resto del código es simplemente un ejemplo para demostrar su uso. Cualquier variable que comiencemy...
es irrelevante para la solución universal y solo está presente por el bien de la demostración.Los espectáculos de demostración el valor de rango / deslizante, así como el número de veces que el estándar
"change"
,"input"
y la costumbre"onRangeChange"
eventos han disparado (filas A, B y C respectivamente). Al ejecutar este fragmento en diferentes navegadores, tenga en cuenta lo siguiente mientras interactúa con el rango / control deslizante:Código de demostración:
Crédito:
Si bien la implementación aquí es en gran medida mía, se inspiró en la respuesta de MBourne . Esa otra respuesta sugirió que los eventos de "entrada" y "cambio" podrían fusionarse y que el código resultante funcionaría en los navegadores de escritorio y móviles. Sin embargo, el código en esa respuesta da como resultado eventos "extra" ocultos que se disparan, lo que en sí mismo es problemático, y los eventos disparados difieren entre los navegadores, un problema adicional. Mi implementación aquí resuelve esos problemas.
Palabras clave:
Los eventos del control deslizante de rango de tipo de entrada de JavaScript cambian la compatibilidad del navegador de entrada entre navegadores de escritorio móvil no-jQuery
fuente
Estoy publicando esto como una respuesta porque merece ser su propia respuesta en lugar de un comentario en una respuesta menos útil. Este método me parece mucho mejor que la respuesta aceptada, ya que puede mantener todos los js en un archivo separado del HTML.
Respuesta proporcionada por Jamrelian en su comentario bajo la respuesta aceptada.
Solo ten en cuenta este comentario de Jaime
Como en él, se activará el evento cuando haya dejado de mover el mouse, y luego nuevamente cuando suelte el botón del mouse.
Actualizar
En relación con el
change
evento y elinput
evento que hace que la funcionalidad se active dos veces, esto no es un problema.Si tiene una función activada
input
, es extremadamente improbable que haya un problema cuandochange
se active el evento.input
se dispara rápidamente al arrastrar un control deslizante de entrada de rango. Preocuparse por una llamada de función más al final es como preocuparse por una sola gota de agua en comparación con el océano de agua que son losinput
eventos.La razón para incluso incluir el
change
evento es en aras de la compatibilidad del navegador (principalmente con IE).fuente
ACTUALIZACIÓN: Dejo esta respuesta aquí como un ejemplo de cómo usar eventos del mouse para usar interacciones de rango / control deslizante en navegadores de escritorio (pero no móviles). Sin embargo, ahora también he escrito una respuesta completamente diferente y, creo, mejor en otra parte de esta página que utiliza un enfoque diferente para proporcionar una solución de escritorio y móvil entre navegadores para este problema.
Respuesta original:
Resumen: una solución de JavaScript simple para todos los navegadores (es decir, no jQuery) para permitir la lectura de valores de entrada de rango sin usar
on('input'...
y / oon('change'...
que funcionan de manera inconsistente entre navegadores.A partir de hoy (finales de febrero de 2016), todavía hay inconsistencia en el navegador, por lo que estoy proporcionando una nueva solución aquí.
El problema: cuando se usa una entrada de rango, es decir, un control deslizante,
on('input'...
proporciona valores de rango actualizados continuamente en Mac y Windows Firefox, Chrome y Opera, así como Mac Safari, mientras queon('change'...
solo informa el valor del rango al mover el mouse. Por el contrario, en Internet Explorer (v11),on('input'...
no funciona en absoluto yon('change'...
se actualiza continuamente.Presento aquí 2 estrategias para obtener informes de valores de rango continuo idénticos en todos los navegadores que usan JavaScript de vainilla (es decir, no jQuery) usando los eventos mousedown, mousemove y (posiblemente) mouseup.
Estrategia 1: más corta pero menos eficiente
Si prefiere un código más corto sobre un código más eficiente, puede usar esta primera solución que usa mouse y mousemove pero no mouseup. Esto lee el control deslizante según sea necesario, pero continúa disparando innecesariamente durante cualquier evento de desplazamiento del mouse, incluso cuando el usuario no ha hecho clic y, por lo tanto, no está arrastrando el control deslizante. Básicamente, lee el valor del rango después de 'mousedown' y durante los eventos 'mousemove', retrasando ligeramente cada uso
requestAnimationFrame
.Estrategia 2: más larga pero más eficiente
Si necesita un código más eficiente y puede tolerar una longitud de código más larga, puede usar la siguiente solución que usa mousedown, mousemove y mouseup. Esto también lee el control deslizante según sea necesario, pero deja de leerlo tan pronto como se suelta el botón del mouse. La diferencia esencial es que solo comienza a escuchar 'mousemove' después de 'mousedown', y deja de escuchar 'mousemove' después de 'mouseup'.
Demostración: explicación más completa de la necesidad e implementación de las soluciones anteriores
El siguiente código demuestra más completamente numerosos aspectos de esta estrategia. Las explicaciones están integradas en la demostración:
Mostrar fragmento de código
fuente
touchmove
debería ser suficiente, y creo que puede tratarse comomousemove
en este caso.Las soluciones de Andrew Willem no son compatibles con dispositivos móviles.
Aquí hay una modificación de su segunda solución que funciona en Edge, IE, Opera, FF, Chrome, iOS Safari y equivalentes móviles (que podría probar):
Actualización 1: Se eliminó la parte "requestAnimationFrame", ya que estoy de acuerdo en que no es necesario:
Actualización 2: Respuesta a la respuesta actualizada de Andrew el 2 de junio de 2016:
Gracias, Andrew: parece funcionar en todos los navegadores que pude encontrar (escritorio de Win: IE, Chrome, Opera, FF; Android Chrome, Opera y FF, iOS Safari).
Actualización 3: solución if ("oninput in slider)
Lo siguiente parece funcionar en todos los navegadores anteriores. (No puedo encontrar la fuente original ahora.) Estaba usando esto, pero posteriormente falló en IE y entonces busqué uno diferente, por lo tanto, terminé aquí.
Pero antes de verificar su solución, noté que esto estaba funcionando nuevamente en IE, tal vez hubo algún otro conflicto.
fuente
Para un buen comportamiento entre navegadores y un código comprensible, lo mejor es usar el atributo onchange en combinación de un formulario:
Lo mismo usando oninput , el valor se cambia directamente.
fuente
Otro enfoque: simplemente establezca un indicador en un elemento que indique qué tipo de evento debe manejarse:
fuente
Puede utilizar el evento "ondrag" de JavaScript para disparar continuamente. Es mejor que "entrada" debido a las siguientes razones:
Soporte de navegador.
Podría diferenciar entre el evento "ondrag" y el "cambio". "input" dispara tanto para arrastrar como para cambiar.
En jQuery:
Referencia: http://www.w3schools.com/TAgs/ev_ondrag.asp
fuente