Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

158
Vistas
El rango de entrada no funcionará en un div desplazable cuando simule un teléfono inteligente

Tengo un input range en un div contenido en un div externo que es más pequeño que el div interno. El resultado final es que mi div interna se desplaza horizontalmente (porque la inmersión externa tiene overflow: scroll ), y el input range es su hijo.

Para personalizar el rango, eliminé la apariencia en CSS con appearance: none . Ahora, esto es lo que sucede. Cuando lo reviso en la herramienta de desarrollo de Chrome (en realidad uso Brave, pero supongo que es lo mismo en Chrome que probé en Chromium, y es lo mismo) con la opción de teléfono inteligente activa, el 99% del tiempo si intente mover el controlador de rango, mueve todo el div con él. Ahora, si desactivo la opción de teléfono inteligente, funciona bien. Además, si mantengo la opción de teléfono inteligente y elimino la appearance: none de CSS, también funciona bien, pero mis personalizaciones en el rango desaparecen. ¿Alguien sabe qué está pasando?

PD: en Firefox, el input range no funciona mientras mantenga activada la opción de teléfono inteligente (no importa si tengo la propiedad de apariencia o no).

Aquí hay un gif animado de lo que quiero decir: Primero, tengo lo descrito anteriormente con el input range sin apariencia. Funciona bien, puedo mover el div desplazable y mover el controlador input range forma independiente. Luego puse la appearance: none en el input range (observe que el formato del rango de entrada cambia), ahora ya no puedo mover el controlador del input range independientemente del div desplazable. Finalmente, elimine la apariencia del input range y todo volverá a la normalidad (pero mis personalizaciones desaparecieron)Texto

Aquí está el código, pero solo puede simular utilizando la herramienta del desarrollador con la opción de teléfono inteligente activa, donde puede simular el toque.

 <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta charset="UTF-8"> <style> #outerframe { height: 310px; width: 300px; border: 2px solid red; padding: 8px; margin: auto; overflow: scroll; } #scrollarea { height: 300px; width: 400px; border: 1px dashed green; padding: 16px; } input[type=range] { appearance: none; background: linear-gradient(90deg, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa); outline: none; opacity: 0.7; border-radius: 4px; height: 14px; width: 200px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset; vertical-align: middle; margin: 16px; } input[type=text] { width: 50px; } </style> <title>Testing range in scroll</title> </head> <body> <div id="outerframe"> <div id="scrollarea"> <input type="range" id="rangescroll"> <input type="text" value="50"> </div> </div> <script> scrollarea.firstElementChild.addEventListener('input', evt => { evt.target.nextElementSibling.value = evt.target.value; }) </script> </body> </html>

EDITAR: CORREGIR:

Oleg Barabanov, sugirió hacer el overflow: hidden mientras se mueve el controlador de entrada (agregue una clase para eso en touchstart y elimine la clase en touchend ). Mientras eso funciona, pensé en una solución más elegante. Recordé sobre event.preventDefault() y cómo nos permite cancelar el manejo del navegador de eventos posteriores. La idea era, si puedo permitir un evento, el evento de input y bloquear el resto (el evento de desplazamiento realizado por el navegador automáticamente), entonces podría funcionar.

Este es el código adicional que probé por primera vez para el rango de entrada:

 document.querySelector('.scrollarea').firstElementChild.addEventListener("touchstart", (evt) => document.querySelector('.outerframe').classList.add("overflow-hidden"); evt.preventDefault(); });

No funcionó aquí (lo cual es sorprendente para mí, ya que lo usé con éxito en el pasado para detener eventos predeterminados). Pero luego recordé que cuando estudié los eventos de JS, había otra forma de evitar los eventos predeterminados y era devolver falso para el evento :

 document.querySelector('.scrollarea').firstElementChild.addEventListener("touchstart", (evt) => document.querySelector('.outerframe').classList.add("overflow-hidden"); return false; });

Para ser justos, ese artículo menciona que return false solo funcionaría cuando el evento esté configurado como un atributo como ontouchstart . Pero lo usé con el método addEventListener() y también funcionó.

Espero que ayude a más personas en el futuro.

over 4 years ago · Santiago Trujillo
5 Respuestas
Responde la pregunta

0

No me queda claro exactamente por qué, pero cuando está en la vista de prueba móvil, deshabilitar la height y el width de #scrollarea en las herramientas de desarrollo soluciona el problema. El #scrollarea en la vista móvil se maneja moviendo todo dentro de los parámetros. Otras dos soluciones, que evitan tener que eliminar sus parámetros, son establecer position=fixed o position=absolute en #rangescroll .

over 4 years ago · Santiago Trujillo Denunciar

0

Si esto es un problema con la compatibilidad con el navegador, puede probar las herramientas en línea que pueden ayudar a generar código CSS con compatibilidad con varios navegadores. Así que te recomendaría que puedes ir aquí .

