繁体   English   中英

制作多个可访问的模式对话框

[英]Making multiple accessible modal dialogs

我正在尝试将多个可访问的模式对话框构建到我正在创建的网站中。 我一直在使用以下链接中的代码: https://github.com/ireade/accessible-modal-dialog 这很适合我的目的。 键盘命令可以完全访问该框。 但是我需要在网站的不同位置有多个对话框,每个框中都有不同的信息。 有谁知道我怎么可能 go 关于改变 JS 使这成为可能? 我试过了,但我对 JS 不是很好,也没有运气。 并且作为奖励:你知道我可以如何动画这个对话框以逐渐滚动/出现在屏幕上吗? 感谢您的任何帮助!

该库需要稍微重写以使其真正可重用。 但是,您可以通过以下方式使用该库:-

  1. 在打开模式的按钮上添加一个额外的 class (这样我们可以单独引用每个按钮,这也可以是一个 ID)
  2. 在对话框中添加一个额外的 class (这样我们可以单独引用每个对话框)
  3. 创建一个新的模态并为该新模态添加事件侦听器(也稍微更改旧模态的引用)。

我在下面包含了一个小提琴。 In the JavaScript I have added comments where I have made changes (scroll to the bottom to see the JavaScript that was included within the HTML, it was the only way I could make this work as a fiddle, all the top JavaScript is just the library你引用了。)。

另请注意,在 HTML 中,我添加了一个额外的按钮来打开第二个模态并添加第二个模态。 密切关注按钮和模式上的类以及它们与我添加了评论的 JavaScript 的关系。

任何问题都可以问。

正确的方法。

为了改进这个库,我会在按钮上添加一个data-target="modalID"并让它自动连接在一起。

