首页 > 解决方案 > 在 ios safari 上设置 datalist 列表属性后,datalist 输入元素丢失光标

问题描述

我有一个 html datalist 元素,我试图仅在字段中输入两个以上字符时才显示自动完成列表。在桌面上,您可以输入从 0 到无穷大的字符,输入永远不会失去焦点,并且列表显示得很好。但是,对于移动设备(特别是 iOS safari),当输入的字符长度达到 3 时,尽管输入仍然具有焦点,但光标会消失。用户必须再次点击输入以继续他的搜索。我会提到,Safari 浏览器会向用户呈现一些不相关的自动完成结果,直到达到 3 的长度。这是管理我预期行为的数据列表上的侦听器:

  // Only show auto-complete results for greater than 2 characters.
  searchNameInput.addEventListener('keyup', e => {
    const input = e.target;
    const list = input.getAttribute('data-list');
    input.value.length > 2 ? input.setAttribute('list', list) : input.removeAttribute('list');

    // Unrelated code (i think):
    if (!input.value.length)
      filtersProxy.searchName = { name: '', city: '', stateProvince: '' };
  });

这是输入 3 个字符后浏览器的样子。请注意输入字段没有光标。datalist 实际列表也尚未出现。

例子

我尝试在每个 keyup 事件后使用 setTimeout 将焦点返回到元素无济于事。这把我难住了!

标签: javascripthtmldatalist

解决方案


我有一个可怕的黑客给你。

首先,创建一个假输入字段:

const fakeInput = document.createElement('input')
fakeInput.setAttribute('type', 'text')
fakeInput.style.position = 'absolute'
fakeInput.style.opacity = 0
fakeInput.style.height = 0
fakeInput.style.fontSize = '16px'
document.body.prepend(fakeInput)
fakeInput.focus()

接下来,使用setTimeout将焦点设置为您的input,因为直接设置它不起作用:

if(input.value.length > 2) {
    if(!input.hasAttribute('list')) {
      fakeInput.focus();
      input.setAttribute('list', list);
      setTimeout(() => input.focus(), 10);
    }
} else input.removeAttribute('list');

瞧。


推荐阅读