Set keyboard focus to a div
you can make a div
focusable if you add a tabindex
attribute.
see: http://snook.ca/archives/accessibility_and_usability/elements_focusable_with_tabindex
The tabindex value can allow for some interesting behaviour.
- If given a value of "-1", the element can't be tabbed to but focus can
be given to the element programmatically (using element.focus()).- If given a value of 0, the element can be focused via the keyboard and
falls into the tabbing flow of the document.- Values greater than 0 create a priority level with 1 being the most important.
UPDATE: added a simple demo at http://jsfiddle.net/roberkules/sXj9m/
How can I give keyboard focus to a DIV and attach keyboard event handlers to it?
Sorted - I added tabindex attribute to the target DIV, which causes it to pick up keyboard events, for example
<div id="inner" tabindex="0">
this div can now have focus and receive keyboard events
</div>
Information gleaned from http://www.w3.org/WAI/GL/WCAG20/WD-WCAG20-TECHS/SCR29.html
Is it possible to focus on a div using JavaScript focus() function?
window.location.hash = '#tries';
This will scroll to the element in question, essentially "focus"ing it.
Make div element receive focus
Set the tabindex="0"
on the div
, on the assumption that you want the div
s to receive focus, rather than child elements.
Updated the answer to add a JS Fiddle demo, showing a JavaScript means of achieving this:
var divs = document.getElementsByTagName('div');
for (var i = 0, len = divs.length; i < len; i++){
divs[i].setAttribute('tabindex', '0');
}
JS Fiddle demo.
While composing the demo I found that tabindex="-1"
allows the element to receive mouse-clicks to assign focus, but not keyboard events (through the tab button), however (and as implied in the comment, earlier, by Fabricio Matté, a tabindex="0"
allows for both). So I've used that in the demo, and updated the original answer to reflect that change.
Behavior of tabindex="0"
versus tabindex="-1"
documented here: https://developer.mozilla.org/en-US/docs/Web/Accessibility/Keyboard-navigable_JavaScript_widgets#Using_tabindex
Adding style on div on keyboard focus
There is "focusin" and "focusout" that you would need to toggle classes such as in a menu structure to open/close as you want. See below, when home is focused, the <a>
item under "sub_sub_menu" is given display: block;
by adding the class .expanded
to it. When focus is removed the classes are toggled off in the focusout
event listener.
var menuItems = document.querySelectorAll('li.dir');
Array.prototype.forEach.call(menuItems, function(el, i) {
el.querySelector('a').addEventListener('focusin', function(event) {
event.preventDefault();
this.parentNode.className = "dir menu_hover";
this.setAttribute('aria-expanded', "true");
el.querySelector('div > ul > li > a').className = "expanded";
});
el.querySelector('a').addEventListener('focusout', function(event) {
event.preventDefault();
this.parentNode.className = "dir";
this.setAttribute('aria-expanded', "false");
el.querySelector('div > ul > li > a').className = "";
});
});
.expanded {
color: red;
background-color: black;
display: block;
}
<ul class="primary">
<li class="dir current">
<a href="" title="Home" aria-haspopup="true"><span>Home</span></a>
<div class="sub_menu">
<ul class="sub_sub_menu ">
<li class=" ">
<a href="" title="Test Page"><span>Test Page</span></a>
</li>
</ul>
</div>
</li>
<li class="dir ">
<a href="" title="Our Products" aria-haspopup="true"><span>Our Products</span></a>
<div class="sub_menu">
<ul class="sub_sub_menu ">
<li class=" ">
<a href="" title="Test Products"><span>Test Products</span></a>
</li>
</ul>
</div>
</li>
<li class=" ">
<a href="" title="News"><span>News</span></a>
</li>
</ul>
Focus on div without click in React to enable keyboard navigation on a module
You'll need to fire a focus()
event on the <div>
you want to have focus after it has rendered.
The easiest way to do this is to use React's built-in lifecycle methods. First, create a ref for the element you want to have focus (in this case, the div listening for keyDown events). Then, you can call focus()
on that node in your component's componentDidMount()
method:
class ImageGallery extends React.Component {
construtor(){
super();
// Create the ref in the constructor
this.focusRef = React.createRef();
}
/* your other methods here */
componentDidMount(){
// Focus on the rendered div using the DOM focus() method
this.focusRef.focus();
}
render(){
// Set the ref in your render() method
return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
}
}
Apply :focus-visible when focusing element programatically
Not sure why you want this, and I would advise you to find an other way to do what you want (e.g, why not use only :focus
?).
But for the hack, you can trick the browser in thinking your div is editable, it should* make it trigger its focus-visible
rule.
const focusable = document.getElementById('focusable');
const button = document.getElementById('button');
const onClickHandler = (e) => {
focusable.contentEditable = true;
focusable.focus();
focusable.contentEditable = false;
};
button.addEventListener("click", onClickHandler);
.focusable {
border: 1px solid lightgrey;
outline: none;
}
.focusable:focus {
border: 2px solid red;
}
.focusable:focus-visible {
border: 2px solid blue;
}
<div id="focusable" class="focusable" tabIndex=0>Lol</div>
<button id="button">Focus Lol</button>
How to focus on a specific element when a button is pressed
After trying the solution found here: stackoverflow.com/a/15338848/1783695, that gave me some ideas... This solution worked, but it was also putting the focus on with a mouse click, where I just wanted the focus on keyboard press.
So I ended up with this, and it's working exactly how I needed:
var input = document.getElementById("mobile-menu-toggle");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
$('.heading.focusable')[0].focus();
}
});
Note: I added the class "focusable" and tabindex to the "Navigation" heading (we have more than one "heading" element) so it can focus there:
<span class="heading focusable" tabindex="0">Navigation</span>
How to allow keyboard tab focusing on div
You can't set focus on div
.
You should catch Tab
key press event and set focus on Yes
button manually.
If Yes
button already has focus, then you should focus No
button.
$('body').live('keydown', function(e) {
if (is_dialog_visible) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
if (container.find(".yes").is(":focus")) {
container.find(".no").focus();
} else {
container.find(".yes").focus();
}
}
}
});
How do i set arrow key focus on these button in angular while pressing the left and right arrow keys?
I imagine the code goes from this SO
The "problem" with this approach is that you should focus one HTMLelement before you can use the arrows keys.
We can take another approach: the service subscribe to document.fromEvent('document')
Imagine a service like
import {map,filter,tap} from 'rxjs/operators'
@Injectable({
providedIn: 'root',
})
export class KeyBoardService {
keyBoard:Subject<any>=new Subject<any>();
subscription:Subscription
sendMessage(message:any)
{
this.keyBoard.next(message)
}
init()
{
if (!this.subscription)
this.subscription=fromEvent(document,'keydown').pipe(
filter((e:Event)=>{
const el=document.activeElement
const ev=(e as KeyboardEvent)
//only want if the key is an arrow
const isArrow=ev.keyCode>=37 && ev.keyCode<=40
//and is the "body" or is arrow down and we are not
//in a select or is an "arrow-div"
return isArrow && (el.tagName== 'body' ||
(ev.keyCode==40 && el.tagName!='SELECT') ||
el.getAttribute('arrow-div')==='')
}),
map(e=>{
const obj={element:document.activeElement,action:null}
switch ((e as KeyboardEvent).keyCode) {
case 38:
obj.action='UP'
break;
case 37:
obj.action='LEFT'
break;
case 40:
obj.action='DOWN'
break;
case 39:
obj.action='RIGTH'
break;
}
return obj
})).subscribe(res=>{
this.sendMessage(res)
})
}
destroy()
{
this.subscription.unsubscribe()
this.subscription=null;
}
}
And a directive like
@Directive({
selector: '[arrow-div]',
})
export class ArrowDivDirective {
element:HTMLElement
constructor(private keyboardService: KeyBoardService,
private el: ElementRef, private render: Renderer2) {
this.render.setAttribute(this.el.nativeElement, "tabindex", "0")
this.element=this.el.nativeElement;
}
}
See that, in this case we not use @HotListener, and that the "element" property is the HTMLElement (not the nativeElement)
We can use in our component like
@ViewChildren(ArrowDivDirective) inputs: QueryList<ArrowDivDirective>;
constructor(private keyboardService: KeyBoardService) {}
ngOnInit() {
this.keyboardService.init();
this.keyboardService.keyBoard.subscribe((res) => {
this.move(res);
});
}
move(object: any) {
const inputToArray = this.inputs.toArray();
let index = inputToArray.findIndex((x) => x.element == object.element);
if (index < 0) index = 0;
else {
switch (object.action) {
case 'UP':
index -= this.columns;
break;
case 'DOWN':
index += this.columns;
break;
case 'LEFT':
index--;
break;
case 'RIGTH':
index++;
break;
case 'RIGTH':
index++;
break;
}
}
if (index >= 0 && index < this.inputs.length) {
inputToArray[index].element.focus();
}
}
ngOnDestroy() {
this.keyboardService.destroy();
}
See that it's necesary "initialize" our service (to began the subscription to fromEvent(document,'keydown'),and, in ngOnDestroy, remove the subscription
The new stackblitz
Related Topics
Open Url in New Tab or Reuse Existing One Whenever Possible
How to Get the Title of HTML Page with JavaScript
How to Get a Floating Footer to Stick to the Bottom of the Viewport in Ie 6
How to Change Reactjs Styles Dynamically
Positioning Multiple, Random Sized, Absolutely Positioned Elements So They Don't Overlap
How to Ignore JavaScript Exceptions When Working with Webdriver (Htmlunit, Ruby Bindings)
Convert Special Characters to HTML in JavaScript
Queryselector, Wildcard Element Match
Set a Callback Function to a New Window in JavaScript
How to Make a Radio Button Unchecked by Clicking It
How to Get a Number Value from an Input Field
How to Stop User from Printing Webpages? Using JavaScript or Jquery
How to Detect CSS Flex Wrap Event
How to Reset :After/:Before CSS Rules for an Element