在Mobile Safari下拉列表项目选择框中使用“下一步”时,select / dropdown的onchange()JS事件的奇怪行为 [英] Strange behavior of select/dropdown's onchange() JS event when using 'Next' on Mobile Safari Dropdown list item select box

查看:148
本文介绍了在Mobile Safari下拉列表项目选择框中使用“下一步”时,select / dropdown的onchange()JS事件的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个难以表达的人,我是移动网络开发的新手,所以请耐心等待:

This is a hard one to articulate and I am new to mobile web development so please bear with me:

在我的网页上我有3个嵌套下拉列表(区域,城镇,街道)。

On my webpage, I have 3 Nested dropdown lists (Area, Town, Street).

嵌套为,当每个下拉列表中的选项更改时,每个下拉列表的项目都会被修改。例如,选择区域更改城镇街道列表并选择城镇更改街道 list。

Nested as in, each dropdown's items are modified when the selection in the dropdown above it changes. e.g selecting an Area changes the Town and Street lists and selecting a Town changes the Street list.

我在下拉列表的onchange()javascript事件中使用XMLHTTPRequests来获取并填充其他下载。这适用于Android和桌面浏览器。

I use XMLHTTPRequests in the onchange() javascript event of the dropdowns to fetch and populate the other downdowns. This works fine on Android and Desktop browsers.

在移动Safari上,触摸drowdown时,会显示一个列表,供用户选择项目。此外,选择框还有上一个/下一个/自动填充/完成按钮以导航到其他表单元素。

On Mobile Safari, when a drowdown is touched, a list is shown where the user can select items. In addition the selection box has the "Previous/Next/Autofill/Done" buttons to navigate to other form elements.

因此用户触摸第一个下拉列表,选择一个值然后按下一步按钮。这会导致两个问题:

So the user touches the first dropdown, selects a value and presses the Next button. This causes two problems:

第一次,在此操作中,第一个下拉列表的oncange()事件未被可靠触发!有时它有时不会发射。

First, On this action the first dropdown's oncange() event is not triggered reliably! Sometimes it fires sometimes not.

如果在选择区域后,用户触摸网页上的其他位置或按完成按钮,则onchange()会正常触发,而城镇和街道则是正常填充。

If after selecting an Area, the user touches somewhere else on the webpage or presses the "Done" button then the onchange() is fired normally and the Towns and Streets are populated normally.

第二,按下然后按下下一步按钮时聚焦的元素是需要更改元素之后需要更改的下拉列表被抓住了。当前一个下拉列表的onchange()被触发时,列表没有更新或者选择框中的项目变为蓝色,并且所有项目都有一个勾号表示它们全部被选中..

Second, the element that comes into focus when pressing then "Next" button is the dropdown whos elements need to be changed after being fetched. When the onchange() of the previous dropdown does get fired then, either the list is no updated or the items in the select box turn blue and all of them have a tick mark showing that they are all selected..

从我所知道的问题将解决,如果我可以禁用选择框中的下一个/上一个按钮或以某种方式修复如何触发onchange()和下一个焦点下拉列表物品在焦点处重新填充。

From what i can tell the problem would be solved if i can disable the Next/Previous buttons in the selection box or somehow fix how the onchange() is fired and the next in focus dropdown's list items are repopulated while it is in focus.

以下是代码(简化):

<!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插件:

I had the same problem on my site. I was able to fix it by manually polling the selectedIndex property on the select control. That way it fires as soon as you "check" the item in the list. Here's a jQuery plugin I wrote to do this:

$.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)
    });
};

您可以像使用更改事件一样使用它。例如:

You use it just like you would use the "change" event. For instance:

$("#mySelect1").quickChange(function() { 
    var currVal = $(this).val();
    //populate mySelect2
});

修改:点按选择内容时,Android无法对焦点进行选择一个新值,但它也没有与iPhone相同的问题。所以通过连接旧的更改事件来修复它。

Edit: Android does not focus the select when you tap it to select a new value, but it also does not have the same problem that iphone does. So fix it by also wiring the old change event.

这篇关于在Mobile Safari下拉列表项目选择框中使用“下一步”时,select / dropdown的onchange()JS事件的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