Slider Javascript input type range
Introducción
Hay veces que necesitamos un valor numérico en una página que será introducido por el usuario en un elemento <input type="text">
. Dado que es un número es posible que luego hagamos cálculos y por lo tanto debemos controlar que está dentro de un rango determinado. Otras veces sólo necesitamos introducir un número aproximado sin ni siquiera tener que conocerlo.
Para esos están los slider o barras deslizadoras como las que aparecen en las imágenes. Los nuevos tipos de HTML5 number
y range
para el elemento <input>
nos ayudan en estas tareas. Algún navegador como Firefox 10.0 aún no ha implementado alguna de estas cosas, por lo que construiremos un par de slider sólo con Javascript (que incluso funciona en Explorer 8).
Controles input de números con HTML5: el tipo number
Empezamos con el nuevo tipo number
de HTML5 para introducir números en el elemento <input>
. En la documentación oficial de WHATWG <input type="number">
tenenemos la información. Vea estos ejemplos de aplicación:
Ejemplo:
- Rango 10 a 20 controlando con JavaScript
- HTML5: Rango 10 a 20 con paso 1
- HTML5: Rango 10 a 20 con paso 0.5
Aún algunos navegadores no implementan el tipo number y sobre todo en los móviles. He realizado un teclado auxiliar para el input type number.
<input type="text">
al que se le agrega el evento onchange"limitaValor(this,'entero',10,20)"
. Esta función la tengo en módulo de JavaScript General con funciones de uso corriente.En el segundo tenemos <input type="number" min="10" max="20" value="15" />
para un rango 10..20. Cuando no se incluye se entiende que usará el atributo step="1"
de tal forma que se desplaza en saltos de una unidad. En el tercer ejemplo ponemos step="0.5"
. Aunque con los botones podemos desplazarnos hasta los límites, aún es posible poner cualquier valor tecleando directamente dentro del cuadro. Por lo tanto haría falta controlar externamente ese valor.
Barra deslizadora o slider con input tipo range de HTML5
Hay aplicaciones donde el usuario necesita introducir sólo un valor aproximado. O bien incluso sin tener que conocer el valor que está introduciendo. Por lo tanto no tiene que estar escribiendo ningún número. Es similar a los controles de volumen de un aparato de música. Se trata de la barra deslizadora o slider que también contempla HTML-5 con WHATWG <input type="range">
Ejemplo:
El control <input type="range">
es sólo del slider. El resto se lo he agregado para comprobar el cambio de valor al desplazar el cursor. Simplemente ponemos un evento
onchange="document.getElementById('text1').value=this.value"
en el slider que modificará el cuadro de texto con la posición del cursor. El cuadro lleva a su vez otro evento onchange
que cambiará la posición del cursor. Este tipo range
es simple pero aún Firefox 10 no lo ha implementado.
Barra deslizadora o slider con JavaScript
Si necesitamos un slider podemos hacernos uno. Vea estos ejemplos:
Ejemplo:
El siguiente es un slider de enteros con el rango 4..150
, identificado con id="este-id"
y con el atributo data-hidden
, por lo que sólo mostrará la barra deslizadora. El cuadro de texto <input>
sigue existiendo con type="hidden"
.
Podemos usar las funciones setSlider()
y getSlider()
parar poner y sacar el valor.
- Ver el valor con . Esto es lo mismo que hacer
document.getElementById("este-id").value
- Poner este valor con
miSlider.setSlider("este-id",this.value)
Estas barras deslizadoras se controlan con los módulos sliderwx.js y sliderwx.css. En el HTML sólo tenemos que poner lo siguiente (para el primer ejemplo):
<div class="sliderwx" data-id="entero" data-title="Entero 1 a 25:" data-width="250" data-type="int" data-decimal="0" data-min="1" data-max="25"></div>
Todos las barras se cargan con la función iniciarSliderWx()
ejecutada en el window.onload
de la página. Si vamos a interactuar con el slider esa función devuelve los métodos setSlider(id)
y getSlider(id,valor)
para obtener el valor numérico o editarlo respectivamente. En esta página lo he asignado como var miSlider = iniciarSlider()
. La función inicializadora incorpora elementos <div>
para construir las partes de la barra, el título y cuadro de texto. Tras eso tendremos el siguiente HTML generado dinámicamente para el primer ejemplo:
He agregado dos argumentos opcionales a la función que inicializa el slider:
iniciarSliderWx([nuevoAnchoCursor[, tituloAntes]])
nuevoAnchoCursor
(Entero): Si no se pasa o se pasa null se usará un ancho de 6px para el cursor. En otro caso se modificará el ancho del cursor al valor que se le pase. Esto es útil en los casos en que podamos detectar dispositivos móviles y así poder aumentar el tamaño del cursor para hacerlo más usable.tituloAntes
(Booleano): Si no se pasa este argumento o se pasa false se pondrá el texto del atributodata-title
después de la barra deslizadora y antes del<input>
con el valor númerico. Si se pasa el argumento será con valor true en cuyo caso se ubicará ese título antes de la barra deslizadora.
<div class="sliderwx" data-id="entero" data-title="Entero 1 a 25:" data-width="250" data-type="int" data-decimal="0" data-min="1" data-max="25" data-num="0" unselectable="on" onselectstart="return false;" style="-webkit-user-select: none;"> <div class="sliderwx-principal"> <div class="sliderwx-fondo" onselectstart="return false;" unselectable="on" style="width: 262px;"> <div class="sliderwx-barra" onselectstart="return false;" unselectable="on" data-num="0" style="height: 28px; margin-top: -14px; width: 262px;"></div> <div class="sliderwx-cursor" onselectstart="return false;" unselectable="on" style="height: 24px; width: 12px; margin-top: -12px; left: 0px;"></div> </div> </div> <div class="sliderwx-anexo" unselectable="on"> <span unselectable="on">Entero 1 a 25:</span> <input type="text" id="entero" value="1" data-num="0" size="3" style="width: 4em;"> </div> </div>
Se incorporan los atributos unselectable
y el evento onselectstart
para impedir la selección de algún contenido al mover el ratón cuando deslizamos el cursor. También usamos la propiedad user-select
para lo mismo, pues el comportamiento de los navegadores no es exactamente el mismo con esto de impedir la selección de contenido. En el JavaScript la incorporamos haciendo uso del gestor de prefijos vpForCss que incorpora automáticamente la propiedad con prefijo en el elemento. Si no se usa este componente (que está en el archivo general.js) debe incluir esa propiedad con los prefijos que sean necesarios.
En HTML5 los atributos que empiezan por WHATWG data-*
son reservados para el programador. Así podemos utilizarlos desde JavaScript con elemento.getAttribute("data-xxx")
. Para el slider necesitamos los siguientes atributos:
data-id
es un tipo ID con el que se identificará el slider. El elemento<input>
a generar será identificado en su atributoid
con este valor.data-title
es un string para el título que se pone antes del cuadro de texto.data-width
es el ancho en píxeles del sliderdata-type
es un string con los valores int, float, log para tipo entero, real y logarítmico.data-decimal
es un entero para el número de decimales que se mostrarán con los tipos real y logarítmico.data-min
ydata-max
para los límites del rango
Además hay unos atributos opcionales que son de la forma data-input-*
y que se transfieren al elemento <input>
a generar.
data-input-value
para dotar de un valor inicial al control. Si se omite se ponedata-min
como valor inicial.data-input-type
para el tipo de cuadro de control. Tiene sentido si queremos ocultar el cuadro de texto poniendodata-input-type="hidden"
. Así sólo se muestra la barra sin el título ni el cuadro de texto, aunque este sigue existiendo pues estará contype="hidden"
.- Podemos incluir cualesquiera otros atributos de un
<input>
comosize
,maxlength
,title
, etc.
Por lo tanto el cuadro de texto porta el valor, es decir, si un slider tiene su atributo data-id="xx"
entonces el cuadro de texto tendrá el atributo id="xx"
. Así podemos acceder al atributo value
del cuadro de texto para obtener el valor del slider. También podemos cambiar el cuadro de texto modificando su atributo value
, pero esta acción no modificará el cursor del slider. En todo caso las funciones setSlider(id, valor)
y getSlider(id)
nos permiten poner y extraer un valor de un slider con ese data-id
.
El rango logarítmico resulta muy interesante cuando tenemos uno como el del ejemplo 0.1 .. 1000. Si usáramos la escala real los valores quedarían proporcionalmente repartidos, por lo que apenas podríamos acceder a valores por debajo de la unidad. En el del ejemplo que tiene un ancho de 250 px y para el tamaño del rango 1000-0.1 = 999.9 resultan tramos de 999.9/250 = 3.9996. Por lo tanto cuando movamos 1 píxel tendremos el valor 3.9996+min=3.9996+0.1=4.0996, no pudiendo obtener ningún valor entre 0.1 y ese 4.0996
Con el logarítmico la distancia para una posición del cursor a x píxeles desde la izquierda resultará en un valor v de
Por lo tanto para un valor dado su posición será
Para v=1 la posición será
Así tenemos unos 23 píxeles para recorrer la distancia que va desde 0.1 a 1.
Barra deslizadora o slider con scroll y JavaScript
Por último también podemos aprovechar las barras de desplazamiento o scroll de los elementos HTML para hacer un slider. Vea estos dos ejemplos:
Ejemplo:
En este caso no existe la opción logarítmica. Usamos el mecanismo de scroll que se incluye en un elemento de bloque con la propiedad de estilo {overflow-x}
y con un contenido cuyo ancho es mayor que el contenedor que lo alberga. El script está en el módulo slider-scroll.js y el estilo en slider-scroll.css. El HTML del primer caso es este:
<div class="wscroll" data-width="250" data-id="sc1" data-title="Entero 1 a 25:" data-min="1" data-max="25" data-type="int"></div>
El estilo es muy simple:
div.wscroll div.wscrolla { overflow-x: scroll; overflow-y: hidden; height: 20px; vertical-align: top; display: inline-block; } div.wscroll div.wscrollz { top: 0; overflow: hidden; display: inline-block; padding-left: 0.2em; } div.wscrollz input { border: 0; background-color: transparent; }
Con el window.onload
de la carga de la página iniciamos las barras con iniciarScrolles()
. Se crean elementos <div>
así como el título y cuadro de texto. Para el primero de los ejemplos anteriores el HTML finalmente creado será este:
<div class="wscroll" data-width="250" data-id="sc1" data-title="Entero 1 a 25:" data-min="1" data-max="25" data-type="int"> <div class="wscrolla" style="width: 250px;"> <div style="width: 6250px;"> </div> </div> <div class="wscrollz" style="left: 250px;"> Entero 1 a 25: <input type="text" id="sc1" value="0"> </div> </div>
Hay un <div>
de 250 píxeles y otro que se calcula con la expresión ancho×(max-min+1), dándonos 250×(25-1+1)=6250 píxeles. El contenedor de 250 píxeles lleva overflow-x: scroll
activándose la barra pues el contenido interior es más ancho. Con el estilo se ajusta la altura para que sólo se vea la barra de desplazamiento del contenedor exterior. Las funciones setScroll(id, valor)
y getScroll(id)
permiten poner y extraer un valor del slider si se necesitará interactuar externamente.
Detalles de los script
En los códigos de sliderwx.js y slider-scroll.js se usan algunas funciones que aparecen en general.js para la compatibilidad con navegadores más antiguos.
-
arrayClassName()
para hacer undocument.getElementsByClassName()
-
nodoPadre()
(parentNode
/parentElement
) -
recogeEvento()
para gestionar los eventos sobre los elementos.
El módulo general.js contiene más cosas, por lo que puede extraer estas funciones si no desea vincular el módulo completo.