制作多个可访问的模态对话框 [英] Making multiple accessible modal dialogs
问题描述
我正在尝试将多个可访问的模式对话框构建到我正在创建的网站中.我一直在使用在以下链接中找到的代码:https://github.com/ireade/accessible-modal-dialog.这对我的目的很有效.键盘命令完全可以访问该框.但是我需要在站点的不同点有多个对话框,每个对话框中都有不同的信息.有谁知道我可能会如何更改 JS 以使其成为可能?我试过,但我不擅长 JS,也没有运气.作为奖励:你知道我如何动画这个对话框以逐渐滚动/出现在屏幕上吗?感谢您的任何帮助!
该库需要稍微重写以使其真正可重用.但是,您可以通过以下方式使用该库:-
- 向打开模态的按钮添加一个额外的类(因此我们可以单独引用每个按钮,这也可以是一个 ID)
- 向对话框添加一个额外的类(以便我们可以单独引用每个对话框)
- 创建一个新的模态并为该新模态添加事件侦听器(也稍微更改旧模态的引用).
我在下面包含了一个小提琴.在 JavaScript 中,我在进行更改的地方添加了注释(滚动到底部以查看包含在 HTML 中的 JavaScript,这是我可以将其用作小提琴的唯一方法,所有顶级 JavaScript 只是库你引用了.)
还要注意在 HTML 中我添加了一个额外的按钮来打开第二个模式并添加第二个模式.密切关注按钮和模态上的类,以及它们与我添加了注释的 JavaScript 的关系.
有任何问题都可以问.
正确的方法.
为了改进这个库,我会在按钮上添加一个 data-target="modalID"
并让它自动连接在一起.
创建一个函数(即function modalInit()
),它将遵循以下步骤:
- 查找具有特定类的所有按钮 (
.open-dialog
) - 查看它的
data-target
(模态ID) - 创建模态 (
new Dialog(IDofModalFromDataTarget, dialogOverlay);
) - 添加事件监听器.(
DialogYouJustCreated.addEventListeners('buttonThatWeFoundTheDataIdOn', '.close-dialog')
可能看起来很吓人,但如果你把它分解成这些步骤,这将是一个很好的学习练习,然后你就可以做到这一点,这样你就可以在未来添加模态,而无需任何额外的代码.
如果你决定尝试这个,请随时发布任何小提琴,我会帮助你.
两个对话框的工作示例.
//忽略上面这部分,向下滚动到'This is the page HTML'功能对话(dialogEl,overlayEl){this.dialogEl = dialogEl;this.overlayEl = overlayEl;this.focusedElBeforeOpen;var focusableEls = this.dialogEl.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([禁用]), [tabindex="0"]');this.focusableEls = Array.prototype.slice.call(focusableEls);this.firstFocusableEl = this.focusableEls[0];this.lastFocusableEl = this.focusableEls[ this.focusableEls.length - 1 ];this.close();//重启}Dialog.prototype.open = function() {var Dialog = this;this.dialogEl.removeAttribute('aria-hidden');this.overlayEl.removeAttribute('aria-hidden');this.focusedElBeforeOpen = document.activeElement;this.dialogEl.addEventListener('keydown', function(e) {Dialog._handleKeyDown(e);});this.overlayEl.addEventListener('click', function() {Dialog.close();});this.firstFocusableEl.focus();};Dialog.prototype.close = function() {this.dialogEl.setAttribute('aria-hidden', true);this.overlayEl.setAttribute('aria-hidden', true);如果(this.focusedElBeforeOpen){this.focusedElBeforeOpen.focus();}};Dialog.prototype._handleKeyDown = function(e) {var Dialog = this;var KEY_TAB = 9;var KEY_ESC = 27;函数 handleBackwardTab() {如果(document.activeElement === Dialog.firstFocusableEl){e.preventDefault();Dialog.lastFocusableEl.focus();}}函数 handleForwardTab() {如果(document.activeElement === Dialog.lastFocusableEl){e.preventDefault();Dialog.firstFocusableEl.focus();}}开关(e.keyCode){案例 KEY_TAB:如果(Dialog.focusableEls.length === 1){e.preventDefault();休息;}if ( e.shiftKey ) {handleBackwardTab();} 别的 {handleForwardTab();}休息;案例 KEY_ESC:Dialog.close();休息;默认:休息;}};Dialog.prototype.addEventListeners = function(openDialogSel, closeDialogSel) {var Dialog = this;var openDialogEls = document.querySelectorAll(openDialogSel);for ( var i = 0; i < openDialogEls.length; i++ ) {openDialogEls[i].addEventListener('click', function() {Dialog.open();});}var closeDialogEls = document.querySelectorAll(closeDialogSel);for ( var i = 0; i < closeDialogEls.length; i++ ) {closeDialogEls[i].addEventListener('click', function() {Dialog.close();});}};//********************这是HTML页面************************//var dialogOverlay = document.querySelector('.dialog-overlay');//对话框覆盖被两者使用,所以我们在这里只需要一个引用.var navDialogEl1 = document.querySelector('.dialog1');//抓取第一个对话框元素var myDialog1 = new Dialog(navDialogEl1, dialogOverlay);//从元素'navDialogEl1'创建一个新对话框.myDialog1.addEventListeners('.open-dialog1', '.close-dialog');//注意我如何更改打开的对话框类 - 我还向与此对话框相关的按钮添加了一个额外的类,具有相同的名称var navDialogEl2 = document.querySelector('.dialog2');//获取第二个对话框元素var myDialog2 = new Dialog(navDialogEl2, dialogOverlay);//为第二个对话框元素创建一个新对话框,注意我如何使用相同的背景(dialogOverlay).myDialog2.addEventListeners('.open-dialog2', '.close-dialog');//添加一个事件监听器来打开这个对话框.再次检查 HTML 我向第二个按钮open-dialog2"添加了一个额外的类.请注意,我还使用了相同的关闭对话框",因为任何带有此类的按钮都应该关闭所有对话框.
.dialog-overlay {z-索引:2;位置:固定;顶部:0;左:0;宽度:100%;高度:100%;背景颜色:RGBA(0,0,0,0.7);}.dialog {z-索引:3;背景色:#fff;填充:20px;文本对齐:居中;宽度:90%;最大宽度:400px;位置:固定;顶部:50%;左:50%;变换:翻译(-50%,-50%);}.dialog-overlay[aria-hidden="true"],.dialog[aria-hidden="true"] {显示:无;}.dialog-overlay:not([aria-hidden="true"]),.dialog:not([aria-hidden="true"]) {显示:块;}.sr-only {不透明度:0;位置:绝对;剪辑:矩形(1px 1px 1px 1px);剪辑:矩形(1px,1px,1px,1px);}
<div class="wrapper"><h1><a href="https://iread.github.io/accessible-modal-dialog/">无障碍对话框</a></h1><button type="button" aria-label="Open Navigation" class="open-dialog1">open 1</button><button type="button" aria-label="Open Navigation" class="open-dialog2">open 2</button>
</标题><div class="dialog dialog1" role="dialog" aria-labelledby="dialog-title" aria-descriptionby="dialog-description"><h1 id="dialog-title">对话框 1</h1><button type="button" aria-label="关闭导航" class="close-dialog">关闭</button>
<div class="dialog dialog2" role="dialog" aria-labelledby="dialog-title" aria-descriptionby="dialog-description"><h1 id="dialog-title">对话框 2</h1><button type="button" aria-label="关闭导航" class="close-dialog">关闭按钮>
<div class="wrapper body-wrapper"><p><a href="https://github.com/ireade/accessible-modal-dialog">查看源码</a>|<a href="=https://bitsofco.de/accessible-modal-dialog">博客帖子</a><p>Venmo 炸玉米饼ennui 连帽衫lomo 凌乱.Meh 讽刺蓝瓶布鲁克林古.后讽刺 PBR&B 蓝瓶,iPhone meh ennui 草料 Salvia normcore neutra Chicharrones gentrify.Banjo Jean 短裤自拍,在 8 位无麸质 pinterest 可持续斜挎包售罄之前尝试一下 venmo,您可能没有听说过它们.Scenester 从农场到餐桌的精酿啤酒,knausgaard 紧身裤凸版早午餐不对称.布鲁克林你可能没有听说过他们打字机法兰绒.Etsy austin venmo、knausgaard 绿汁鱿鱼屠夫康普茶字面意思是胡须牛仔短裤 VHS 手提袋.</p><p>Artisan Bushwick 快闪店,生物柴油病毒符号学陈词滥调 pinterest Fingerstache Godard lo-fi franzen 草料.吊床独角鲸伦理,kogi 在它上面放了一只鸟五花肉布什维克照相亭 +1 大师清洁 pinterest 直接贸易素食豆腐.小批量冷压古狼,滑板不对称信誉纯素腌制 pinterest freegan.男人发髻波特兰男人辫子,雷猫赃物 keffiyeh Scenester 符号学把一只鸟放在上面,钥匙塔四个 loko 胡须倾泻而出.Meh VHS 生物柴油实际上是 poutine,normcore 中性胡须独角鲸连帽衫.Synth 可持续信誉冥想健康乱七八糟.不管是后讽刺的玉米洞场景,正宗的布什维克 keffiyeh venmo kinfolk chia.</p><p>Sriracha XOXO 大师洁面lomo 蓝瓶,banh mi 时尚斧头男编织弹性主义者.Meggings pug ennui,青年布 8 位腹腔绅士化.苦味直接贸易奇亚符号学.Synth fixie mixtape,健康哥特四美元吐司乙烯基 3 狼月亮 VHS schlitz.喝醋凸版 VHS poutine,venmo cronut 酿酒厂工匠.每天随身携带精酿啤酒屠夫DIY.Normcore affogato chillwave、thundercats banh mi 指尖键盘弹出四个 loko 4 美元吐司.</p>
<div class="dialog-overlay" tabindex="-1"></div><!--JavaScript 从这里移到 JavaScript 部分的底部-->