Esto es difícil de articular y soy nuevo en el desarrollo web móvil así que tenga paciencia conmigo:Comportamiento extraño de on/dropdown onchange() Evento JS al utilizar 'Siguiente' en Mobile Safari Lista desplegable seleccionar elemento
En mi página web, Tengo 3 listas desplegables anidadas (Área, Pueblo, Calle).
Anidado como en, los elementos de cada menú desplegable se modifican cuando cambia la selección en el menú desplegable situado encima. por ejemplo la selección de un área de cambia la Ciudad y Calle listas y selección de una ciudad cambia la lista la calle.
Utilizo XMLHTTPRequests en el evento onchange() javascript de las listas desplegables para recuperar y rellenar las otras downdowns. Esto funciona bien en los navegadores Android y de escritorio.
En Mobile Safari, cuando se toca un drowdown, se muestra una lista donde el usuario puede seleccionar elementos. Además, el cuadro de selección tiene los botones "Anterior/Siguiente/Autorrelleno/Hecho" para desplazarse a otros elementos del formulario.
De modo que el usuario toca el primer menú desplegable, selecciona un valor y presiona el botón Siguiente. Esto causa dos problemas:
Primero, en esta acción, el primer evento oncange() desplegable no se desencadena de forma confiable. A veces se dispara a veces no.
Si después de seleccionar un Área, el usuario toca en otro lugar en la página web o presiona el botón "Hecho", el cambio() se dispara normalmente y los Pueblos y Calles se llenan normalmente.
Segundo elemento, el elemento que se enfoca cuando se presiona el botón "Siguiente" es el menú desplegable que necesita cambiar los elementos después de la búsqueda. Cuando se activa el onchange() del menú desplegable anterior, o bien la lista no se actualiza o los elementos en el cuadro de selección se vuelven azules y todos tienen una marca que muestra que todos están seleccionados ..
De Lo que sí puedo decir es que el problema se resolverá si puedo desactivar los botones Siguiente/Anterior en el cuadro de selección o arreglar de algún modo cómo se activa el cambio() y los elementos de la lista desplegable siguiente se vuelven a llenar mientras está enfocado.
Aquí está el código (simplificado):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no" />
<title></title>
</head>
<body onload="AppStart();">
<form action="#">
Area:
<select id="ddlArea">
<option value="">-- Select Area -- </option>
<option value="1">Area 1</option>
<option value="2">Area 2</option>
<option value="3">Area 3</option>
<option value="4">Area 4</option>
<option value="5">Area 5</option>
</select>
<br />
Town:
<select id="ddlTown">
<option value="">Please wait ...</option>
</select>
<br />
Street:
<select id="ddlStreet">
<option value="">-- Select Area or Town -- </option>
</select>
<br />
Unit:
<select id="ddlUnit">
<option value="">-- No Street Selected -- </option>
</select>
<script type="text/javascript">
var ddlArea, ddlTown, ddlStreet, ddlUnit;
function AppStart() {
ddlArea = document.getElementById("ddlArea");
ddlTown = document.getElementById("ddlTown");
ddlStreet = document.getElementById("ddlStreet");
ddlUnit = document.getElementById("ddlUnit");
ddlArea.onchange = areaChanged;
ddlTown.onchange = townChanged;
ddlStreet.onchange = streetChanged;
setTimeout(function() { updateTown(""); }, 250);
}
var areaId = "", townId = "", streetId = "", unitId = "";
function areaChanged(e) {
areaId = ddlArea.options[ddlArea.selectedIndex].value
ddlClear(ddlTown, createOption("Please Wait...", ""));
ddlClear(ddlStreet, createOption("Please Wait...", ""));
ddlClear(ddlUnit, createOption("-- No Street Selected --", ""));
setTimeout(function() { updateTown(areaId); }, 500);
setTimeout(function() { updateStreet(areaId, ""); }, 700);
}
function townChanged(e) {
townId = ddlTown.options[ddlTown.selectedIndex].value
ddlClear(ddlStreet, createOption("Please Wait...", ""));
ddlClear(ddlUnit, createOption("-- No Street Selected --", ""));
setTimeout(function() { updateStreet(areaId, townId); }, 400);
}
function streetChanged(e) {
streetId = ddlStreet.options[ddlStreet.selectedIndex].value
ddlClear(ddlUnit, createOption("Please Wait...", ""));
setTimeout(function() { updateUnit(streetId); }, 600);
}
function updateTown(areaID) {
ddlClear(ddlTown, createOption("-- Select Town --", ""));
var items = isNaN(parseInt(areaID)) ? 10 : parseInt(areaID);
if (areaID == "") areaID = "ALL";
for (var i = 0; i < items; i++) {
ddlTown.appendChild(createOption("Town " + (i+1) + ", Area " + areaID, i));
}
}
function updateStreet(areaID, townID) {
ddlClear(ddlStreet, createOption("-- Select Street --", ""));
var items1 = isNaN(parseInt(areaID)) ? 10 : parseInt(areaID);
var items2 = isNaN(parseInt(townID)) ? 10 : parseInt(townID);
var items = items1 + items2;
if (areaID == "") areaID = "ALL";
if (townID = "") townId = "ALL";
for (var i = 0; i < items; i++) {
ddlStreet.appendChild(createOption("Street " + (i + 1) + ", Area " + areaID + ", Town " + townID, i));
}
}
function updateUnit(streetID) {
ddlClear(ddlUnit, createOption("-- Select Unit --", ""));
var items = isNaN(parseInt(streetID)) ? 10 : parseInt(streetID);
if (streetID == "") streetID = "ALL";
for (var i = 0; i < items; i++) {
ddlUnit.appendChild(createOption("Unit " + (i + 1) + ", Street " + streetID, i));
}
}
function ddlClear(Dropdown, option) {
while (Dropdown.options.length > 0) {
try { Dropdown.options[0] = null; } catch (e) { };
}
if (option != null) {
Dropdown.appendChild(option);
}
}
function createOption(text, value) {
var oOption = document.createElement("OPTION");
oOption.innerHTML = text;
oOption.value = value;
return oOption;
}
</script>
</form>
</body>
</html>
Ayuda. :/
Gracias por esto .. He resuelto este problema llamando a blur() en el siguiente menú desplegable, cuando se cambió la primera selección y se devolvieron los datos de XMLHttpRequest, por lo que el cuadro de selección desapareció y el usuario tuvo que tocar el segundo menú desplegable para acceder a él, que hace que los elementos se actualicen en la lista ... fue un truco que no me gusta mucho ... –
Esta es una gran solución que resolvió la falla de primer orden del navegador web Safari Mobile (que es todavía presente en iOS 5). Pero parece haber dejado otro efecto secundario. Ahora el "spinner" está poblando, pero al presionar "next" o "done" el pulldown actual no parece actualizarse con la selección y no se registra. ¿Alguna idea? Además, la solución parecía romper temporalmente la versión de la interfaz de Android. Pero luego funcionó. – iJames
Descubrí el problema de Android después de publicar esto. Ver mi edición y el nuevo código anterior para la solución. ¿Puedes crear un jsfiddle para el primer problema? – InvisibleBacon