英文:
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('in').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 -->
<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>
<!-- 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('in');
input.parentElement.classList.toggle('invisible');
if (!input.parentElement.classList.contains('invisible')) {
input.focus();
}
}
<!-- language: lang-css -->
.invisible {
display: none;
}
<!-- language: lang-html -->
<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>
<!-- 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('in');
inp.classList.add('active');
inp.focus();
inp.classList.remove('active');
}
<!-- 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 -->
<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>
<!-- end snippet -->
答案3
得分: 1
简化了基本的 CSS,但后来又添加了一些内容以解决页面上放置 float
时的问题。
更改摘要:
- 在元素上使用事件
- 从 HTML 中移除事件附加并将其放入代码中
- 为了清晰起见,使用自定义事件
- 文本字段的失焦/模糊将使用
'blur'
事件隐藏它 - 关键部分:使用元素上的属性作为切换机制显示/隐藏其容器包装器
- 也可以为 "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
'blur'
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('.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 -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论