gpt4 book ai didi

javascript - 支持用escape取消DHTML对话框

转载 作者:行者123 更新时间:2023-11-29 15:01:03 25 4
gpt4 key购买 nike

想象一个带有以下标记的 DHTML 对话框:

<div id="someDialog" class="dialog">
<h2>Title of dialog</h2>

Lots: <input ...>
of: <select ...>
controls: <textarea ...>

<input type="submit" value="OK">
<input type="reset" value="Cancel">
</div>

用户会期望点击 escape 来取消对话框。这本身并不难——只需将 keydown 事件处理程序添加到 document.documentElement 以检查 ev.keyCode == 27,并使用它关闭页面上最顶部的对话框。

问题是——在某些情况下,浏览器首先看到转义键是很重要的。例如,如果浏览器提示 <input type="text"> 的自动完成菜单, 按 escape 应该取消它,而不是取消对话框。如果您调出 <select> 的下拉/弹出菜单, 按 escape 应该关闭它,而不是对话框。

当且仅当浏览器不需要为某些东西使用转义键时,您如何安排处理窗口的转义键?


编辑:Stack Exchange 本身就有这个错误。如果我单击“您希望通过电子邮件将对您的问题的答复发送给您吗?”链接,打开一个 DHTML 对话框,然后选择频率下拉菜单,按 alt-down 打开下拉菜单,然后退出关闭下拉菜单,整个对话框关闭。这不应该发生。在这些情况下,浏览器的控件实现应该首先选择转义键。

最佳答案

经过一些体面的研究和试错,这里最好/唯一的解决方案似乎是创建您自己的自定义表单控件。


以下是解决问题失败的尝试。

http://jsfiddle.net/CoryDanielson/4jBgs/10/

基本原理如下。


首先,有一个 activeInput 变量,它存储用户关注的输入的 DOMElement。 (仅当输入可转义时)

var activeInput = false;

为了填充此变量,我创建了一个您提到的可以转义的 DOMElement 数组(具有自动完成功能的文本框,选择元素)

var escapableElements = [];
escapableElements = escapableElements.concat(
Array.prototype.slice.call(document.getElementsByTagName('select')),
Array.prototype.slice.call(document.getElementsByTagName('input'))
//add more elements here
);

然后遍历数组并为 focusblur(失去焦点)事件附加 eventListeners。 (我在这篇文章的底部包含了每个函数)

forEach(escapableElements, function() {
this.addEventListener('focus', registerActiveElement);
this.addEventListener('blur', deregisterActiveElement);
});

function registerActiveElement() {
if (!activeInput)
activeInput = this;
//console.log('registered'); //testing only
}

function deregisterActiveElement() {
if (activeInput)
activeInput = false;
//console.log('deregistered'); //testing only
}

之后,我为 keydown 事件连接了一个 eventListener。在其中,我检查是否有 activeInput 如果有,我只是 return true; 这会让浏览器做它想做的事(从自动完成中逃脱,等)如果没有 activeInput,我检查是否按下了 ESC 并调用 hide_dialog_box(event.keyCode);

与您问题中有关处理 ESC 按键的段落的唯一区别是,我事先检查了是否有 activeInput。如果有 activeInput,我什么都不做(让浏览器本地处理 ESC)如果没有 activeInput 我调用了 event.preventDefault()将取消浏览器对 ESC 的 native 处理,然后调用函数 hide_dialog_box(keyCode) 然后执行 return false; 这也有助于防止浏览器处理 ESC 按键。

document.addEventListener('keydown', function(event) {
if (!activeInput) {
if (event.keyCode == 27) { //esc
event.preventDefault();
hide_dialog_box(event.keyCode);
return false;
}
} else {
return true; //if active input, let browser function
}
/*
if the browser prompts with an autocomplete menu for
<input type="text">, or options on a <select> drop down
pressing escape will cancel that, not cancel the dialog.
*/
});

代码的最后 2 个片段是函数 hide_dialog_box(keyCode) 和我编写的用于循环遍历 NodeList 的函数,称为 escapableElements

function hide_dialog_box(keyCode) {
var dialog_box = document.getElementById('dialog_box');
dialog_box.style.display = 'none';
}

function forEach(list, callback) {
for (var i = 0; i < list.length; i++)
{
//calls the callback function, but places list[i] as the 'this'
callback.call(list[i]);
}
}

关于javascript - 支持用escape取消DHTML对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10178793/

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