Aquí está el código que se generó:

 <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta charset="UTF-8"> <style> #outerframe { height: 310px; width: 300px; border: 2px solid red; padding: 8px; margin: auto; overflow: scroll; } #scrollarea { height: 300px; width: 400px; border: 1px dashed green; padding: 16px; } input[type=range] { -webkit-appearance: none; -moz-appearance: none; appearance: none; background: -webkit-gradient(linear, left top, right top, from(#aaa), color-stop(30%, #ccf1ff), color-stop(70%, #ccf1ff), to(#aaa)); background: -o-linear-gradient(left, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa); background: linear-gradient(90deg, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa); outline: none; opacity: 0.7; border-radius: 4px; height: 14px; width: 200px; -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset; box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset; vertical-align: middle; margin: 16px; } input[type=text] { width: 50px; } </style> <title>Testing range in scroll</title> </head> <body> <div id="outerframe"> <div id="scrollarea"> <input type="range" id="rangescroll"> <input type="text" value="50"> </div> </div> <script> scrollarea.firstElementChild.addEventListener('input', evt => { evt.target.nextElementSibling.value = evt.target.value; }) </script> </body> </html>

over 4 years ago · Santiago Trujillo Denunciar

0

Tal vez esta no sea la mejor solución, pero parece funcionar. Simplemente usando los eventos touchstart y touchend + css overflow :

 scrollarea.firstElementChild.addEventListener("input", (evt) => { evt.target.nextElementSibling.value = evt.target.value; }); scrollarea.firstElementChild.addEventListener("touchstart", (evt) => { outerframe.classList.add("overflow-hidden"); }); scrollarea.firstElementChild.addEventListener("touchend", (evt) => { outerframe.classList.remove("overflow-hidden"); });
 #outerframe { height: 310px; width: 300px; border: 2px solid red; padding: 8px; margin: auto; overflow: scroll; } #scrollarea { height: 300px; width: 400px; border: 1px dashed green; padding: 16px; } input[type=range] { appearance: none; background: linear-gradient(90deg, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa); outline: none; opacity: 0.7; border-radius: 4px; height: 14px; width: 200px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset; vertical-align: middle; margin: 16px; } input[type=text] { width: 50px; } .overflow-hidden { overflow: hidden !important; }
 <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta charset="UTF-8"> <title>Testing range in scroll</title> </head> <body> <div id="outerframe"> <div id="scrollarea"> <input type="range" id="rangescroll"> <input type="text" value="50"> </div> </div> </body> </html>

over 4 years ago · Santiago Trujillo Denunciar

0

Puede agregar la propiedad css touch-action:manipulation; a su #outerframe para deshabilitar los eventos táctiles cuando está en modo de teléfono inteligente

editar: descubrí que touch-action:manipulation; puede que no lo resuelva, pero touch-action:none lo hará, pero a expensas de renderizar overflow:scroll; inútil en el móvil

2da edición: me doy cuenta de agregar touch-action: pan-x; touch-action: pan-y en lugar de touch-action:none; Todavía no puedo hacer que tu div externo se pueda desplazar de cierta manera

 <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta charset="UTF-8"> <style> #outerframe { height: 310px; width: 300px; border: 2px solid red; padding: 8px; margin: auto; overflow: scroll; touch-action: pan-x; touch-action: pan-y; } #scrollarea { height: 300px; width: 400px; border: 1px dashed green; padding: 16px; touch-action: manipulation; } input[type=range] { appearance: none; background: linear-gradient(90deg, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa); outline: none; opacity: 0.7; border-radius: 4px; height: 14px; width: 200px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset; vertical-align: middle; margin: 16px; } input[type=text] { width: 50px; } </style> <title>Testing range in scroll</title> </head> <body> <div id="outerframe"> <div id="scrollarea"> <input type="range" id="rangescroll"> <input type="text" value="50"> </div> </div> <script> scrollarea.firstElementChild.addEventListener('input', evt => { evt.target.nextElementSibling.value = evt.target.value; }) </script> </body> </html>

over 4 years ago · Santiago Trujillo Denunciar

0

En el móvil, arrastra para desplazarse hacia arriba y hacia abajo, así como hacia la izquierda y hacia la derecha. Si simplemente deshabilitara el overflow-x en #outerframe , puede solucionar su problema:

 #outerframe { height: 310px; width: 300px; border: 2px solid red; padding: 8px; margin: auto; overflow-x: hidden; } #scrollarea { height: 300px; width: 400px; border: 1px dashed green; padding: 16px; } input[type=range] { appearance: none; background: linear-gradient(90deg, #aaa, #ccf1ff 30%, #ccf1ff 70%, #aaa); outline: none; opacity: 0.7; border-radius: 4px; height: 14px; width: 200px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.5) inset, 0 -5px 4px rgba(0, 0, 0, 0.5) inset; vertical-align: middle; margin: 16px; } input[type=text] { width: 50px; }
 <div id="outerframe"> <div id="scrollarea"> <input type="range" id="rangescroll"> <input type="text" value="50"> </div> </div> <script> scrollarea.firstElementChild.addEventListener('input', evt => { evt.target.nextElementSibling.value = evt.target.value; }) </script>

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda