How to write conditions for an automatic mouse click in the UI when we press any key on the keyboard.
I'm Working on the Accessibility Part ->
My Scenario is we are having banner which is displayed when the page loads initially. for that until we close that banner the focus should be inside that banner.
I have tried the onKeyDown event. when we trigger the onKeyDown event by using e.preventDefault() the focus is hidden. I need to get that focus again when I click any key on the keyboard.
Thanks in Advance.
handleTab = (e) => {
let tabKey = false
if (e.keyCode === 9) {
e.preventDefault()
tabKey = true
}
if(tabKey) {
# here I need an automatic browser click event. so that when I hit the tab key it will go inside of that banner
}
onKeyDown = {this.handleTab()}
Try to use tabindex property to prevent tab navigation outside the banner.
<input type="text" tabIndex="-1"/>
I created small demo to test: https://codepen.io/mich_life/pen/vYRMpqe
This is what the MDN documentation has to say about keyCode:
Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
key which is a textual representation of the pressed key should be used instead & has been supported since Internet Explorer 9.
Since you haven't specified, if the banner is inside or outside your component, I am going by outside.
handleTab=(evt)=> {
if(evt.key == 'Tab') {
evt.preventDefault();
document.getElementById('banner').focus();
}
}
If it's rendered inside your component, use a ref instead.
Related
I'm struggling to disable default taphold browser event. Nothing that I have found on Google provided any help. I have only Android 4.4.4 mobile and Chrome dev tools for testing. I tried CSS fixes, such as webkit-touch-callout and others, but apparently they don't work for Android, also they don't work in Chrome dev tools.
I also tried detecting right click, (e.button==2), it doesn't work.
I came up with a solution, but it solves one problem and creates another. I just want to have a custom action for 'long press' event for selected anchors and I don't want the default pop up to appear (open in a new tab, copy link address, etc.)
This is what I did:
var timer;
var tap;
$("body").on("touchstart", my_selector, function(e) {
e.preventDefault();
timer = setTimeout(function() {
alert('taphold!');
tap=false;
},500);
});
$("body").on("touchend", my_selector, function() {
if(tap) alert('tap');
else tap=true;
clearTimeout(timer);
});
It successfully disables the default taphold event and context menu doesn't appear. However it also disables useful events, such as swipe. The links are in a vertical menu and the menu is higher than the screen, so a user has to scroll it. If he tries to scroll, starting on an anchor, it won't scroll, it will alert 'tap!'
Any ideas how could I disable taphold default or how could I fix this code so it disables only tap events and leave default swipe events enabled?
Edit: Now I thought about setting a timeout, if the pointer is in the same place for lets say 100ms, then prevent default action. However e.preventDefault(); doesn't work inside setTimeout callback.
So now I'm just asking about the simplest example. Can I prevent default actions after certain amount of time has passed (while the touch is still there).
And this is my whole problem in a fiddle. http://jsfiddle.net/56Szw/593/
This is not my code, I got this from http://www.gianlucaguarini.com/blog/detecting-the-tap-event-on-a-mobile-touch-device-using-javascript/
Notice that while swiping the box up and down, scrolling doesn't work.
I got the solution. It was so simple! I had no idea there's an oncontextmenu event. This solves everything:
$("body").on("contextmenu", my_selector, function() { return false; });
For an <img> I had to use event.preventDefault() instead of return false.
document.querySelector('img').addEventListener('contextmenu', (event) => {
event.preventDefault();
}
I'm writing code in JavaScript, targeting Chrome.
Now, consider what happens when:
I press Space/Backspace on a webpage vs
I press Space/Backspace on a textbox
BY using (goog.events.listen js/document.body ...) I can listen for Space/Baskspace events and react on them. However, the browse still processes them i.e. when I press Space the browser still scrolls down and when I press Basckspace, the browser goes to the previous webpage.
I would like to prevent this "default behavior" -- i.e. I want to process the Space/Backspace events, and I want the browser to ignore them.
Thanks!
Return false from the event handler to cancel the event.
document.body.onkeydown = function killSpace(e) {
if (e.keyCode === 32) {
return false;
}
};
Please don't kill keyboard shortcuts globally like this. It hurts usability. Only prevent default behaviour when some custom widget on the page has focus, and this element can lose focus using a keyboard shortcut like tab.
I'm building my first application where I have to have compliance with keyboard navigation for accessibility reasons.
My problem has to do jquery-ui modal dialog boxes. If the user presses tab on the last control of the dialog (cancel button for this app), focus goes outside of the dialog box. Or presses shift-tab on the first control in the dialog box.
When the user does this, it isn't always possible to tab back into dialog box. IE8 and FF8 behave somewhat differently in this respect. I've tried to capture the tab key with the following event handler -
lastButton.keydown(function (e) {
if (e.which === TAB_KEY_CODE) {
e.stopPropagation();
$(this).focus();
}
});
But this doesn't work as it appears the browser processes the key press after jquery is done.
Two questions -
For Accessibility compliance, do I even have to worry about this? Although, for usability reasons, I think that I should.
Is there a way to make this work?
My problem has to do jquery-ui modal dialog boxes. If the user presses tab on the last control of the dialog (cancel button for this app), focus goes outside of the dialog box. Or presses shift-tab on the first control in the dialog box.
... and then tabbing occurs below the modal box, under a grey semi-transparent layer with scrollbar jumping from bottom to top after a few keypresses? Yes, this is a concern for sighted users who use the keyboard to browse and won't know how to go back to the modal box without pressing Tab a hundred times. Blind people won't even know the modal box is still displayed (they still can see/hear the entire DOM with their screen reader!) and that the page/script is waiting for a submit or cancel decision so it's also a concern for them.
An example done right is shown at http://hanshillen.github.com/jqtest/#goto_dialog (click on Dialog tab, direct link with anchor doesn't work :/ ). It'll tab forever inside the modal box till you click on Close or OK and will put you back on the focused element that triggered the modal box (I think it should focus the next focusable element after leaving the modal box but nevermind, this isn't the biggest accessibility problem here).
This serie of scripts is based on jQueryUI and are highly improved for keyboard and ARIA support and any accessibility problem that could exist in the original scripts. Highly recommended! (I tried to mix jQuery UI original scripts and these ones but didn't manage to get anything working, though you don't need to do so: these scripts work fine by themselves)
Maybe you should prevent the default action with preventDefault() instead of stopping the propagation and use keypress instead of keydown.
In this way there should be no need to regain focus.
Stopping the propagation doesn't work because it just prevent the event from bubbling up. You could think about using stopImmediatePropagation() but i think that changing input on the pression of the tab can't be stopped that way and preventDefault() is more correct.
lastButton.keypress(function (e) {
if (e.which === TAB_KEY_CODE) {
e.preventDefault();
}
});
fiddle here: http://jsfiddle.net/jfRzM/
Im a little late to the party, but I found I had to call preventDefault in the other keyboard events as well.
ex) I was setting the focus in the keyup event. But the browser was still doing its thing in either keydown or keypress. So I had something like this (I used JQuery/Typescript, but the idea should translate to about anything):
elem.keyup(this.onDialogKeyPress);
elem.keydown(this.onDialogPressPreventDefault);
elem.keypress(this.onDialogPressPreventDefault);
...
private onDialogPressPreventDefault = (e: KeyboardEvent) => {
const keys = [9, 27];
if (keys.includes(e.which)) {
e.preventDefault();
return false;
}
}
private onDialogKeyPress = (e: KeyboardEvent) => {
// Tab
if (e.which == 9) {
e.preventDefault();
// Do tab stuff
return false;
}
// Esc
else if (e.which == 27) {
e.preventDefault();
// Do Esc stuff
return false;
}
}
I'm trying to add keyboard shortcuts on my website to make fast navigation possible using the keyboard. I'm running into a slight problem, however, with my attempted Alt+X shortcut. The event runs just fine and returns false as it should, but the browser's File menu comes up regardless. I've also tried the preventDefault method, but no change.
The cut-down version of the script is:
document.documentElement.onkeydown = function(e) {
e = e || window.event;
switch( e.keyCode || e.which) {
// some cases here - most notably:
case 116: // F5 key
if( activeFrame) {
activeFrame.contentWindow.location.reload();
// reloads an iframe if one is active
return false;
}
break;
// more cases...
case 88: // X key
if( e.altKey) {
// do something
return false;
}
}
}
As noted above, overriding the default action of the F5 key works just fine - the browser reloads the page only if no iframe is active. I don't quite see how to prevent the menu from appearing when Alt+X is pressed.
use stopPropagation(e); instead of preventDefault method
function stopPropagation(e)
{
e = e || event;/* get IE event ( not passed ) */
e.stopPropagation? e.stopPropagation() : e.cancelBubble = true;
}
Reference link
Another SO question which mentions that preventDefault has issue in IE.
UPDATE
Try using below code as per MSDN Reference
event.returnValue=false;
And some point from Detecting keystrokes
Some general caveats:
Generally, Mac is less reliable than Windows, and some keys cannot be detected.
Explorer doesn't fire the keypress event for delete, end, enter, escape, function keys, home, insert, pageUp/Down and tab.
Onkeypress, Safari gives weird keyCode values in the 63200 range for delete, end, function keys, home and pageUp.Down. The onkeydown and -up values are normal.
Alt, Cmd, Ctrl and Shift cannot be detected on Mac, except in Opera. However, you can always use the altKey, ctrlKey, and shiftKey properties.
I actually had a web app working just fine with CTRL shortcut keys, but then decided I'd be clever and use the accesskey attribute, and ran into this exact issue with IE.
The problem with going to CTRL shortcut keys is that many of those are more standard/useful across many applications (eg: cut, copy, paste, select all).
Ctrl+Alt is fairly safe, but requires more work on the user's part.
I tend to just try to stick to ALT shortcuts IE doesn't stubbornly insist on handling.
Demo of CTRL + A/CTRL + F being cancelled successfully:
http://jsfiddle.net/egJyT/
This answer seems to imply it isn't possible to disable the menu shortcuts without putting IE into kiosk mode.
Beware that if you manage to successfully prevent the browser from detecting a key combination you may make your page unusable for some users. Many screen readers have reserved almost any key you can think of to control the screen reader and if your page was accessible using a screen reader before you added the shortcut key code, it may be completely un-accessible users needing screen readers after you add it.
Read this article about access keys (a bit old but probably still relevant), and this article about Reserved Keystroke Combinations before you invest too much time on this problem.
Does anyone know of crossbrowser equivalent of explicitOriginalTarget event parameter? This parameter is Mozilla specific and it gives me the element that caused the blur. Let's say i have a text input and a link on my page. Text input has the focus. If I click on the link, text input's blur event gives me the link element in Firefox via explicitOriginalTarget parameter.
I am extending Autocompleter.Base's onBlur method to not hide the search results when search field loses focus to given elements. By default, onBlur method hides if search-field loses focus to any element.
Autocompleter.Base.prototype.onBlur = Autocompleter.Base.prototype.onBlur.wrap(
function(origfunc, ev) {
var newTargetElement = (ev.explicitOriginalTarget.nodeType == 3 ? ev.explicitOriginalTarget.parentNode: ev.explicitOriginalTarget); // FIX: This works only in firefox because of event's explicitOriginalTarget property
var callOriginalFunction = true;
for (i = 0; i < obj.options.validEventElements.length; i++) {
if ($(obj.options.validEventElements[i])) {
if (newTargetElement.descendantOf($(obj.options.validEventElements[i])) == true || newTargetElement == $(obj.options.validEventElements[i])) {
callOriginalFunction = false;
break;
}
}
}
if (callOriginalFunction) {
return origFunc(ev);
}
}
);
new Ajax.Autocompleter("search-field", "search-results", 'getresults.php', { validEventElements: ['search-field','result-count'] });
Thanks.
There is no equivalent to explicitOriginalTarget in any of the other than Gecko-based browsers. In Gecko this is an internal property and it is not supposed to be used by an application developer (maybe by XBL binding writers).
2015 update... you can use event.relatedTarget on Chrome. Such a basic thing, hopefully the other browsers will follow...
The rough equivalent for Mozilla's .explicitOriginalTarget in IE is document.activeElement. I say rough equivalent because it will sometimes return a slightly different level in the DOM node tree depending on your circumstance, but it's still a useful tool. Unfortunately I'm still looking for a Google Chrome equivalent.
IE srcElement does not contain the same element as FF explicitOriginalTarget. It's easy to see this: if you have a button field with onClick action and a text field with onChange action, change the text field and move the cursor directly to the button and click it. At that point the IE srcElement will be the text field, but the explicitOriginalTarget will be the button field. For IE, you can get the x,y coordinates of the mouse click from the event.x and event.y properties.
Unfortunately, the Chrome browser provides neither the explicitOriginalTarget nor the mouse coordinates for the click. You are left to your own devices to figure out where the onChange event was fired from. To do this, judicious use of mousemove and mouseout events can provide mouse tracking which can then be inspected in the onChange handler.
Looks like it is more designed for extension writers than for Web design...
I would watch the blur/focus events on both targets (or potential targets) and share their information.
The exact implementation might depend on the purpose, actually.
For IE you can use srcElement, and forced it.
if( !selectTag.explicitOriginalTarget )
selectTag.explicitOriginalTarget = selectTag.srcElement;
In case of form submit events, you can use the submitter property in all modern browser (as of 2022).
let form = document.querySelector("form");
form.addEventListener("submit", (event) => {
let submitter = event.submitter; //either a form input or a submit button
});