type number javascript google-chrome w3c html-input soft-keyboard

javascript - Cómo superar WhatWG/W3C/Chrome versión 33.0.1750.146 "error de regresión" con campos<input type="number"/>



input type select (2)

Dependiendo del caso de uso, puede haber una solución más apropiada (aunque elaborada). Por ejemplo, para agregar texto en la posición actual del cursor, puede hacer lo siguiente (probado en Chrome):

var len, pre, post, // Currently focused element a = document.activeElement, // Get current selection s = window.getSelection(); // Delete any existing contents s.deleteFromDocument(); // Keep moving selection backward until the length stops increasing do { len = String(s).length; s.modify(''extend'', ''backward'', ''line''); } while (String(s).length !== len); // Store the selection, then delete it pre = String(s); s.deleteFromDocument(); // Keep moving selection forward until the length stops increasing do { len = String(s).length; s.modify(''extend'', ''forward'', ''line''); } while (String(s).length !== len); // Store the selection, then delete it post = String(s); s.deleteFromDocument(); // Recreate the contents with the new text added a.setAttribute(''value'', a.defaultValue); a.value = pre + txt + post; // Move the selection to after the new text a.select(); s = window.getSelection(); s.collapseToEnd(); while (len-- > 0) s.modify(''move'', ''backward'', ''character'');

Existen limitaciones en este enfoque que también podrían necesitar soluciones más elaboradas, como cuando se devuelve un valor diferente de la selección del texto (que puede ser el caso para los nombres de dominio árabes en una entrada type="email" , por ejemplo) .

Lamentablemente, hay un error que impide que esta solución funcione en Firefox / Gecko, pero al menos Firefox todavía permite la API de selección en <input type="email"> .

Puse las palabras "error de regresión" entre comillas ya que obviamente hay algunas opiniones encontradas sobre esto. Para detalles completos, rastrea el Bug 24796 en Bugzilla.

En resumen, Google Chrome implementó cambios de acuerdo con la última versión de las especificaciones de WhatWG: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type- attr-summary que eliminó las siguientes propiedades y métodos de los campos <input type="number"/> .

Propiedades:

  • selectionStart
  • selectionEnd

Métodos:

  • seleccionar()
  • setSelectionRange (inicio, final)

(hay otros, pero estos son los más comunes utilizados)

Los métodos se definen si inspecciona una instancia "numérica" ​​de HTMLInputElement sin embargo, intentar llamar a los métodos o solicitar las propiedades arrojará una excepción. :-(

En mi humilde opinión, esto es un error (ya que la funcionalidad se eliminó sin nada ganado ... y hay 1,000 sitios / aplicaciones web que proporcionan un comportamiento extendido a estos campos de entrada numéricos mediante JavaScript ... pero estoy divagando (para aquellos que lo deseen) para combatirlo, utiliza la publicación de errores que se menciona arriba)

TL; DR

Para fines de usabilidad, con toda seguridad quiero y planeo seguir usando los campos <input type="number"/> , ya que proporcionan una "pista" al agente de usuario que si en un dispositivo móvil (teléfono inteligente / tableta /?) Me gustaría para presentar el teclado numérico cuando el campo está enfocado vs. el teclado alfabético predeterminado.

Sin embargo, para la versión actual de Chrome (ver 33.0.1750.146) y cualquier otro navegador que implemente a ciegas este cambio de especificación, me gustaría convertir de forma segura los campos representados a <input type="text"/>

Notas:

  • Intentar cambiar estos campos sobre la marcha al modificar sus contenidos no ha tenido éxito ya que el campo pierde su rango de selección cuando se cambia el atributo de tipo.
  • Tengo una solución alternativa que surgió y que publicaré en breve, pero quería asegurarme de que esta pregunta / respuesta estuviera aquí para todos los desarrolladores que se encuentren con este problema.

Lo he resuelto con el siguiente código:

function checkForInputTypeNumberBug(){ var dummy = document.createElement(''input''); try { dummy.type = ''number''; } catch(ex){ //Older IE versions will fail to set the type } if(typeof(dummy.setSelectionRange) != ''undefined'' && typeof(dummy.createTextRange) == ''undefined''){ //Chrome, Firefox, Safari, Opera only! try { var sel = dummy.setSelectionRange(0,0); } catch(ex){ //This exception is currently thrown in Chrome v33.0.1750.146 as they have removed support //for this method on number fields. Thus we need to revert all number fields to text fields. $(''input[type=number]'').each(function(){ this.type = ''text''; }); } } } $(document).ready(function(){ checkForInputTypeNumberBug(); });

Lo he convertido en una función independiente ya que tengo casos en los que los campos se cargan a través de AJAX y necesito poder llamar la función sobre la marcha.

Este código maneja versiones anteriores de IE donde intentar establecer el tipo fallará, así como manejar la excepción en Chrome (en un elemento ficticio) para que las páginas puedan superar este cambio de comportamiento.

Actualización: según la sugerencia de @Andy E sobre el uso del atributo inputmode (actualmente no compatible), he creado un error para tratar de priorizar la implementación de inputmode antes de que los agentes de usuario eliminen las API de selección: https://www.w3.org/Bugs /Public/show_bug.cgi?id=26695