Headless UI Combobox焦点行为

huangapple go评论51阅读模式
英文:

Headless UI Combobox Focus Behavior

问题

我正在使用 Headless UI 的 Combobox 作为自动完成搜索栏(React/Remix 应用程序)。我希望在搜索提交后,搜索栏失去焦点。

在某些设备上(例如 iPhone Safari),似乎默认情况下会这样做;然而,在桌面版的 Chrome 上,我得到了非常不同的行为。Combobox 重新获得焦点,我无法弄清楚它是何时/为什么这样做的,因此我无法在 useEffect 中手动模糊它。

我唯一能做的是在 setTimeout 上模糊该栏。

英文:

I am using the Headless UI Combobox as an autocomplete search bar (React/Remix app). I would like the search bar to give up focus after the search is submitted.

On some devices (e.g. iPhone Safari) it seems to do this by default; however, on desktop Chrome I get very different behavior. The combobox refocuses and I cant figure out when/why it is doing this, so I can't manually blur it in a useEffect.

All I could do to hack it was blur the bar on a setTimeout.

答案1

得分: 0

我遇到了类似的问题,并找到了一个解决方案,可能不是最优雅的,但它能完成任务。

首先,我向ComboBox输入元素添加了一个ref,并使用了一个延迟为0的setTimeout来模糊它:

const handleChange = (event) => {
  // 其他操作
  setTimeout(() => {
    searchRef.current.blur()
  }, 0)
}

// 类似这样的结构
<ComboBox onChange={handleChange}>
  <Combobox.Input ref={searchRef} />
</ComboBox>

这对键盘输入效果很好,但我注意到当我点击ComboBox时,它会立即聚焦然后由于setTimeout而模糊,产生明显的闪烁效果。为了解决这个问题,我向ComboBox添加了一个onMouseDown事件,并调用了preventDefault()来防止输入元素获得焦点:

<Combobox.Options
  onMouseDown={(e) => {
    e.preventDefault()
  }}
/>

就像你说的,这有点巧妙,但它能正常工作。在经过几个小时的努力后,它的工作效果要比不工作好,而且我也没有薪水,所以没有人会看这段代码。

英文:

I encountered a similar issue and found a solution that may not be the most elegant but it does the job.

First, I added a ref to the ComboBox input element and used a setTimeout with a delay of 0 to blur it:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const handleChange = (event) =&gt; {
  // other stuff
  setTimeout(() =&gt; {
    searchRef.current.blur()
  }, 0)
}

// a structure like this
&lt;ComboBox onChange={handleChange}&gt;
  &lt;Combobox.Input ref={searchRef} /&gt;
&lt;/ComboBox&gt;

<!-- end snippet -->

This worked fine for keyboard input, but I noticed that when I clicked on the ComboBox, it would immediately focus and then blur due to the setTimeout, creating a noticeable blinking effect. To fix this, I added an onMouseDown event to the ComboBox and called preventDefault() to prevent the input from being focused:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

&lt;Combobox.Options
  onMouseDown={(e) =&gt; {
    e.preventDefault()
  }}
/&gt;

<!-- end snippet -->

Like you said it's kinda hacky but it works and after working on it for several hours, it working is better than it not working plus I don't get paid so no one will look at the code anyway.

答案2

得分: -1

只需修改您网站头部的此元标签:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
英文:

just modify this meta tag on your website head

&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no&quot; /&gt;

huangapple
  • 本文由 发表于 2023年4月20日 05:26:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76058930.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定