You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部分设备下JS select选择事件触发滞后一次的问题修复

诗篇站点移动端select选择滞后问题

问题现象

  • 站点功能:从150篇诗篇中随机抽取1篇展示,搭配随机配图;支持两种交互:点击「Any Psalm」按钮随机切换诗篇,通过select下拉框手动指定诗篇
  • 异常表现:随机切换功能全端正常,select选择功能存在设备差异:
    • 笔记本端、本地环境访问时功能正常
    • 手机、iPad端访问时选择始终滞后一步:当前展示诗篇20时,第一次选诗篇83页面无响应,第二次选诗篇102时,页面才会加载第一次选中的诗篇83,需要两次操作才能触发上一次选择的内容渲染
  • 已尝试方案:将原生JS事件监听替换为jQuery写法,两种写法异常表现完全一致
  • 站点地址:站点访问地址

相关代码

selectPsalm 处理函数

const selectPsalm = () => {
    loadingImage();
    let psalms = randomPsalm(psalmsBulk)[1];
    let selectedPsalmIndex = document.getElementById("choose").value;
    let lastIndex = () => {
        if(psalms.indexOf(psalms[selectedPsalmIndex])<10) {
            return 2
        } else if(psalms.indexOf(psalms[selectedPsalmIndex])<100) {
            return 3
        } else return 4
    }
    strHeading = psalms[selectedPsalmIndex].slice(0, psalms[selectedPsalmIndex].indexOf(psalms.indexOf(psalms[selectedPsalmIndex]))+lastIndex());
    strScripture = psalms[selectedPsalmIndex].slice(psalms[selectedPsalmIndex].indexOf(psalms.indexOf(psalms[selectedPsalmIndex]))+lastIndex());
    document.getElementById('heading').innerHTML = strHeading;           
    document.getElementById('psalm').innerHTML = strScripture;     
}

原有事件绑定代码

//document.getElementById("random").addEventListener('click', newRandomPsalm);
//document.getElementById("choose").addEventListener('click', selectPsalm);

$('document').ready(function(){
  $('#random').on('click', newRandomPsalm);
  $('#choose').on('click', selectPsalm)
})

问题成因

核心原因是给select元素绑定了错误的事件类型:

  • 现有代码给下拉选择框绑定的是click事件,该事件触发时机是元素被点击的瞬间,并非选项值变更完成的时机
  • 桌面端Chrome、Edge等浏览器的交互逻辑中,用户点击下拉选项完成选择时,会额外触发一次select元素上的click事件,因此代码能拿到最新选中值,表现为功能正常
  • 移动端、iPad端的系统select交互为原生弹窗样式:第一次点击select弹出选择器时,click事件就已经触发完成,此时用户还未完成选项选择,代码读取到的是上一次的旧value;用户选完选项关闭选择器后,不会再触发第二次click事件,因此第一次选择不会触发内容更新;等用户第二次点击select准备选新值时,click事件再次触发,此时读取到的是上一次选中的值,就出现了操作滞后一步的现象。
  • 额外存在一个语法隐患:*$('document')*写法错误,不需要给document加引号,加引号后jQuery会查找页面中不存在的<document>标签,而非绑定到真正的文档就绪事件上,只是大部分场景下不会阻塞代码运行。

修复方案

  1. 将select元素的监听事件从click替换为change事件,change事件只会在select选中值真正变更完成后触发,全端交互逻辑一致
  2. 修正jQuery就绪事件的语法错误,移除document的引号

修改后的事件绑定代码:

// 原生JS写法(可按需选用)
// document.getElementById("random").addEventListener('click', newRandomPsalm);
// document.getElementById("choose").addEventListener('change', selectPsalm);

// jQuery写法
$(document).ready(function(){
  $('#random').on('click', newRandomPsalm);
  $('#choose').on('change', selectPsalm)
})

可选优化

selectPsalm函数每次执行都会调用randomPsalm(psalmsBulk)[1]重新生成诗篇数组,这个数组是固定的150篇内容,可以提前定义为全局常量,不需要每次选择时重复生成,减少不必要的性能消耗。


内容的提问来源于stack exchange,提问作者chylinski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:18:27