基本思路
- div 增加tabindex属性,使div能响应focus和blur事件
- 通过控制css display控制元素显示隐藏
- 打开对话框后,调用div.focus()聚焦元素
- blur事件中控制对话框隐藏
- 防止元素被聚焦后出现outline边框,css需设置outline:none;
- 由于tabindex属性,用户可以按下键盘上的tab按键,切换聚焦元素,导致对话框关闭。因此在对话框中监听键盘事件,禁止tab按键。
特性
点击浏览器外的地方,也会触发onblur,关闭弹窗。
(f12调试不好调)
代码
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>blur对话框</title>
</head>
<style>
.dialog{
overflow: hidden;
width:400px;
position:absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
box-shadow: 0 0 10px #ddd;
border:1px solid #ccc;
border-radius: 5px;
display: none;
outline: none;
}
.dialog-header{
background-color: #eee;
padding:10px;
}
.dialog-body{
display:flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding:10px;
}
</style>
<body>
<button onclick="onShowDialogClick()">click to show dialog</button>
<div class="dialog" tabindex="1" onblur="closeDialog(event)">
<div class="dialog-header">使用focus实现点击空白处关闭弹窗</div>
<div class="dialog-body">
<p>特性:点击浏览器外的其他窗口,也会触发onblur,关闭弹窗</p>
<button>close dialog</button>
</div>
</div>
</body>
<script>
const dialog = document.querySelector('.dialog');
function onShowDialogClick(){
dialog.style.display = 'block'; // 使用display控制弹窗显隐
dialog.focus(); // 使dialog获取焦点
}
dialog.addEventListener('keydown', (e) => {
console.log('keyCode', e.keyCode);
if(e.keyCode == 9){ // 禁用tab按键
e.preventDefault();
}
})
function closeDialog(ev){
ev.target.style.display = 'none'; // 使用display控制弹窗显隐
console.log('on blur');
}
</script>
</html>