admin管理员组文章数量:1399762
I've a web application with dialogs. A dialog is a simple div-container appended to the body. There is also an overlay for the whole page to prevent clicks to other controls. But: Currently the user can focus controls that are under the overlay (for example an input). Is there any way to limit the tabbable controls to those which are in the dialog?
I am using jQuery (but not using jQueryUI). In jQueryUi dialogs it's working (but I don't want to use jQueryUI). I failed to figure out, how this is acplished there.
Here is the jQueryUI example: .html - The link on the webpage is not focusable. The focus is kept inside the dialog (the user cannot focus the urlbar of the browser using tab).
HTML:
<a href="#test" onclick="alert('Oh no!');">I should not receive any focus</a>
<input type="text" value="No focus please" />
<div class="overlay">
<div class="dialog">
Here is my dialog<br />
TAB out with Shift+Tab after focusing "focus #1"<br />
<input type="text" value="focus #1" /><br />
<input type="text" value="focus #1" /><br />
</div>
</div>
CSS:
.overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
text-align: center;
}
.dialog {
display: inline-block;
margin-top: 30%;
padding: 10px;
outline: 1px solid black;
background-color: #cccccc;
text-align: left;
}
Here is my fiddle: /
Does anybody have an idea? I repeat: I don't want to use jQueryUI for this. I'd like to understand the underlying technique.
I've a web application with dialogs. A dialog is a simple div-container appended to the body. There is also an overlay for the whole page to prevent clicks to other controls. But: Currently the user can focus controls that are under the overlay (for example an input). Is there any way to limit the tabbable controls to those which are in the dialog?
I am using jQuery (but not using jQueryUI). In jQueryUi dialogs it's working (but I don't want to use jQueryUI). I failed to figure out, how this is acplished there.
Here is the jQueryUI example: http://jqueryui./resources/demos/dialog/modal-confirmation.html - The link on the webpage is not focusable. The focus is kept inside the dialog (the user cannot focus the urlbar of the browser using tab).
HTML:
<a href="#test" onclick="alert('Oh no!');">I should not receive any focus</a>
<input type="text" value="No focus please" />
<div class="overlay">
<div class="dialog">
Here is my dialog<br />
TAB out with Shift+Tab after focusing "focus #1"<br />
<input type="text" value="focus #1" /><br />
<input type="text" value="focus #1" /><br />
</div>
</div>
CSS:
.overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
text-align: center;
}
.dialog {
display: inline-block;
margin-top: 30%;
padding: 10px;
outline: 1px solid black;
background-color: #cccccc;
text-align: left;
}
Here is my fiddle: http://jsfiddle/SuperNova3000/weY4L/
Does anybody have an idea? I repeat: I don't want to use jQueryUI for this. I'd like to understand the underlying technique.
Share Improve this question edited Jul 16, 2019 at 14:23 Stephen R 3,9271 gold badge30 silver badges54 bronze badges asked Jun 5, 2014 at 9:33 SuperNovaSuperNova 3,0324 gold badges26 silver badges40 bronze badges2 Answers
Reset to default 5I've found an easy solution for this issue after hours of trying. I think the best way is adding 2 pseudo elements. One before and one after the dialog (inside the overlay). I'm using <a>-Tags which are 0x0 pixels. When reaching the first <a>, I'm focusing the last control in the dialog. When focusing the last <a>, I'm focusing the first control in the dialog.
I've adapted the answer of this post: Is there a jQuery selector to get all elements that can get focus? - to find the first and last focusable control.
HTML:
<div class="overlay">
<a href="#" class="focusKeeper">
<div class="dialog">
Here is my dialog<br />
TAB out with Shift+Tab after focusing "focus #1"<br />
<input type="text" value="focus #1" /><br />
<input type="text" value="focus #1" /><br />
</div>
<a href="#" class="focusKeeper">
</div>
Extra CSS:
.focusKeeper {
width: 0;
height: 0;
overflow: hidden;
}
My Javascript:
$.fn.getFocusableChilds = function() {
return $(this)
.find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object:not([disabled]), embed, *[tabindex], *[contenteditable]')
.filter(':visible');
};
[...]
$('.focusKeeper:first').on('focus', function(event) {
event.preventDefault();
$('.dialog').getFocusableChilds().filter(':last').focus();
});
$('.focusKeeper:last').on('focus', function(event) {
event.preventDefault();
$('.dialog').getFocusableChilds().filter(':first').focus();
});
May be I'll add a fiddle later, no more time for now. :(
EDIT: As KingKing noted below the focus is lost, when clicking outside the control. This may be covered by adding an mousedown handler for the .overlay:
$('.overlay').on('mousedown', function(event) {
event.preventDefault();
event.stopImmediatePropagation();
});
EDIT #2: There's another thing missing: Going outside the document with the focus (for example the titlebar) and than tabbing back. So we need another handler for document which puts back the focus on the first focusable element:
$(document).on('focus', function(event) {
event.preventDefault();
$('.dialog').getFocusableChilds().filter(':first').focus();
});
You can try handling the focusout
event for the .dialog
element, check the e.target
. Note about the e.relatedTarget
here, it refers to the element which receives focus while e.target
refers to the element lossing focus:
var tabbingForward = true;
//The body should have at least 2 input fields outside of the dialog to trap focusing,
//otherwise focusing may be outside of the document
//and we will loss control in such a case.
//So we create 2 dummy text fields with width = 0 (or opacity = 0)
var dummy = "<input style='width:0; opacity:0'/>";
var clickedOutside = false;
$('body').append(dummy).prepend(dummy);
$('.dialog').focusout(function(e){
if(clickedOutside) {
e.target.focus();
clickedOutside = false;
}
else if(!e.relatedTarget||!$('.dialog').has(e.relatedTarget).length) {
var inputs = $('.dialog :input');
var input = tabbingForward ? inputs.first() : inputs.last();
input.focus();
}
});
$('.dialog').keydown(function(e){
if(e.which == 9) {
tabbingForward = !e.shiftKey;
}
});
$('body').mousedown(function(e){
if(!$('.dialog').has(e.target).length) {
clickedOutside = true;
}
});
Demo.
本文标签: javascriptWhat39s the best way to limit focusable controls to current dialogStack Overflow
版权声明:本文标题:javascript - What's the best way to limit focusable controls to current dialog? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744231426a2596355.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论