Focusing focus blur
JavaScript Focusing: focus/blur
Focusing on an element generally considers “preparing to accept the data here”. So, it’s the moment that one can run the code to initialize the required functionality. (专注于一个元素通常会考虑“准备接受这里的数据”。因此,现在可以运行代码来初始化所需的功能。)
An element receives a focus at the moment the user clicks on it or presses the keyboard Tab key. (元素在用户单击或按下键盘Tab键时接收焦点。)
Also, an HTML autofocus can be used: it puts the focus into an element by default during the loading of the page.
The moment of losing the focus is more principal. It happens when the user clicks somewhere else or presses the Tab key for going to the next form field. Of course, other means exist, as well. (失去焦点的那一刻更重要。当用户单击其他地方或按Tab键转到下一个表单字段时,就会发生这种情况。当然,还有其他手段。)
So, to lose the focus means that the data has been inserted, and the code can be run to check it, to save it on the server, and more. (因此,失去焦点意味着数据已插入,可以运行代码进行检查,将其保存在服务器上等。)
There are significant peculiarities while dealing with focus events that we are going to cover further on. (在处理焦点事件时,我们将进一步讨论一些重要的特点。)
Events:focus/blur
Events:focus/blur
On focusing, the focus event is called, and when the element loses the focus, the blur event is called. (在聚焦时,调用焦点事件,当元素失去焦点时,调用模糊事件。)
To be more accurate, let’s apply them for validation of an input field. (为了更准确,让我们将它们应用于输入字段的验证。)
The blur handler checks if the email is entered. If it’s not entered- an error occurs. (-模糊处理程序检查是否输入了电子邮件。如果未输入,则会出现错误。)
The focus handler hides the error message:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the Document</title>
<style>
.invalid {
border-color: red;
}
#error {
color: red
}
</style>
</head>
<body>
<div id="error"></div>
Your email please:
<input type="email" id="input">
<script>
input.onblur = function() {
if(!input.value.includes('@')) { // not email
input.classList.add('invalid');
error.innerHTML = 'Please write a correct email.'
(error.innerHTML = '请输入正确的电子邮件。')
}
};
input.onfocus = function() {
if(this.classList.contains('invalid')) {
// remove the "error" indication, if the user wants to re-enter something
(//如果用户想要重新输入内容,请删除“错误”指示)
this.classList.remove('invalid');
error.innerHTML = "";
}
};
</script>
</body>
</html>
Modern HTML is capable of doing much validation, applying input attributes: required, pattern, and more. JavaScript may be used for getting more flexibility. Also, the changed value can be sent to the server, in case it’s correct.
Methods focus/blur
Methods focus/blur (方法焦点/模糊)
The elem.focus() and elem.blur() methods are used for setting/unsetting the focus on the element. (Elem.focus ()和elem.blur ()方法用于设置/取消设置元素的焦点。)
Let’s make the user unable to leave the input, if the value is invalid, like this:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the Document</title>
<style>
.errorClass {
border-color: red;
}
</style>
</head>
<body>
<div>
Your email please:
<input type="email" id="input">
<input type="text" placeholder="invalidate the email and try to focus here">
</div>
<script>
input.onblur = function() {
if(!this.value.includes('@')) { // not email
// show the error
(//显示错误)
this.classList.add("errorClass");
// ...and put the focus back
(//...并放回焦点)
input.focus();
} else {
this.classList.remove("errorClass");
}
};
</script>
</body>
</html>
It operates on all the browsers, except for Firefox (bug). (它可以在所有浏览器上运行,但Firefox (错误)除外。)
If you enter something into the input and then try to apply Tab or click away from the <input>, and then onblur brings the focus back.
Another important note: it’s not possible to prevent losing focus by calling event.preventDefault() in onblur, as the latter works the element lost the focus. A focus loss can happen for different reasons.
One of the reasons is when the user clicks somewhere else. But, JavaScript itself can lead to it, for example:
An alert moves the focus to itself, causing the focus loss at the element ( it’s a blur event). When the alert is discarded, the focus returns (focus event). (-警报将焦点移动到自身,导致元素的焦点丢失(这是一个模糊事件)。当警报被丢弃时,焦点返回(焦点事件)。)
In case an element is removed from DOM, it may also cause a focus loss. But, if it is reinserted later, the focus won’t return. (-如果某个元素从DOM中删除,也可能导致焦点丢失。但是,如果稍后重新插入,焦点将不会返回。)
The features above sometimes cause focus/blus handlers to misbehave: they trigger when it’s not necessary.
The best solution is to be careful while using those events. (最好的解决方案是在使用这些事件时要小心。)
Allow Focusing on any Element: tabindex
Allow Focusing on any Element: tabindex
Focusing is not supported by many elements by default. (默认情况下,许多元素不支持聚焦。)
The list can vary a little between browsers, but a thing is constantly correct: focus/blur support is guaranteed for elements that a user can interact with: <input>, <button>, <a>, and more.
On the other hand, elements that exist for formatting something, such as <span>, <div>, <table> - are non focusable by default. The elem.focus() method doesn’t operate on them, and focus/blur events never trigger.
That situation can be changed with HTML-attribute tabindex. (这种情况可以使用HTML属性tabindex进行更改。)
When an element has tabindex, it becomes non focusable. The attribute value is the order number of the element when Tab is applied for switching between them. In other words: if there are two elements and the first hastabindex=“1”, the second- tabindex=“2”, using Tab while in the first one, moves the focus into the second.
The switch order is as follows: elements with tabindex from 1 and above go first and only then go the elements without. Elements that have matching tabindex are switched in the document source order.
Two special values exist:
tabindex=“0” that places an element amid the ones without tabindex. In other words, when you switch elements, the ones with tabindex=0 go after those with tabindex ≥ 1. As a rule, it is used for making an element focusable, keeping the default switching order. (- tabindex = “0"将元素放置在没有tabindex的元素中。 换句话说,当您切换元素时, tabindex = 0的元素会跟随tabindex ≥ 1的元素。 通常,它用于使元素可聚焦,保持默认切换顺序。)
tabindex="-1” is used only for programmatic focusing on an element. The Tab key ignores elements like that, but the elem.focus() method works. (- tabindex = “-1"仅用于对元素进行编程聚焦。Tab键忽略此类元素,但elem.focus ()方法有效。)
Let’s take a look at the example below:
<!-- You should click the first item pressing the Tab. Keep track of the order. Please consider that many subsequent Tabs are capable of moving the focus out of the iframe with the example.-->
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the Document</title>
<style>
li {
cursor: pointer;
}
:focus {
outline: 2px solid red;
}
</style>
</head>
<body>
<ul>
<li tabindex="1">One</li>
<li tabindex="0">Zero</li>
<li tabindex="-1">Minus one</li>
<li tabindex="2">Two</li>
</ul>
</body>
</html>
Also, you can add tabindex from JavaScript by applying the elem.tabIndex property. The effect will be the same. (此外,还可以通过应用elem.tabIndex属性从JavaScript添加tabindex。效果将是相同的。)
Delegation: focusin/focusout
Delegation: focusin/focusout
The focus and blur events don’t bubble. (焦点和模糊事件不会冒泡。)
For example, it is not possible to put onfocus on the <form> to highlight it, as follows:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the Document</title>
<style>
.focused {
outline: 1px solid red;
}
</style>
</head>
<body>
<!-- on focusing in the form - add the class -->
<form onfocus="this.className='focused'">
<input type="text" name="firstname" value="FirstName">
<input type="text" name="lastname" value="LasName">
</form>
</body>
</html>
The reason that the code above doesn’t work is that when the user focuses on the <input>, the focus event triggers on that input only. As it doesn’t bubble up, the form.onfocus doesn’t trigger either.
In such a case, we can suggest two solutions. (在这种情况下,我们可以提出两种解决方案。)
Within the first solution, focus/blur don’t bubble up but propagate down on the capturing phase. Hence, this is a working example:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the Document</title>
<style>
.focused {
outline: 1px solid red;
}
</style>
</head>
<body>
<form id="form">
<input type="text" name="firstname" value="FirstName">
<input type="text" name="lastname" value="LastName">
</form>
<script>
// put the handler on capturing phase, last argument true
(//将处理程序置于捕获阶段,最后一个参数为true)
form.addEventListener("focus", () => form.classList.add('focused'), true);
form.addEventListener("blur", () => form.classList.remove('focused'), true);
</script>
</body>
</html>
And, finally, there are focusin and focusout events, similar to focus/blur. The difference is that they can bubble. They should be assigned by applying elem.addEventListener , not on<event> .
The example of using the focusin and focusout events looks like this:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the Document</title>
<style>
.focused {
outline: 1px solid red;
}
</style>
</head>
<body>
<form id="form">
<input type="text" name="firstname" value="FirstName">
<input type="text" name="lastname" value="LastName">
</form>
<script>
form.addEventListener("focusin", () => form.classList.add('focused'));
form.addEventListener("focusout", () => form.classList.remove('focused'));
</script>
</body>
</html>
Summary
Summary (概要)
The focus and blur events are a crucial part of any programming activity. (焦点和模糊事件是任何编程活动的重要组成部分。)
The focus event triggers on focusing, while the blur event happens when the focus is lost. (聚焦事件在聚焦时触发,而模糊事件在聚焦丢失时发生。)
They have several specific features that are described below:
They never bubble. But, instead, you can use focusin/focusout that can bubble. (-它们永远不会冒泡。但是,您可以使用可以冒泡的focusin/focusout。)
By default, the focus is not supported by most elements. The good thing is that you can use tabindex for making anything focusable. (-默认情况下,大多数元素不支持焦点。好消息是,您可以使用tabindex使任何内容可聚焦。)
And, finally, the currently focused element may be available in document.activeElement. (最后,当前聚焦的元素可能在document.activeElement中可用。)