これは明確にするのが難しいものであり、私はモバイルWeb開発に不慣れなので、我慢してください。
私のWebページに 3つのネストされたドロップダウンリスト(エリア、タウン、ストリート)があります。
のようにネストすると、各ドロップダウンのアイテムは、その上のドロップダウンの選択が変更されると変更されます。たとえば、Areaを選択すると、TownリストとStreetリストが変更され、TownはStreetリストを変更します。
ドロップダウンのonchange()javascriptイベントでXMLHTTPRequestsを使用して、他のダウンダウンをフェッチしてデータを入力します。これは、Androidおよびデスクトップブラウザで正常に機能します。
モバイルSafariの場合、ドローダウンをタッチすると、ユーザーがアイテムを選択できるリストが表示されます。さらに、選択ボックスには、他のフォーム要素に移動するための[前へ/次へ/自動入力/完了]ボタンがあります。
したがって、ユーザーは最初のドロップダウンをタッチし、値を選択して、[次へ]ボタンを押します。これにより、2つの問題が発生します。
First、このアクションでは、最初のドロップダウンのoncange()イベントが確実にトリガーされません!時々それは時々発火しません。
エリアを選択した後、ユーザーがWebページの別の場所に触れるか、[完了]ボタンを押すと、onchange()が正常に起動され、町と通りが正常に入力されます。
Second、[次へ]ボタンを押したときにフォーカスが表示される要素は、フェッチ後に要素を変更する必要があるドロップダウンです。前のドロップダウンのonchange()が起動されると、リストが更新されないか、選択ボックスの項目が青色に変わり、すべての項目にチェックマークが付いて、すべてが選択されていることを示します。
選択ボックスの[次へ]/[前へ]ボタンを無効にするか、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>
助けて。 :/
私のサイトでも同じ問題が発生しました。 selectコントロールのselectedIndex
プロパティを手動でポーリングすることで、これを修正することができました。そうすれば、リスト内のアイテムを「チェック」するとすぐに起動します。これを行うために私が書いたjQueryプラグインは次のとおりです。
$.fn.quickChange = function(handler) {
return this.each(function() {
var self = this;
self.qcindex = self.selectedIndex;
var interval;
function handleChange() {
if (self.selectedIndex != self.qcindex) {
self.qcindex = self.selectedIndex;
handler.apply(self);
}
}
$(self).focus(function() {
interval = setInterval(handleChange, 100);
}).blur(function() { window.clearInterval(interval); })
.change(handleChange); //also wire the change event in case the interval technique isn't supported (chrome on Android)
});
};
「change」イベントを使用するのと同じように使用します。例えば:
$("#mySelect1").quickChange(function() {
var currVal = $(this).val();
//populate mySelect2
});
編集:Androidタップして新しい値を選択するときに選択の焦点が合わないが、iphoneと同じ問題はないので修正する古いchange
イベントも配線します。