考虑到堆叠层上下文,如何处理javascript键绑定?

考虑到堆叠层上下文,如何处理javascript键绑定?,javascript,html,css,dom,keyboard,Javascript,Html,Css,Dom,Keyboard,假设我打开了一个,打开了一个完整模式。按[ESC]键可关闭此模式。 在该完整模式中,用户可以打开另一个较小的模式,也可以按[ESC]键关闭该模式。如何处理[ESC]键并关闭“更高”层,防止按键传播并关闭正在收听按键的其他层 我期待着一个直截了当的答案,使用默认值或类似的。。我不考虑设置某种服务,在决定关闭哪一层之前进行多次检查。。对我来说,这东西应该像点击事件一样向上传播。这是可行的吗?没有直接的.preventDefault()或一些黑魔法可以阻止您关闭事件侦听器,除非您每次都要创建一个新的处

假设我打开了一个
,打开了一个
完整模式。按[ESC]键可关闭此模式。
在该
完整模式中
,用户可以打开另一个较小的模式,也可以按[ESC]键关闭该模式。如何处理[ESC]键并关闭“更高”层,防止按键传播并关闭正在收听按键的其他层


我期待着一个直截了当的答案,使用默认值或类似的。。我不考虑设置某种服务,在决定关闭哪一层之前进行多次检查。。对我来说,这东西应该像点击事件一样向上传播。这是可行的吗?

没有直接的
.preventDefault()
或一些黑魔法可以阻止您关闭事件侦听器,除非您每次都要创建一个新的处理程序,以便为该模式专门附加一个事件侦听器,而该模式不会干扰其他处理程序

与其拥有一个处理程序数组和大量事件监听器,不如将模态堆叠在一个数组中,然后逐个销毁它们

这是我能想到的最短的代码,请参阅代码中的注释以获得逐步的解释

// Global variable, we use this to store DOM objects.
var modalStack = [];

// My function to create/open my modals.
function openModal() {
    var modalHTML = '<div id="modal-'+modalStack.length+'" class="modal"><button onclick="openModal()">Open modal '+(modalStack.length+1)+'</button></div>'; // I populate the modal with my stuff and assign it an ID containing the current stack size. 
    document.body.insertAdjacentHTML( 'beforeend', modalHTML ); // Add into the body
    modalStack.push( document.getElementById('modal-'+modalStack.length) ); // And push my DOM object I just created into the array.
}


// My ESC event listener
window.addEventListener('keyup', function(event) {
    var lastIndex = modalStack.length-1; // This gets the last element on the stack.
    if (event.keyCode == 27 && lastIndex >= 0) {
        var thisModal = modalStack[ lastIndex ]; // Just to make sense, I could've called the removeChild directly from the array.
        thisModal.parentNode.removeChild(thisModal); // Destroy the current element.
        modalStack.pop(); // Remove the associated last DOM object from the array.
    }
}, false);
//全局变量,我们使用它来存储DOM对象。
var modalStack=[];
//创建/打开模态的My函数。
函数openModal(){
var modalHTML='Open-modal'+(modalStack.length+1)+'';//我用我的东西填充该模式,并为其分配一个包含当前堆栈大小的ID。
document.body.insertAdjacentHTML('beforeend',modalHTML);//添加到正文中
modalStack.push(document.getElementById('modal-'+modalStack.length));//并将我刚刚创建的DOM对象推送到数组中。
}
//我的ESC事件侦听器
window.addEventListener('keyup',函数(事件){
var lastIndex=modalStack.length-1;//这将获取堆栈上的最后一个元素。
如果(event.keyCode==27&&lastIndex>=0){
var thisModal=modalStack[lastIndex];//为了说明问题,我可以直接从数组中调用removeChild。
thisModal.parentNode.removeChild(thisModal);//销毁当前元素。
modalStack.pop();//从数组中删除关联的最后一个DOM对象。
}
},假);

我们可以通过使用数据结构来解决这个问题,该数据结构可用于维护创建和删除的模式窗口的状态

最顶端的模态将是堆栈的顶部/顶部,它将在退出时首先被移除。下面是如何实现这一点的简单演示

最后,不需要额外的努力来创建堆栈实现,JavaScript数组内置了
push
pop
方法,我们将在下面的实现中使用这些方法

var Modal=(函数(){
//只是为了给每种模式提供不同的余量
var基数_保证金=20;
//堆栈,在此数组中,我们将存储所有模态
var modalStack=[];
//创建所有DOM并将其附加到文档正文
函数createModal(){
var modal=document.createElement('div');
modal.className='modal';
modal.style.margin=((modalStack.length+1)*基_边距)+‘px’;
var header=document.createElement('div');
header.className='modalHeader';
header.innerHTML='Level-'+(modalStack.length+1);
var close=document.createElement('div');
close.className='closeModal';
close.innerHTML='X';
close.addEventListener(“单击”,函数(){
var指数=modalStack.indexOf(模态);
对于(var i=modalStack.length-1;i>=index;i--){
var div=modalStack.pop();
//不需要i,因为pop总是得到最后一个元素
文件.正文.删除文件(div);
}
});
header.appendChild(关闭);
var createModalButton=document.createElement(“按钮”);
createModalButton.className='createButton';
createModalButton.addEventListener(“单击”,createModal);
createModalButton.innerHTML=“创建模态”;
modal.appendChild(表头);
modal.appendChild(createModalButton);
document.body.appendChild(模态);
modalStack.push(模态);
}
/**
*应在加载dom时调用
*/
函数初始化(){
文件.附录列表器(“键控”,功能(ev){
如果(ev.keyCode==27){//escape键映射到keyCode`27`
var div=modalStack.pop();
文件.正文.删除文件(div);
}
});
}
返回{
createModal:createModal,
初始化:初始化
}
})();
div.modal{
位置:固定;
顶部:0px;
底部:0px;
左:0px;
右:0px;
利润率:20px;
z指数=100;
背景色:#fff;
边框:2倍实心#333;
}
button.createButton{
显示:块;
保证金:自动;
利润上限:4倍;
}
莫达尔赫德先生{
背景颜色:淡蓝色;
边框底部:1px实心#555;
颜色:白色;
填充:6px 6px 6px 24px;
}
.closeModal{
颜色:红色;
光标:指针;
显示:内联块;
浮动:对;
右边距:14px;
}

我能想到的最简单的方法是只使用JS:

函数openModalOnTop(modalHtml)
{
$modalsContainer=document.getElementById(“modalsContainer”);
var modalContainerTemplate=document.createElement(“div”);
modalContainerTemplate.className=“modal”;
modalContainerTemplate.innerHTML=modalHtml;
$modalContainer.appendChild(modalContainerTemplate);
}
函数closeTopModal()
{
$modalsContainer=document.getElementById(“modalsContainer”);
$modalsContain