gpt4 book ai didi

javascript - 调用 onBlur 时 relatedTarget 在 Firefox 中为 null

转载 作者:行者123 更新时间:2023-11-30 13:53:43 24 4
gpt4 key购买 nike

我正在尝试创建一个帮助消息,当用户单击切换按钮以显示帮助消息或通过单击页面上的其他位置来单击离开时,该帮助消息将消失。解决方案似乎是查看 onblur 事件的 relatedTarget 属性,并防止 onblur 处理程序在 relatedTarget 是切换帮助信息的按钮。这似乎在 Chrome 中有效,但在 Firefox 和 Safari 中,relatedTarget 属性设置为容器 div 而不是按钮,这使得无法区分切换按钮点击和“点击离开”。

我创建了一个简单的演示程序来说明问题:

let openState = false;
let contentDiv = document.getElementById("show-hide-content");
let accordionDiv = document.getElementById("accordion");
let showHideButton = document.getElementById("show-hide-toggle");
function setOpenState(state) {
openState = state;
if(openState) {
contentDiv.style.visibility = "visible";
contentDiv.focus();
}
else {
contentDiv.style.visibility = "hidden";
}
}

function toggleVisibility(override) {
if (typeof override === "boolean") {
setOpenState(override);
}
else {
setOpenState(!openState);
}
}

function buttonClickHandler(event) {
toggleVisibility();
}

function contentBlurHandler(event) {
if(!accordionDiv.contains(event.relatedTarget)) {
toggleVisibility(false);
}
}

showHideButton.onclick = buttonClickHandler;
contentDiv.onblur = contentBlurHandler;
.parent {
display: flex;
width: 100vw;
height: 100vh;
flex-direction: row;
background-color: #409958;
}

.accordion {
background-color: #28a7c9;
}

.show-hide-content {
visibility: hidden;
background-color: #c91e63;
}
<h1>Show/Hide Test</h1>
<div class="parent">
<div class="drawer">
<div class="accordion" id="accordion">
<button class="show-hide-toggle" id="show-hide-toggle">Show/Hide</button>
<div class="show-hide-content" id="show-hide-content" tabindex="-1">
<p>This is some content that should be shown or hidden depending on the toggle.</p>
</div>
</div>
<div class="spacer">
</div>
</div>
</div>

此代码在 Chrome 中正常工作。但是,在 Firefox 中,单击“显示/隐藏”按钮会显示隐藏的内容,但再次单击该按钮时不会隐藏它。据我所知,这是因为 onblur 处理程序隐藏了 div,然后 onclick 处理程序再次打开它,即使我正在检查 onblur.relatedTarget 以确保它不在抽屉内的任何地方。

在 Firefox 中检测点击离开的正确方法是什么?

最佳答案

问题是 clicking the <button> doesn't focus it on some browser/OS combinations (特别是在 macOS 上,Chrome 除外),所以 onblurevent.relatedTargetnull因为页面上没有任何内容获得焦点。如果您从 <div id="show-hide-content"> 按下 SHIFT+TAB ,你会看到 relatedTarget设置如您所愿,因为按钮在这种情况下确实获得了焦点。

我会运行代码来隐藏 div 一个小的超时,给 click处理程序有机会首先运行。

在下面的示例中,我实现了这个建议并添加了一些日志记录,以便更容易查看发生了什么:

let openState = false;
let contentDiv = document.getElementById("show-hide-content");
let accordionDiv = document.getElementById("accordion");
let showHideButton = document.getElementById("show-hide-toggle");
function setOpenState(state) {
openState = state;
if(openState) {
contentDiv.style.visibility = "visible";
contentDiv.focus();
}
else {
contentDiv.style.visibility = "hidden";
}
}

function buttonClickHandler(event) {
console.log("click, setting openState to", !openState);
setOpenState(!openState);
}

function contentBlurHandler(event) {
console.log("blur, relatedTarget is", event.relatedTarget);

setTimeout(function() {
console.log("blur, after timeout, openState is", openState);
setOpenState(false);
}, 100);
}

showHideButton.onclick = buttonClickHandler;
showHideButton.onmousedown = function() {console.log("button mousedown"); };
contentDiv.onblur = contentBlurHandler;
showHideButton.onfocus = function(ev) { console.log("button onfocus"); }
.parent {
display: flex;
width: 100vw;
height: 100vh;
flex-direction: row;
background-color: #409958;
}

.accordion {
background-color: #28a7c9;
}

.show-hide-content {
visibility: hidden;
background-color: #c91e63;
}
<h1>Show/Hide Test</h1>
<div class="parent">
<div class="drawer">
<div class="accordion" id="accordion">
<button class="show-hide-toggle" id="show-hide-toggle">Show/Hide</button>
<div class="show-hide-content" id="show-hide-content" tabindex="-1">
<p>This is some content that should be shown or hidden depending on the toggle.</p>
</div>
</div>
<div class="spacer">
</div>
</div>
</div>

关于javascript - 调用 onBlur 时 relatedTarget 在 Firefox 中为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57695377/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com