1. 场景
-
如图,input输入框处于focus状态,下拉框展开,此时点击浏览器之外的位置,input失去焦点,下拉框关闭,但是再次点击浏览器中的任意位置(最好是导航栏),input会重新获取焦点,导致下拉框再次打开,如果点的不是导航栏位置,那么就是重新执行focus----blur事件,造成下拉框闪烁。
2. 问题分析及解决
以react为例:
<input
className="test-input"
onFocus={() => {
console.log('获取焦点');
}}
onBlur={() => {
console.log('失去焦点', document.activeElement);
}}
/>
上述代码按照上述场景中的操作,分为两种情况,
- (1)获取焦点后点击浏览器内任意位置,触发blur失去焦点,打印的document.activeElement是body节点
- (2)获取焦点后点击浏览器外任意位置,触发blur失去焦点,打印的document.activeElement是input节点
说明情况(2)并没有真正失焦,所以调用blur()方法使其强制失焦:
document.activeElement.blur();
当然情况(2)是比较少见的,可以加一个判断:
<input
className="test-input"
onFocus={() => {
console.log('获取焦点');
}}
onBlur={() => {
if(document.activeElement.classList.contains('test-input') {
// contains的作用和数组的includes方法类似
document.activeElement.blur();
}
}}
/>