问题关于使用JavaScript聚焦在输入框上。

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

Issue with focusing on input with Javascript

问题

我有一个按钮,当它获得焦点时,会使包含输入框的 div 变为可见:

<button class="edit-path-btn " style="float:right" onfocus='makeFocus()'>click to show</button>
<div class="edit-path-container ">
    <input id="in" type="text" value="test">
</div>

在这里,您可以单击输入框并编辑文本,如果单击其他地方,容器将按预期消失。我已经添加了一些 JavaScript 代码,以便将焦点设置到输入框,以便用户可以立即开始输入,但容器永远不会变得可见。有没有办法修复这个问题?

英文:

I have a button that when it has focus will make a div containing an input become visible:

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

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

function makeFocus() {
	//document.getElementById(&#39;in&#39;).focus();
}

<!-- language: lang-css -->

.edit-path-container {
	display: none;
	height: 100%;
}
.edit-path-btn:focus + .edit-path-container {
	display: block;
}
.edit-path-container:focus-within, .edit-path-container:active {
	display: block !important;
}

<!-- language: lang-html -->

&lt;button class=&quot;edit-path-btn &quot; style=&quot;float:right&quot; onfocus=&#39;makeFocus()&#39;&gt;click to show&lt;/button&gt;
&lt;div class=&quot;edit-path-container &quot;&gt;
	&lt;input id=&quot;in&quot; type=&quot;text&quot; value=&quot;test&quot;&gt;
&lt;/div&gt;

<!-- end snippet -->

Here you can click in the input and edit the text, if you click away the container will disappear as intended.
I have added some JavaScript to give the input focus so the user can start typing straight away but the container never becomes visible. Is there a way to fix this?

答案1

得分: 1

我认为你可以这样做:

function switchFocus() {
  const input = document.getElementById('in');
  input.parentElement.classList.toggle('invisible');
  if (!input.parentElement.classList.contains('invisible')) {
    input.focus();
  }
}
.invisible {
    display: none;
}
<button class="edit-path-btn " style="float:right" onclick='switchFocus()'>click to show</button>
<div id="in-container" class="edit-path-container invisible">
    <input id="in" type="text" value="test" onblur="switchFocus()">
</div>
英文:

I think you can do like that :

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

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

