IScroll 4 no funciona con el elemento form <select> iPhone Safari y navegador Android
Estoy usando este código HTML:
<form action="#" method="post"> <fieldset> <label class="desc" id="title10" for="Field10"> How many children do you have? </label> <select id="Field10" name="Field10" class="field select large" tabindex="5"> <option value="0" selected="selected">0 </option> <option value="1">1 </option> <option value="2">2 </option> <option value="3">3 </option> <option value="4">4 </option> <option value="5">5 </option> <option value="6">6 </option> <option value="7">7 </option> <option value="8">8 </option> <option value="9">9 </option> </select> <input type="submit" value="Send message" /> </fieldset> </form>
<select>
no funciona en iPhone y Android. Cuando toco la caja de selección, no pasa nada.
- ¿Puede Selenium probar webapps móviles?
- Evento de clic de JQuery de un elemento div en li no disparado en Safari móvil
- ¿Cómo puedo encontrar la ventana virtual / ancho de pantalla con Javascript?
- Detectar si el navegador admite la reproducción automática de medios incrustados: YouTube playVideo () e iOS
- Entrada de Android / iOS enfocada al tocar en el cuerpo de la página
Estoy usando iScroll 4 que está creando el problema.
<script type="application/javascript" src="iscroll-lite.js"></script> <script type="text/javascript"> var myScroll; function loaded() { myScroll = new iScroll('wrapper'); } document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false); document.addEventListener('DOMContentLoaded', loaded, false); </script>
Creo que esta es una solución, pero no sé cómo implementarla.
- Cómo abrir un teclado numérico en android / chrome con <input type = "text">?
- Creación de una versión móvil de un sitio web
- ¿Cómo puedo hacer que el navegador Android muestre mi documento al tamaño de la pantalla?
- Detectar la compatibilidad con la entrada de archivos del navegador
- Optimizar la aplicación ASP.NET Navegadores IPhone y Android para la aplicación ASP.NET
- ¿Hay una manera de hacer un número de teléfono clicable en un teléfono de iphone o android para hacer una llamada en HTML?
- Fondo-adjunto: fijo interferir con el tamaño de fondo
- ¿Es posible, en JavaScript, detectar cuándo se apaga la pantalla en los navegadores de Android y iOS
El problema es que iScroll cancela el comportamiento predeterminado de su etiqueta de select
(No es una implementación muy buena si me pregunta).
Esto ocurre en la función _start()
en la línea 195:
e.preventDefault();
Si comenta eso, notará que la etiqueta de select
funciona de nuevo.
Pero comentarlo significa que has hackeado la biblioteca, lo que podría romper la funcionalidad deseada de iScroll. Así que aquí hay una solución mejor:
var selectField = document.getElementById('Field10'); selectField.addEventListener('touchstart' /*'mousedown'*/, function(e) { e.stopPropagation(); }, false);
Ese código permitirá que el comportamiento predeterminado ocurra, sin propagar el evento a iScroll donde atornilla todo.
Puesto que su JS no está dentro de ningún evento jQuery-like onReady()
, tendrá que asegurarse de poner este código DESPUÉS del HTML donde se definen los elementos select
.
Tenga en cuenta que para los dispositivos móviles el evento es touchstart
, pero para el navegador de su PC se realizará
Tuve el mismo problema en el iScroll 4.1.9 en Android, acabo de reemplazar la línea 95 (en mi versión):
onBeforeScrollStart: function (e) { e.preventDefault(); },
Por:
onBeforeScrollStart: function (e) {var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase():(e.target ? e.target.nodeName.toLowerCase():''); if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') e.preventDefault(); },
Que permiten enfocar las etiquetas de entrada, seleccionar y textarea
Finalmente arregló esto para Android. Terminó modificando un par de líneas en iscroll.js
Así es como inicializamos iScroll.
// code from https://github.com/cubiq/iscroll/blob/master/examples/form-fields/index.html // don't preventDefault for form controls _menuScroll = new iScroll('menu_wrapper',{ useTransform: false, onBeforeScrollStart: function (e) { var target = e.target; while (target.nodeType != 1) target = target.parentNode; if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') e.preventDefault(); } });
El onBeforeScrollStart es lo que permite que los comportamientos predeterminados de los controles tengan lugar. El navegador de Android parece tener problemas con useTransform, así que a su vez a false.
Finalmente, es necesario excluir algún código de iscroll adicional cuando useTransform es falso:
// iscroll.js v4.1.9 // line 216: if (that.options.useTransform) bar.style.cssText += ';pointer-events:none;-' + vendor + '-transition-property:-' + vendor + '-transform;-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-' + vendor + '-transition-duration:0;-' + vendor + '-transform:' + trnOpen + '0,0' + trnClose; // line 295: if (that.options.useTransform) that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose;
Probado varios otros métodos antes de darse cuenta de que tenía que ver con el css que iscroll añade.
Aquí está la solución
/* on page add this after all scripts */ <script type="text/javascript"> var myScroll; function loaded() { myScroll = new iScroll('wrapper'); } document.addEventListener('DOMContentLoaded', function(){ setTimeout(loaded,500);}, false); </script> /* attach a script for fix */ $(document).ready(function(){ var my_select = document.getElementsByTagName('select'); for (var i=0; i<my_select.length; i++) { my_select[i].addEventListener('touchstart' /*'mousedown'*/, function(e) { myScroll.destroy(); setTimeout(function(){myScroll = new iScroll('wrapper');},500); }, false); } /*if you have input problems */ var input = document.getElementById('input'); if (input) { input.addEventListener('touchstart' /*'mousedown'*/, function(e) { e.stopPropagation(); }, false); } });
Otro ejemplo de código para la solución. Y gracias por comentarios anteriores! Uso de JQuery!
Después:
$(document).ready(function() { document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false); document.addEventListener('DOMContentLoaded', setTimeout(function () { loaded(); }, 200), false); });
En la función cargada
function loaded() { var allSelects = $('select'); allSelects.each(function(index, item) { item.addEventListener('touchstart' /*'mousedown'*/, function(e) { e.stopPropagation(); }, false); }); }
Sustitución de la línea, onBeforeScrollStart: function (e) { e.preventDefault(); },
onBeforeScrollStart: function (e) { e.preventDefault(); },
Por
onBeforeScrollStart: function (e) { var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase():(e.target ? e.target.nodeName.toLowerCase():''); if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') { e.preventDefault(); } },
En iScroll.js
Obras
Comience con este código. Esta solución funcionó para mí:
<script type="text/javascript"> var myScroll; function iScrollLoad() { myScroll = new iScroll('wrapper'); enableFormsInIscroll(); } function enableFormsInIscroll(){ [].slice.call(document.querySelectorAll('input, select, button, textarea')).forEach(function(el){ el.addEventListener(('ontouchstart' in window)?'touchstart':'mousedown', function(e){ e.stopPropagation(); }) }) } document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false); document.addEventListener('DOMContentLoaded', function () { setTimeout(iScrollLoad, 200); }, false); </script>
Sé que estoy tarde, pero podría ser útil para alguien,
Escriba el código siguiente en el evento de show de páginas, pero asegúrese de que los identificadores de div no sean los mismos.
Es porque, iscroller evita los comportamientos predeterminados de los elementos
$('#yourpage').bind('pageshow',function (event, ui) { var myScroll; if (this.id in myScroll) { myScroll[this.id].refresh(); }else{ myScroll[this.id] = new iScroll('wrapper', { //wrapper is div id checkDOMChanges: true, onBeforeScrollStart: function (e) { var target = e.target; while (target.nodeType != 1) target =target.parentNode; if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA'){ e.preventDefault(); } } }); } document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false); });
Llego tarde, pero te dejo mi solución.
Si estás usando jQuery puedes intentarlo.
$('input, textarea, button, a, select').off('touchstart mousedown').on('touchstart mousedown', function(e) { e.stopPropagation(); });
// Setup myScroll myScroll = new IScroll('#wrapper', { scrollX: horizontalSwipe, scrollY: !horizontalSwipe, momentum: false, snap: document.querySelectorAll('#scroller .slide'), snapSpeed: 400, bounceEasing: 'back', keyBindings: true, click: true });
Para mí, sólo necesito añadir click: true en la última línea … Pasé todo el día depurando e implementando todas las soluciones sugeridas sin éxito …
Él cualquiera.
Sé que sobre todas sus respuestas pero tengo nueva manera de ofrecer. Sin java-script o drop iscroll funciones.
Los grandes problemas con toda esta solución es cuando se desplaza en el elemento de entrada no tiene desplazamiento en la página. Cuando usted hace apenas una o dos entrada no es realmente materia pero cuando la página es una forma usted tiene gran problema para desplazar la página.
La solución i que ofrece es envolver la entrada en la etiqueta etiqueta o hacer la etiqueta de la etiqueta con el puntero a la entrada. Luego hacer con posicionamiento absoluto y z-index la etiqueta por encima de la entrada. Cuando toque la etiqueta se enfoca la entrada.
Y ejemplo por favor
HTML
<fieldset> <label> <input type="text" /> </label> </fieldset>
CSS
fieldset {position:relative;z-index:20;} label {position:relative;z-index:initial;} input {position:relative;z-index:-1;}
También puede de esta manera poner el lado de la etiqueta de la entrada y con la posición absoluta de la entrada poner eso en el área de la etiqueta
Está trabajando en 100%, compruébelo
Hay un error con Android cuando -webkit-transform: translate3d se aplica a un contenedor que tiene un cuadro de selección o una contraseña [1]. El área en caja para activar esos elementos se mueve, y no están donde crees que estarían. Además, los cuadros de contraseña pintan en una ubicación diferente, por lo que parece que tiene dos elementos de entrada en lugar de uno.
Trabajo en AppMobi y hemos desarrollado una biblioteca de herramientas que tiene arreglos para estos. Hemos implementado widgets personalizados de cuadro de selección y un reemplazo para el campo de entrada de contraseña. Compruébelo abajo.
https://github.com/imaffett/AppMobi.toolkit
[1] Creo que el autor del comentario está hablando de este error https://bugs.webkit.org/show_bug.cgi?id=50552
Estoy un poco tarde para el juego, pero si alguien sigue interesado, tomé el enfoque de @bastien y lo retocó un poco para que funcione en Android. Estoy usando JQM con mi implementación.
Básicamente lo que hice fue:
function scrollMe(element) { var contentID = $wrapper.get(0).id; var scroller = elm.find('[data-iscroll="scroller"]').get(0); if (scroller) { var iscroll = new iScroll(contentID, { hScroll : false, vScroll : true, hScrollbar : false, vScrollbar : true, fixedScrollbar : true, fadeScrollbar : false, hideScrollbar : false, bounce : true, momentum : true, lockDirection : true, useTransition : true, //the preceding options and their values do not have any to do with the fix //THE FIX: onBeforeScrollStart: function(e) { var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase() : (e.target ? e.target.nodeName.toLowerCase():''); //get element node type if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') e.preventDefault(); //be have normally if clicked element is not a select, option, input, or textarea. else if (iscroll != null) { //makes sure there is an instance to destory iscroll.destroy(); iscroll = null; //when the user clicks on a form element, my previously instanced iscroll element is destroyed } }, onScrollStart: function(e) { if (iscroll == null) { //check to see if iscroll instance was previously destoryed var elm = $.mobile.activePage; //gets current active page var scrollIt = setTimeout( function(){ scrollMe(elm) }, 0 ); } //recursively call function that re-instances iscroll element, as long as the user doesn't click on a form element } }); elm.data("iscroll-plugin", iscroll); } }
Básicamente, todo lo que necesitas hacer es destruir tu instancia de iScroll cuando el usuario selecciona un elemento de formulario, pero antes de que realice el desplazamiento (onBeforeScrollStart) y si el usuario hace clic en cualquier elemento dentro del elemento con el atributo personalizado data-iscroll="scroller"
, pueden desplazarse usando iScroll como de costumbre.
<div data-role="page" id="pageNameHere" data-iscroll="enable">
Aquí hay una solución muy fácil que funcionó para mí. Me di cuenta en los navegadores de Android que en la carga inicial de la página no podía hacer clic en un cuadro de selección, pero pude hacer clic en un campo de entrada de texto que estaba utilizando para la búsqueda. Entonces me di cuenta de que después de hacer clic en el campo de entrada de texto, me reconocería haciendo clic en una caja de selección. Así que todo lo que hice fue añadir esto a la función de JavaScript que estaba usando para cargar la página de búsqueda …
$('#search').focus();
Así que cuando la página de búsqueda se carga, se centra automáticamente en el campo de entrada de texto, pero no aparece el teclado, que es exactamente lo que quería. Lo siento mi ejemplo no es de acceso público, pero espero que esto todavía puede ayudar a alguien.
Pruebe esta solución si (e.target.nodeName.toLowerCase () == "seleccione" || e.target.tagName.toLowerCase () == 'input' || e.target.tagName.toLowerCase () == 'textarea ') {
regreso; }
¿Qué pasa, que funciona para mí !:
$('input, select').on('touchstart', function(e) { e.stopPropagation(); });
Incluso si ha excluido elementos de formulario en onBeforeScrollStart (), hay otro error en el navegador / webview de Android 2.2 / 2.3:
https://www.html5dev-software.intel.com/viewtopic.php?f=26&t=1278 https://github.com/01org/appframework/issues/104
No se pueden introducir caracteres chinos en elementos de entrada en la div con el estilo css "-webkit-transform". El iscroll 4 aplicó el "-webkit-transform" con el scroller div.
La solución es mantener los campos de formulario en una div absoluta fuera del scroller.
El error del navegador de Android es el resultado de una versión muy antigua de WebKit dentro de Android, incluso dentro de Android 4.3. La causa raíz del error – el procesamiento incorrecto del evento de clic que iScroll devuelve al navegador (la eliminación de preventDefault simplemente deja de enviar este evento de clic) El navegador Chrome de Android está libre de este error porque ha actualizado la biblioteca de WebKit dentro.
Esperando la actualización de Android WebKit de Google.
- Implementación de servicios de Google Play en android
- Cómo restringir los caracteres especiales de un campo Android EditText?