我有下面的代码,它工作得很好:
window.addEventListener('load', () => {
const values = ['input_1', 'input_2', 'input_3', 'input_4', 'input_5', 'input_6', 'input_7', 'input_8'];
document.querySelectorAll('.box-ipt').forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box1', values[Array.prototype.indexOf.call(document.querySelectorAll('.box-ipt'), input)]));
});
但是我需要一种方法,当我在HTML代码中添加更多的输入框时,不必回到这段代码并向变量添加更多的元素,如"input_9","input_10"等。
基本上是一种让变量接受任意数量的"input_X"元素的方法(比如"input_∞"--我知道JS中不存在∞,只是表明一个观点)。
或者可能是像for
这样的循环,但它不起作用,因为在扩展重载后,输入被设置为随机输入,而不是最后一个活动输入:
window.addEventListener('load', () => {
const inputElements = document.querySelectorAll('.box-ipt');
const values = [];
for (let i = 0; i < inputElements.length; i++) {
values.push(`input_${i + 1}`);
}
inputElements.forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box2', values[Array.prototype.indexOf.call(inputElements, input)]));
});
我也试过这个,但它打破了扩展/浏览器:
window.addEventListener('load', () => {
let i = 1;
for (;;) {
const values = [`input_${i}`];
document.querySelectorAll('.box-ipt').forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box2', values[Array.prototype.indexOf.call(document.querySelectorAll('.box-ipt'), input)]));
i++;
}
});
有什么建议吗?
PS:我知道标题烂透了,如果你有更好的主意,请提出别的建议。
编辑:
更多的上下文到JS代码我有:
// Set focus after checking local storage for last focus
window.addEventListener('load', () => {
const baseanimdur = getComputedStyle(window.parent.document.documentElement).getPropertyValue('--base-anim-dur').replace('s', '');
const focusDelay = getComputedStyle(document.documentElement).getPropertyValue('--parent-grid-searchbox-focus-onload');
setTimeout(() => {
const inputValue = localStorage.getItem("myInputFocused_box1") || "";
const inputNumber = inputValue.match(/\d+/)?.[0];
const input = inputNumber ? document.querySelectorAll(".box-ipt")[inputNumber - 1] : document.querySelectorAll(".box-ipt")[0];
input.focus();
}, baseanimdur / focusDelay);
});
// Function on get active input on Search BT click in order to if input box empty then BT click goes back to focused box
window.getActiveInputOnBTClick = () => {
const inputNumber = localStorage.getItem("myInputFocused_box1").match(/\d+/)?.[0];
const input = inputNumber ? document.querySelectorAll(".box-ipt")[inputNumber - 1] : document.querySelectorAll(".box-ipt")[0];
input.focus();
};
/////////////// REFOCUS WHEN CLICKING BODY ( EMPTY SPACE ) ///////////////
window.addEventListener('load', () => {
const body = document.querySelector('body');
document.addEventListener('click', event => {
event.composedPath().includes(body) ? getActiveInputOnBTClick() : getActiveInputOnBTClick();
});
});
/////////////// Set local storage item for memorizing last focus
window.addEventListener('load', () => {
const values = ['input_1', 'input_2', 'input_3', 'input_4', 'input_5', 'input_6', 'input_7', 'input_8'];
document.querySelectorAll('.box-ipt').forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box1', values[Array.prototype.indexOf.call(document.querySelectorAll('.box-ipt'), input)]));
});
4条答案
按热度按时间j0pj023g1#
我认为你应该利用
forEach
循环中的"index"来完成这个任务,当你使用querySelectorAll
来获取一个页面中的所有inputs
时,你收到的数组会按照元素在页面上出现的顺序来索引每个元素。您可以简单地将索引保存到本地存储器中,然后在加载页面时对该元素调用
focus()
,这样可以扩展到无限的输入。我无法使用localStorage制作代码片段-但请尝试在本地运行此代码片段:
这种解决方案适用于页面上的任何输入量,而无需任何特殊的命名或标记。
页面的HTML可以是
这样就行了。
编辑:
下面是这个例子中的codepen。我对codepen做的唯一修改是在页面加载后等待400ms来改变焦点-因为codepen会加载其他内容并在页面加载后窃取焦点。单击任何输入,然后刷新页面-输入将重新聚焦。https://codepen.io/brandonetter/pen/PoBzWQd
7eumitmz2#
正如布兰登所写的,你可以只使用
forEach
循环的可选参数index
来获得输入在列表中的索引,要实现和前面一样的行为,只需从索引中构造名称'input_n',方法是加1。通过生成与以前完全相同的格式和编号,您不需要修改现有代码的其他部分。
gc0ot86w3#
目标
换句话说,OP需要一个解决方案,其中任何
<input>
,无论是静态的(在页面加载时出现)还是动态的(通过编程添加到页面),都将在它被聚焦时做出React(“focus”事件的起源)。解决方案-事件委派
在祖先元素上注册“焦点”事件(父元素、父元素的父元素等,一直到
<body>
、document
对象、window
对象),通常在注册的祖先元素上触发事件时,会发生"event bubbling",其中事件原点¹是用户实际交互的元素,成为事件链最后一个阶段的开始。事件链就像是从事件源到祖先元素(包括其间的所有元素)的信号传递路径(只有彼此具有父/子关系的元素才具有共同的源和祖先)。参见图I。图I -事件链
| 阶段|从|至|方向|
| - ------|- ------|- ------|- ------|
| 捕获|祖先|来源|向下|
| 目标|两者|两者|枢轴|
| 气泡|来源|祖先|向上|
但在这些特定的情况下,我们有两种选择,因为“焦点”事件不会冒泡(这种情况并不常见,大多数事件实际上冒泡):
1.通过传递
true
作为.addEventListener()
方法的第三个参数,让祖先监听“捕获”阶段(事件链中沿DOM树向下的部分)(参见图II)。1.使用“focusin”事件,它只是带有冒泡的“focus”。
图II -倾听捕获阶段
事件处理程序(由被触发的注册事件调用的回调函数)必须设计为只调用祖先的特定原始元素组的特定行为,而排除所有其他元素。最好将事件处理程序视为注解源来理解,请参阅示例。
如果事件委托按照前面的描述实现,那么当注册的事件被触发时,您将能够控制祖先元素的任何子元素的行为。
event.currentTarget
乌尔
平方英寸event.bubbles
示例
**注意:**Web存储API在SO上被阻止,因此以下堆栈代码段中的示例功能不全。若要查看功能示例,请转到此Plunker。
一个
jfewjypa4#
这起了作用: