這是一個很難闡明,我是移動web開發的新手,所以請耐心等待:移動Safari上使用'下一個'時,選擇/下拉的onchange()JS事件的奇怪行爲下拉列表項選擇框
在我的網頁,我有3名嵌套的下拉列表(區,鎮,街道)。
嵌套如,當在下拉選擇上述它改變每個下拉的項目將被修改。 e.g選擇區改變鎮和街列表和選擇鎮改變街名單。
我在下拉菜單的onchange()javascript事件中使用XMLHTTPRequests來獲取並填充其他下拉菜單。這適用於Android和桌面瀏覽器。
在移動Safari上,當觸摸下降時,會顯示一個列表,用戶可以選擇項目。此外,選擇框具有「上一個/下一個/自動填充/完成」按鈕以導航到其他表單元素。
因此,用戶觸摸第一下拉,選擇一個值,並按下Next按鈕。這會導致兩個問題:
第一個,在此操作上,第一個下拉的oncange()事件不會被可靠地觸發!有時它有時會失火。
如果選擇一個區域後,用戶觸摸網頁上的其他地方或按下「完成」按鈕,然後onchange()正常啓動,城鎮和街道正常填充。
第二個,當按下然後「下一步」按鈕進入焦點的元素是下拉whos元素被取出後需要更改。當先前的下拉列表的的onchange()不被解僱的話,要麼名單沒有更新,或者在選擇框中的項目變爲藍色和所有的人都表示,他們都選擇了刻度..
從如果我可以禁用選擇框中的Next/Previous按鈕,或者以某種方式修復onchange()如何觸發,並且下一個焦點下拉列表項在重點時重新填充,我可以告訴問題將得到解決。
下面是代碼(簡化):
<!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>
幫助。 :/
感謝您的支持。我通過調用下一個下拉列表中的blur()來解決此問題,當第一個選擇被更改並返回XMLHttpRequest數據時,選擇框消失,用戶必須觸摸第二個下拉訪問它,這會導致項目刷新列表..這是一個黑客,我不喜歡太多.. – 2011-09-03 05:10:56
這是一個很好的解決方案,它確實解決了Safari移動Web瀏覽器(這是一階失敗仍然存在於iOS 5上)。但它似乎留下了另一個次要影響。現在,「微調器」正在填充,但在點擊「下一個」或「完成」後,實際下拉似乎不會隨着選擇而更新,也不會進行註冊。任何見解?此外,修復似乎暫時破壞了Android的界面版本。但它然後工作。 – iJames 2011-10-13 20:12:47
我發佈了這個之後發現了android問題。查看我的編輯和上面的新代碼以獲得修復。你能爲第一個問題創建一個jsfiddle嗎? – InvisibleBacon 2011-10-14 19:33:13