gpt4 book ai didi

javascript - 如果在 Firefox 中单击时移动鼠标,HTML 标签不会触发相应的输入

转载 作者:行者123 更新时间:2023-12-02 23:04:51 25 4
gpt4 key购买 nike

在以下示例中,当您单击标签时,输入会更改状态。

document.querySelector("label").addEventListener("click", function() {
console.log("clicked label");
});
label {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<input type="checkbox" id="1">
<label for="1">Label</label>

在 Chrome 中,当您在 mousedownmouseup 事件之间移动光标时,输入仍然会被触发,而在 Firefox 中,复选框不会更改状态。

有办法解决这个问题吗? (不使用 JavaScript 事件监听器)

Firefox 版本:69.0.3(64 位)

使用 Chrome 时的全套操作。

  1. 按标签上的按钮
  2. 按住按钮的同时移动光标(甚至在标签外)
  3. 将光标返回到标签
  4. 松开按钮

最佳答案

简介

虽然我在问题中明确指出答案不应涉及 JavaScript,但所有答案都适用于 JavaScript。
由于这似乎是一个 Firefox 错误,并且此时提交的大多数答案都需要我更改其余代码,因此我决定创建一个可以运行一次的脚本,无论何时都会处理所有标签它们被添加到 dom 中,对我的其他脚本的影响最小。

解决方案 - 示例

var mutationConfiguration = {
attributes: true,
childList: true
};

if (document.readyState === "complete") onLoad();
else addEventListener("load", onLoad);

var managingDoms = [];

function onLoad() {
document.querySelectorAll("label[for]").forEach(manageLabel);
if (typeof MutationObserver === "function") {
var observer = new MutationObserver(function(list) {
list.forEach(function(item) {
({
"attributes": function() {
if (!(item.target instanceof HTMLLabelElement)) return;
if (item.attributeName === "for") manageLabel(item.target);
},
"childList": function() {
item.addedNodes.forEach(function(newNode) {
if (!(newNode instanceof HTMLLabelElement)) return;
if (newNode.hasAttribute("for")) manageLabel(newNode);
});
}
}[item.type])();
});
});
observer.observe(document.body, mutationConfiguration);
}
}

function manageLabel(label) {
if (managingDoms.includes(label)) return;
label.addEventListener("click", onLabelClick);
managingDoms.push(label);
}

function onLabelClick(event) {
if (event.defaultPrevented) return;
var id = this.getAttribute("for");
var target = document.getElementById(id);
if (target !== null) {
this.removeAttribute("for");
var self = this;
target.click();
target.focus();
setTimeout(function() {
self.setAttribute("for", id);
}, 0);
}
}
label {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
padding: 10px;
border: 1px solid black;
cursor: pointer;
}
<input type="checkbox" id="a">
<input type="text" id="b">
<label for="a">A</label>
<script>
setTimeout(function() {
var label = document.createElement("label");
label.setAttribute("for", "b");
label.textContent = "b";
document.body.appendChild(label);
}, 3E3);
</script>

说明

onLabelClick

每当标签被点击时,函数onLabelClick就会被调用,它会检查标签是否有相应的输入元素。如果确实如此,它将触发它,删除标签的 for 属性,以便没有错误的浏览器不会重新触发它,然后使用 setTimeout 0ms 的 code> 在事件冒泡后添加 for 属性。这意味着不必调用 event.preventDefault ,因此不会取消其他操作/事件。另外,如果我需要重写此函数,我只需添加一个事件监听器来调用 Event#preventDefault 或删除 for 属性。

管理标签

函数 manageLabel 接受标签,检查是否已添加事件监听器以避免重新添加它,如果尚未添加则添加监听器,并将其添加到标签列表中已被管理。

onLoad

页面加载时需要调用函数 onLoad ,以便此时可以为 DOM 上的所有标签调用函数 manageLabel 。该函数还使用 MutationObserver在加载被触发(并且脚本被运行)之后捕获添加的任何标签。

上面显示的代码已通过 Martin Barker 进行了优化.

关于javascript - 如果在 Firefox 中单击时移动鼠标,HTML 标签不会触发相应的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58840134/

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