웹접근성 레이어 팝업 포커스 트랩
by hohoya33
HTML
<button class="dialog_open" aria-haspopup="true">상품 퀵뷰</button>
<h3>매일 오전 9시! 특별한 쇼핑을 시작하세요</h3>
<p>SSG 상품을 더욱 알뜰하고 행복한 가격으로 만나는기회!</p>
<p><a href="#">오반장</a>, <a href="#">해피바이러스</a>가 책임질게요</p>
<ul>
<li><a href="#">[도드람한돈 28주년] 전품목 S포인트 20%</a></li>
<li><a href="#">스와치 한정판 SSG 에디션</a></li>
<li><a href="#">[SSG단독]국산 150g 대용량 핫팩 1세트</a></li>
<li><a href="#">닌텐도 스위치 구매시 스타벅스 텀블러 증정</a></li>
<li><a href="#">발뮤다 에어엔진 외 29종 모음딜!</a></li>
<li><a href="#">[이마트 제철과일] 감귤은 안 질린다</a></li>
<li><a href="#">해비아우터 득템찬스 균일가99,900원</a></li>
<li><a href="#">[히트가전]브랜드별 강력추천 건조기/스타일러 기획 딜</a></li>
<li><a href="#">[SSG 단독 판매]아울 핸드메이드 코트</a></li>
<li><a href="#">사각사각 고밀도 면 60수 고급 홑이불커버/베개커버</a></li>
</ul>
<div id="quick_view" class="dialog" role="dialog" aria-modal="true" aria-labelledby="quick_title">
<div class="dialog_content">
<div class="cdtl_col_lft">
<div class="cdtl_item_image"><img src="http://item.ssgcdn.com/85/36/55/item/1000030553685_i1_1200.jpg" width="300" height="300" alt="메인 상품 이미지"></div>
<ul class="cdtl_pager">
<li><a href="#"><img src="http://item.ssgcdn.com/85/36/55/item/1000030553685_i1_60.jpg" alt="첫번째 상품 이미지"></a></li>
<li><a href="#"><img src="http://item.ssgcdn.com/85/36/55/item/1000030553685_i2_60.jpg" alt="두번째 상품 이미지"></a></li>
<li><a href="#"><img src="http://item.ssgcdn.com/85/36/55/item/1000030553685_i4_60.jpg" alt="세번째 상품 이미지"></a></li>
<li><a href="#"><img src="http://item.ssgcdn.com/85/36/55/item/1000030553685_i5_60.jpg" alt="네번째 상품 이미지"></a></li>
</ul>
</div>
<div class="cdtl_col_rgt">
<h2 id="quick_title" class="cdtl_info_tit">맥심 모카골드 카카오프렌즈 한정판</h2>
<div class="cdtl_optprice_wrap">
<div class="cdtl_optprice">
<span class="cdtl_old_price"><span class="blind">판매가 </span><em class="ssg_price">29,800</em> <span class="ssg_tx">원</span></span>
<span class="cdtl_new_price"><span...
CSS
:focus{outline:4px solid #FF0000}
.blind{overflow:hidden;position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;line-height:0;white-space:normal;word-wrap:break-word;word-break:break-all;clip:rect(0,0,0,0)}
.blind:before{display:block;width:0;height:0;font-size:0;content:'\00a0'}
address,caption,cite,code,dfn,em,strong,th,var{font-style:normal}
button{border:0}
.dialog_open{border-radius:2px;display:inline-block;height:36px;line-height:36px;padding:0 16px;vertical-align:middle;font-size:14px;text-decoration:none;color:#fff;background-color:#26a69a;text-align:center;letter-spacing:.5px;cursor:pointer}
.dialog_close{display:inline-block;overflow:hidden;position:absolute;top:0;right:-1px;z-index:10;width:49px;height:49px;background:url(http://static.ssgcdn.com/ui/ssg/img/product/v2/sp_cmqv.png) no-repeat 0 -83px;font-size:0;line-height:0;vertical-align:top}
.dialog{display:none;width:750px;position:fixed;top:50%;left:50%;background:#fff;-webkit-transform: translate(-50%, -50%);-ms-transform: translate(-50%, -50%);transform: translate(-50%, -50%);margin:0;z-index:10;}
.overlay{position:fixed;top:0;left:0;display:none;background-color:rgba(0,0,0,0.5);height:100vh;width:100vw;}
.cdtl_col_lft{display:inline-block;width:300px}
.cdtl_col_rgt{display:inline-block;width:400px}
.cdtl_info_tit{padding-top:20px;font-size:24px;line-height:35px;color:#222;letter-spacing:-.5px;word-wrap:break-word;word-break:break-all}
.cdtl_pager{text-align:center}
.cdtl_pager li{display:inline-block}
.cdtl_optprice_wrap{margin:20px 0}
.cdtl_optprice_wrap > .cdtl_txt_info{margin-top:7px;font-size:15px;line-height:18px;color:#666;letter-spacing:-.5px}
.cdtl_optprice{position:relative;margin-left:-10px}
.cdtl_optprice:after{display:block;clear:both;content:''}
.cdtl_optprice .cdtl_new_price{float:left;margin-left:10px;line-height:48px}
.cdtl_optprice .cdtl_new_price...
JavaScript
var welDialogOpen = $('.dialog_open');
var welDialogClose = $('.dialog_close');
// 마지막 포커스가 있는요소를 저장하기위한 변수
var welLastFocused;
welDialogOpen.on('click', function(){
showModal();
});
function showModal() {
// 마지막 포커스된 요소 저장
welLastFocused = document.activeElement;
$('#quick_view').show().attr('tabindex', '0').focus();
$('#quick_view').on('keydown', trapTabKey);
welDialogClose.one('click', hideModal);
$('#overlay').show();
}
function hideModal() {
$('#quick_view').hide().removeAttr('tabindex');
$('#quick_view').off('keydown', trapTabKey);
welLastFocused.focus();
$('#overlay').hide();
}
function trapTabKey(e) {
var aFocusable = $('#quick_view').find('*').filter('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]');
var firstTabStop = aFocusable[0];
var lastTabStop = aFocusable[aFocusable.length - 1];
//$('#quick_view').find('*').filter(':focusable');
if (e.keyCode === 9) {
if (!aFocusable.length) {
e.preventDefault();
}
// SHIFT + TAB
if (e.shiftKey) {
if (document.activeElement === firstTabStop) {
e.preventDefault();
lastTabStop.focus();
}
// TAB
} else {
if (document.activeElement === lastTabStop) {
e.preventDefault();
firstTabStop.focus();
}
}
}
// ESC
if (e.keyCode === 27) {
hideModal();
}
}