function switchFocus() {
  const input = document.getElementById(&#39;in&#39;);
  input.parentElement.classList.toggle(&#39;invisible&#39;);
  if (!input.parentElement.classList.contains(&#39;invisible&#39;)) {
    input.focus();
  }
}

<!-- language: lang-css -->

.invisible {
    display: none;
}

<!-- language: lang-html -->

&lt;button class=&quot;edit-path-btn &quot; style=&quot;float:right&quot; onclick=&#39;switchFocus()&#39;&gt;click to show&lt;/button&gt;
&lt;div id=&quot;in-container&quot; class=&quot;edit-path-container invisible&quot;&gt;
    &lt;input id=&quot;in&quot; type=&quot;text&quot; value=&quot;test&quot; onblur=&quot;switchFocus()&quot;&gt;
&lt;/div&gt;

<!-- end snippet -->

答案2

得分: 1

代码部分不要翻译。

英文:

The problem with how it works is the blur event fires before the focus happens so the element hides as you try to focus it.

Only way I can see to get around it with how your HTML code is written is to add a temp class that makes it visible and you can then remove that temp class after you focus it or use all JavaScript.

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

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

function makeFocus() {
  var inp = document.getElementById(&#39;in&#39;);
  inp.classList.add(&#39;active&#39;);
  inp.focus();
  inp.classList.remove(&#39;active&#39;);
}

<!-- language: lang-css -->

.edit-path-container {
  display: none;
  height: 100%;
}

.edit-path-btn:focus+.edit-path-container {
  display: block;
}

.edit-path-container:focus-within,
.edit-path-container:active,
.edit-path-container:has(.active) {
  display: block !important;
}

<!-- language: lang-html -->

&lt;button class=&quot;edit-path-btn &quot; style=&quot;float:right&quot; onfocus=&#39;makeFocus()&#39;&gt;click to show&lt;/button&gt;
&lt;div class=&quot;edit-path-container &quot;&gt;
	&lt;input id=&quot;in&quot; type=&quot;text&quot; value=&quot;test&quot;&gt;
&lt;/div&gt;

<!-- end snippet -->

答案3

得分: 1

简化了基本的 CSS,但后来又添加了一些内容以解决页面上放置 float 时的问题。
更改摘要:

  • 在元素上使用事件
  • 从 HTML 中移除事件附加并将其放入代码中
  • 为了清晰起见,使用自定义事件
  • 文本字段的失焦/模糊将使用 &#39;blur&#39; 事件隐藏它
  • 关键部分:使用元素上的属性作为切换机制显示/隐藏其容器包装器
  • 也可以为 "custom" 效果添加多个值。例如,添加一个新值以同时显示它并显示相关内容,例如在失焦时显示相邻的兄弟元素;诸如此类。参考链接:https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator
  • 大量过多的控制台日志以展示何时/何处发生的情况

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

<-- language: lang-js -->

let editPathButton = document.querySelector('.edit-path-btn');
let textInputFoFocus = document.querySelector('.text-input-for-focus');
const focusEvent = new Event("focus");
const makeVisibleEvent = new Event("makevisible");
editPathButton.addEventListener('click', makeFocus, false);

function makeFocus(event) {
  console.log("here");
  textInputFoFocus.dispatchEvent(makeVisibleEvent);
}

textInputFoFocus.addEventListener("blur", (event) => {
  console.log("here in blur");
  event.target.dataset.showonfocus = "hide";
});
textInputFoFocus.addEventListener("makevisible", event => {
  console.log("here in custom");
  event.target.dataset.showonfocus = "show";
  event.target.focus()
  console.log(event.target.outerHTML);
});
textInputFoFocus.addEventListener("focus", (event) => {
  console.log("here in focus; start typing");
});

<-- language: lang-css -->

body {
  font-size: 16px;
  margin: 0;
  padding: 0;
  box-sizing: border;
}

.container-wrapper {
  display: grid;
  grid-template: columns: 1fr auto;
  justify-content: space-between;
  height: 3rem;
  padding: 1rem;
}

.edit-path-btn {
  grid-column: 2;
  grid-row: 1;
  height: 1.5rem;
}

.edit-path-container {
  grid-column: 1;
  grid-row: 1;
  display: none;
  height: 100%;
}

.edit-path-container:has(> .text-input-for-focus[data-showonfocus="show"]) {
  display: block;
}

<-- language: lang-html -->

<div class="container-wrapper">
  <button class="edit-path-btn">Click to show and focus text edit</button>
  <div class="edit-path-container">
    <label for="in">Edit Me:</label>
    <input class="text-input-for-focus" id="in" type="text" value="test" data-showonfocus="hide">
  </div>
</div>

<-- end snippet -->

英文:

Basic CSS I simplified but then added some more to remove the problematic float when placed on a page.
Change summary:

  • Used events on the elements
  • Removed event attachment from HTML and put it in code
  • Used a custom event just for clarity
  • Focus out/blur on the text fields will hide it using the &#39;blur&#39; event
  • Key part Used an attribute on the element to show/hide its container wrapper as a toggle mechanism
  • Can also have multiple values for "custom" effects. For example add a new value to both show it and show a related for example to show an adjacent sibling when the blur happens; things like that. ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator
  • Lots of excess console logs to show what happens when/where

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

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

let editPathButton = document.querySelector(&#39;.edit-path-btn&#39;);
let textInputFoFocus = document.querySelector(&#39;.text-input-for-focus&#39;);
const focusEvent = new Event(&quot;focus&quot;);
const makeVisibleEvent = new Event(&quot;makevisible&quot;);
editPathButton.addEventListener(&#39;click&#39;, makeFocus, false);

function makeFocus(event) {
  console.log(&quot;here&quot;);
  textInputFoFocus.dispatchEvent(makeVisibleEvent);
}

textInputFoFocus.addEventListener(&quot;blur&quot;, (event) =&gt; {
  console.log(&quot;here in blur&quot;);
  event.target.dataset.showonfocus = &quot;hide&quot;;
});
textInputFoFocus.addEventListener(&quot;makevisible&quot;, event =&gt; {
  console.log(&quot;here in custom&quot;);
  event.target.dataset.showonfocus = &quot;show&quot;;
  event.target.focus()
  console.log(event.target.outerHTML);
});
textInputFoFocus.addEventListener(&quot;focus&quot;, (event) =&gt; {
  console.log(&quot;here in focus; start typing&quot;);
});

<!-- language: lang-css -->

body {
  font-size: 16px;
  margin: 0;
  padding: 0;
  box-sizing: border;
}

.container-wrapper {
  display: grid;
  grid-template: columns: 1fr auto;
  justify-content: space-between;
  height: 3rem;
  padding: 1rem;
}

.edit-path-btn {
  grid-column: 2;
  grid-row: 1;
  height: 1.5rem;
}

.edit-path-container {
  grid-column: 1;
  grid-row: 1;
  display: none;
  height: 100%;
}

.edit-path-container:has(&gt; .text-input-for-focus[data-showonfocus=&quot;show&quot;]) {
  display: block;
}

<!-- language: lang-html -->

&lt;div class=&quot;container-wrapper&quot;&gt;
  &lt;button class=&quot;edit-path-btn&quot;&gt;Click to show and focus text edit&lt;/button&gt;
  &lt;div class=&quot;edit-path-container&quot;&gt;
    &lt;label for=&quot;in&quot;&gt;Edit Me:&lt;/label&gt;
    &lt;input class=&quot;text-input-for-focus&quot; id=&quot;in&quot; type=&quot;text&quot; value=&quot;test&quot; data-showonfocus=&quot;hide&quot;&gt;
  &lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月31日 20:25:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75898503.html
匿名

发表评论

匿名网友

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

确定