简体   繁体   English

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

[英]Making multiple accessible modal dialogs

I'm trying to build multiple accessible modal dialog boxes into a website I'm creating.我正在尝试将多个可访问的模式对话框构建到我正在创建的网站中。 I've been using the code found at the following link: https://github.com/ireade/accessible-modal-dialog .我一直在使用以下链接中的代码: https://github.com/ireade/accessible-modal-dialog This works well for my purposes.这很适合我的目的。 The box is fully accessible to keyboard commands.键盘命令可以完全访问该框。 But I need to have multiple dialog boxes at different points on the site, with different information in each box.但是我需要在网站的不同位置有多个对话框,每个框中都有不同的信息。 Does anyone know how I might go about altering the JS to make this possible?有谁知道我怎么可能 go 关于改变 JS 使这成为可能? I've tried, but I'm not great with JS and haven't had any luck.我试过了,但我对 JS 不是很好,也没有运气。 And as a bonus: do you know how I might animate this dialog to scroll/appear gradually on the screen?并且作为奖励:你知道我可以如何动画这个对话框以逐渐滚动/出现在屏幕上吗? Thank you for any and all help!感谢您的任何帮助!

The library would need a slight rewrite to make it truly reusable.该库需要稍微重写以使其真正可重用。 However you can use the library as it is by:-但是,您可以通过以下方式使用该库:-

  1. adding an extra class to the button that opens the modal (so we can reference each button individually, this could also be an ID)在打开模式的按钮上添加一个额外的 class (这样我们可以单独引用每个按钮,这也可以是一个 ID)
  2. adding an extra class to the dialog (so we can reference each dialog seperately)在对话框中添加一个额外的 class (这样我们可以单独引用每个对话框)
  3. creating a new modal and adding event listeners for that new modal (also change the references slightly for the old modal).创建一个新的模态并为该新模态添加事件侦听器(也稍微更改旧模态的引用)。

I have included a fiddle below.我在下面包含了一个小提琴。 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 you referenced.). 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你引用了。)。

Also notice in the HTML I added an extra button to open the second modal and add a second modal.另请注意,在 HTML 中,我添加了一个额外的按钮来打开第二个模态并添加第二个模态。 Pay close attention to the classes on the buttons and the modals and how they relate to the JavaScript I have added comments to.密切关注按钮和模式上的类以及它们与我添加了评论的 JavaScript 的关系。

Any questions just ask.任何问题都可以问。

The proper way.正确的方法。

To improve this library I would add a data-target="modalID" to the buttons and have this automatically wire things together.为了改进这个库,我会在按钮上添加一个data-target="modalID"并让它自动连接在一起。

Create a function (ie function modalInit() ) that would follow the following steps:创建一个 function (即function modalInit() ),将遵循以下步骤:

  1. look for all buttons with a certain class ( .open-dialog )查找所有具有特定 class ( .open-dialog ) 的按钮
  2. look at its data-target (ID of the modal)查看它的data-target (模态的 ID)
  3. create the modal ( new Dialog(IDofModalFromDataTarget, dialogOverlay); )创建模态( new Dialog(IDofModalFromDataTarget, dialogOverlay);
  4. add the event listeners.添加事件监听器。 ( DialogYouJustCreated.addEventListeners('buttonThatWeFoundTheDataIdOn', '.close-dialog') ( DialogYouJustCreated.addEventListeners('buttonThatWeFoundTheDataIdOn', '.close-dialog')

Might look scary but if you break it down into those steps it would be a great learning exercise and you would then make it so that you could add modals without any extra code in the future.可能看起来很吓人,但如果你把它分解成这些步骤,这将是一个很好的学习练习,然后你会做到这一点,这样你就可以在将来添加模态而不需要任何额外的代码。

If you do decide to try this feel free to post any fiddles and I will help you.如果您决定尝试这个,请随时发布任何小提琴,我会帮助您。

Working Example for Two Dialogs.两个对话框的工作示例。

 //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