创建一个 function (即function modalInit() ),将遵循以下步骤:

  1. 查找所有具有特定 class ( .open-dialog ) 的按钮
  2. 查看它的data-target (模态的 ID)
  3. 创建模态( new Dialog(IDofModalFromDataTarget, dialogOverlay);
  4. 添加事件监听器。 ( DialogYouJustCreated.addEventListeners('buttonThatWeFoundTheDataIdOn', '.close-dialog')

可能看起来很吓人,但如果你把它分解成这些步骤,这将是一个很好的学习练习,然后你会做到这一点,这样你就可以在将来添加模态而不需要任何额外的代码。

如果您决定尝试这个,请随时发布任何小提琴,我会帮助您。

两个对话框的工作示例。

 //Ignore this top part, scroll down to 'This is the page HTML' function Dialog(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([disabled]), [tabindex="0"]'); this.focusableEls = Array.prototype.slice.call(focusableEls); this.firstFocusableEl = this.focusableEls[0]; this.lastFocusableEl = this.focusableEls[ this.focusableEls.length - 1 ]; this.close(); // Reset } 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); if ( this.focusedElBeforeOpen ) { this.focusedElBeforeOpen.focus(); } }; Dialog.prototype._handleKeyDown = function(e) { var Dialog = this; var KEY_TAB = 9; var KEY_ESC = 27; function handleBackwardTab() { if ( document.activeElement === Dialog.firstFocusableEl ) { e.preventDefault(); Dialog.lastFocusableEl.focus(); } } function handleForwardTab() { if ( document.activeElement === Dialog.lastFocusableEl ) { e.preventDefault(); Dialog.firstFocusableEl.focus(); } } switch(e.keyCode) { case KEY_TAB: if ( Dialog.focusableEls.length === 1 ) { e.preventDefault(); break; } if ( e.shiftKey ) { handleBackwardTab(); } else { handleForwardTab(); } break; case KEY_ESC: Dialog.close(); break; default: break; } }; 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(); }); } }; //*****************This is the page HTML*********************// var dialogOverlay = document.querySelector('.dialog-overlay'); //dialog overlay is used by both so we only need one reference to it here. var navDialogEl1 = document.querySelector('.dialog1');//grab the first dialog element var myDialog1 = new Dialog(navDialogEl1, dialogOverlay); //create a new dialog from the element 'navDialogEl1'. myDialog1.addEventListeners('.open-dialog1', '.close-dialog'); //notice how I changed the open dialog class - I also added an extra class to the button that is related to this dialog with the same name var navDialogEl2 = document.querySelector('.dialog2'); //grab the second dialog element var myDialog2 = new Dialog(navDialogEl2, dialogOverlay); //create a new dialog for the second dialog element, notice how I use the same background (dialogOverlay). myDialog2.addEventListeners('.open-dialog2', '.close-dialog'); //add an event listener to open this dialog. Yet again check the HTML I added an extra class to the second button 'open-dialog2'. Notice how I also used the same 'close-dialog' as any button with this calss should close all dialogs anyway.
 .dialog-overlay { z-index: 2; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.7); }.dialog { z-index: 3; background-color: #fff; padding: 20px; text-align: center; width: 90%; max-width: 400px; position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%); }.dialog-overlay[aria-hidden="true"], .dialog[aria-hidden="true"] { display: none; }.dialog-overlay:not([aria-hidden="true"]), .dialog:not([aria-hidden="true"]) { display: block; }.sr-only { opacity: 0; position: absolute; clip: rect(1px 1px 1px 1px); clip: rect(1px, 1px, 1px, 1px); }
 <header> <div class="wrapper"> <h1><a href="https://ireade.github.io/accessible-modal-dialog/">Accessible 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> </header> <div class="dialog dialog1" role="dialog" aria-labelledby="dialog-title" aria-describedby="dialog-description"> <h1 id="dialog-title">Dialog 1</h1> <button type="button" aria-label="Close Navigation" class="close-dialog"> Close </button> </div> <div class="dialog dialog2" role="dialog" aria-labelledby="dialog-title" aria-describedby="dialog-description"> <h1 id="dialog-title">Dialog 2</h1> <button type="button" aria-label="Close Navigation" class="close-dialog"> Close</button> </div> <div class="wrapper body-wrapper"> <p><a href="https://github.com/ireade/accessible-modal-dialog">View Source</a> | <a href="=https://bitsofco.de/accessible-modal-dialog">Blog Post</a> <p>Venmo tacos ennui hoodie lomo tousled. Meh irony blue bottle brooklyn paleo. Post-ironic PBR&B blue bottle, iPhone meh ennui forage salvia normcore neutra chicharrones gentrify. Banjo jean shorts selfies, try-hard venmo before they sold out 8-bit gluten-free pinterest sustainable messenger bag you probably haven't heard of them poutine. Scenester farm-to-table craft beer, knausgaard leggings letterpress brunch asymmetrical. Brooklyn you probably haven't heard of them typewriter flannel. Etsy austin venmo, knausgaard green juice squid butcher kombucha literally beard jean shorts VHS tote bag.</p> <p>Artisan bushwick pop-up, biodiesel viral semiotics cliche pinterest fingerstache godard lo-fi franzen forage. Hammock narwhal ethical, kogi put a bird on it pork belly bushwick photo booth +1 master cleanse pinterest direct trade vegan tofu. Small batch cold-pressed paleo wolf, skateboard asymmetrical cred vegan pickled pinterest freegan. Man bun portland man braid, thundercats swag keffiyeh scenester semiotics put a bird on it keytar four loko beard pour-over. Meh VHS biodiesel actually poutine, normcore neutra beard narwhal hoodie. Synth sustainable cred meditation health goth tousled. Post-ironic cornhole scenester whatever, authentic bushwick keffiyeh venmo kinfolk chia.</p> <p>Sriracha XOXO master cleanse lomo blue bottle, banh mi fashion axe man braid flexitarian. Meggings pug ennui, chambray 8-bit celiac gentrify. Bitters direct trade chia semiotics. Synth fixie mixtape, health goth four dollar toast vinyl 3 wolf moon VHS schlitz. Drinking vinegar letterpress VHS poutine, venmo cronut distillery artisan. Everyday carry craft beer butcher DIY. Normcore affogato chillwave, thundercats banh mi fingerstache keytar pop-up four loko four dollar toast.</p> </div> <div class="dialog-overlay" tabindex="-1"></div> <!--JavaScript moved from here to the bottom of the JavaScript section-->

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM