【问题标题】:How to detect a change event on an iOS7 select menu, before the user closes the popup?如何在用户关闭弹出窗口之前检测 iOS7 选择菜单上的更改事件?
【发布时间】:2014-07-17 03:14:48
【问题描述】:

在 iOS 7 上,Mobile Safari 中的<select> 菜单在用户单击“完成”之前不会触发更改事件。是否有任何其他事件可以让我知道用户的选择何时发生变化?

<select onchange="alert('This will not fire until the user clicks Done')">
    <option>1</option>
    <option>2</option>
</select>

【问题讨论】:

    标签: javascript iphone html ios7 mobile-safari


    【解决方案1】:

    在用户触摸“完成”之前无法确定新的选择值。

    当用户第一次触摸&lt;select&gt; 控件时,iOS 会为选择选项打开一个原生 UI。这不是 DOM。当用户点击“完成”时,它会发送新的值/索引并在 DOM 上触发相应的事件。

    你可以测试一下。只需设置两个事件:onfocus 将设置一个计时器并不断轮询selectedIndex,直到onblur 在触摸“完成”时销毁计时器。

    <select id="my-select" onfocus="checkSelectedIndex()" onblur="selectDone()">
        <option>1</option>
        <option>2</option>
    </select>
    
    var timer;
    // timer setup on focus
    function checkSelectedIndex() {
        timer = window.setInterval(function () {
            console.log('selected index:', document.getElementById('my-select').selectedIndex);
        }, 500); // 2 polls per second
    }
    
    // timer cleared on blur
    function selectDone() {
        console.log('Selection changed!');
        if (!timer) { return; }
        window.clearInterval(timer);
    }
    

    使用this test,即使您更改了 UI 上的选定项目,您也会看到这一点;在您触摸“完成”(即最终消息发送到 DOM 时)之前,记录的索引不会改变。

    所以,你可以做的是; (有一些 UX 权衡);而不是&lt;select&gt; 元素,创建一个自定义控件,它会在&lt;div&gt;&lt;ul&gt; 中弹出一个选项列表。这样,您将不会触发本机 UI,用户也不会离开 DOM。并且您将能够收听菜单和单击项目的事件。

    只需确保您的控件适合移动设备即可。

    为 iOS 设备启用 Safari Web Inspector:

    1. 在 iOS 设备上,转到:设置 » Safari » 高级 并启用 Web Inspector
    2. 在桌面 Safari 上,转到:首选项 » 高级 并选中 “在菜单栏中显示开发人员菜单”。一个名为“Develop”的新菜单项将添加到您的 Safari 菜单中。
    3. 通过 USB 将您的 iOS 设备连接到您的计算机。
    4. 打开要调试的页面(外部或本地 URL)。
    5. 从桌面 Safari 的开发菜单中,选择您的设备名称,然后单击子菜单中的应用程序名称。

    【讨论】:

    • 不是我想要的答案,但感谢您如此彻底地确认! :)
    【解决方案2】:

    iOS 上的移动 Safari 不会触发 change 事件。

    解决方法:

    同时使用 blurchange,您可以附加一个在触发一次时解除绑定的事件处理程序:jQuery has $().one()

    $("input[type='select']").one("blur change", function(){  
    //will only execute once
      alert('This will fire sure and only once');
    });
    

    注意:如果您需要让每个 DOM 元素多次执行该函数,您可以使用 setTimeout 重新应用它,以避免双重触发

    【讨论】:

    • 唉,这并没有解决它。如果您在 iOS7 设备上查看 jsfiddle.net/PcS5E/4,在点击“完成”之前,该事件仍然不会触发。
    • 我在仿真中检查了它的工作原理。抱歉,我没有 iPhone。
    • 这很奇怪,因为“select”元素,IOS弹出,每次用户选择一个选项时,没有点击“done”就会触发一个更改事件......这很奇怪,因为用户没有“完成”它呢。这就是为什么我通常为 ios 做的模糊事件
    • @Miguel - 是的!我想知道 2014 年和 2017 年之间是否发生了变化。我有一个通过淘汰赛绑定的多选菜单,并且更改事件肯定会触发。当我在所需选项旁边放置检查时,页面在后台更新,然后关闭弹出窗口(测试 iPad Mini 和 iPhone 7 Safari)
    • @bkwdesign ,不确定更改是否在 2014 年和 2017 年之间。但苹果的意见是,如果菜单状态发生更改,那么他们允许更改触发,以便他们可以看到该更改的影响UI 中的变化。想象一下这是一个颜色选项,通过检查颜色你可以实时看到颜色变化,我个人认为这会导致混乱,因为平台的统一性。这就是为什么你应该使用模糊来确认值的最终状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 2013-03-12
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    相关资源
    最近更新 更多