Hi I'm currently working on a reactjs web application and trying to provide accessibility features in web pages. In one page there's a drawer popping up once a button clicked, and I wanted to make sure the tab navigation only through the drawer without going outside of the drawer when it expanded. How can I do that?
Here I have attached the screen shot of the page including the expanded drawer.
I'd recommend writing a keyboard handler in JavaScript to restrict tab order to the pop-out "drawer" (or modal as I'd call it).
Hidde de Vries wrote an excellent short tutorial on this, see here.
I adapted this very slightly:
// Function to trap tab movement to a specific container element
trapFocusInArtworkModal = function (el) {
// Gather all focusable elements in a list
var query = "a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type='email']:not([disabled]), input[type='text']:not([disabled]), input[type='radio']:not([disabled]), input[type='checkbox']:not([disabled]), select:not([disabled]), [tabindex='0']"
var focusableEls = el.querySelectorAll(query);
var firstFocusableEl = focusableEls[0];
var lastFocusableEl = focusableEls[focusableEls.length - 1];
// Add the key listener to the modal container to listen for Tab,
// Left Arrow, Right Arrow, Enter and Escape
el.addEventListener('keydown', function(e) {
var isTabPressed = (e.key === "Tab" || e.keyCode === KEYCODE_TAB);
var isEscPressed = (e.key === "Escape" || e.keyCode === KEYCODE_ESCAPE);
// Define behaviour for Tab or Shift+Tab
if (isTabPressed) {
// Shift+Tab
if (e.shiftKey) {
if (document.activeElement === firstFocusableEl) {
// Move keyboard focus to the last focusable element in the container
lastFocusableEl.focus();
e.preventDefault();
}
}
// Tab
else {
if (document.activeElement === lastFocusableEl) {
// Move keyboard focus to the first focusable element in the container
firstFocusableEl.focus();
e.preventDefault();
}
}
}
// Define behaviour for Escape
if (isEscPressed) {
// This will close out the modal when the Escape key is pressed
// by clicking the modal's close link/button
el.querySelector("a").click();
}
});
};
// Find the modal
var modal = document.querySelector("[role='dialog']");
// Attach the trap keyboard function to the modal
trapFocusInArtworkModal(modal);
You can then attach the code to run when the page has loaded.
Related
I have a pop up menu that appears when the users name is hovered over using onmouseeneter and the menu disapeers when onmouseleave is triggerd.
The problem i have is that on occasion the mouseleave is not triggered and the menu stays showing, which is ok but i require another check to see if mouse is within the div on mouse move. and also a click event to close the div if the click is outside of the div.
How can i check weather a click or a mousemove is within a div or not.
I have tried the following with no luck. allthough the code is fine i require another way.
<div id='overlay' class='overlay' style='display:none;'
onmouseover='showoverlay();' onmouseleave='removeoverlay();'> </div>
function showoverlay() {
var overlay=document.getElementById("overlay");
overlay.style.display="block";
overlay.style.zIndex="999";
overlay.style.opacity="1";
}
function removeoverlay() {
var overlay = document.getElementById("overlay");
overlay.style.opacity="0";
overlay.style.display="none"
overlay.style.zIndex="-999";
}
$(document).ready(function(){
$(document).mouse(function(e)
{
var subject = $("#overlay");
if(e.target.id != subject.attr('id') &&
!subject.has(e.target).length)
{
removeoverlay();
}
});
});
You can use is jQuery function like so:
$(function() {
$('ul').on('click', function (event) {
let target = $(event.target);
let handle = $(this).find('i');
let checkbox = $(this).find('input[type=checkbox]');
if (false === target.is(handle) && false === target.is(checkbox)) {
checkbox.prop('checked', !checkbox.prop('checked'));
}
});
});
I have a form in a modal dialog. After submiting a form that dialog closes and does some actions in the background. After closing the modal dialog I also want to update html in the sidebar (without refreshing the sidebar). I have a div with "loader" id in the sidebar with class hidden (which prevents it to be visible). On modal dialog close I want to remove class hidden from the "loader" div. How do I access that "loader" div from the modal dialog template?
You could use the browser sessionStorage, set a timer, and continuously "poll" for available information.
Thanks to a comment, a variation was suggested which eliminates the need for polling:
jquery
$(window).bind('storage',
function(e){if(e.key === "newValuesWereEntered"){doSomething()}});
Script tag:
<script>
//Use a timer to keep checking for a completed action from another dialog
var theTimer;
window.setTheTimer = function() {
//To Do - Hide the Spinner
if (typeof(Storage) === "undefined") {
alert('HTML5 Storage is not supported. This App will not work in this browser. Please update your browser.');
return;
}
try {
window.sessionStorage.setItem("newValuesWereEntered","n"); //Make sure check value is reset
} catch(e) {
alert(e.error + ' You may have this apps cookies blocked in this browser, and/or this browser tab. Check cookie blocking.');
return;
};
theTimer = window.setInterval(monitorForTheResponse, 500); //Every 1/2 second, check for response value
};
window.monitorForTheResponse = function() {
var was_a_newValueEntered,dlgInfo;
was_a_newValueEntered = window.sessionStorage.getItem("newValuesWereEntered");
if (was_a_newValueEntered === 'y') {//Dialog just wrote value to window.sessionStorage
window.sessionStorage.setItem("newValuesWereEntered","n");//Reset
clearTimeout(theTimer);//turn off timer
//Get submitted values
dlgInfo = window.sessionStorage.getItem("newValuesToTransfer");
//To Do - Run code to display new value
};
};
</script>
The dialog that has the value to pass to the sidebar must save that value to session storage
window.theValueWasSavedOrEntered = function() {
var arry,objectOfNewValues,strJSON;
try{
if (typeof(Storage) !== "undefined") {//Browser has local storage
window.sessionStorage.setItem("newValuesWereEntered","y"); //Set to yes
objectOfNewValues = {};
objectOfNewValues.valueOne = arry[0];
objectOfNewValues.valueTwo = arry[1];
strJSON = JSON.stringify(objectOfNewValues);
window.sessionStorage.setItem("newValuesWereEntered","y"); //Set to yes
window.sessionStorage.setItem("newValuesToTransfer", strJSON);
};
google.script.host.close();
} catch(e) {
SendErr({'message':'ERROR: ' + e.stack + ' message: ' + e.message});
};
};
I have a javascript popup context menu with a button below it with close. That button when pressed close will continue to the next page. If a user dont click the close button and decides to click outside the popup box it will not redirect the user. What function for javascript can i add if a user click outside the box it will redirect them without clicking the close button inside the box. using a osx-modal-content plugin
How its triggered*
<input type='button' name='osx' value='Click Here To Enter The Website!' class='osx demo'/></a>
plugin page (link)
OSX STYLE DIALOG ** OSX STYLE DIALOG ** OSX STYLE DIALOG **
http://www.ericmmartin.com/projects/simplemodal-demos/
This is something that i have for the close function**
close: function (d) {
var self = this; // this = SimpleModal object
d.container.animate(
{top:"-" + (d.container.height() + 20)},
500,
function () {
self.close(); // or $.modal.close();
}
This is how you can do stuff on close:
$("#element-id").modal({
onClose: function () {
window.location.href = "http://stackoverflow.com";
}
});
If you had an element added like:
// Load dialog on click
$('#basic-modal .basic').click(function (e) {
$('#basic-modal-content').modal();
return false;
});
Change that to
// Load dialog on click
$('#basic-modal .basic').click(function (e) {
$('#basic-modal-content').modal({
onClose: function () {
window.location.href = "http://stackoverflow.com";
}
});
return false;
});
WHAT I HAVE:
3 buttons
when one is clicked it gets hidden and its corresponding box is shown
in each box is a link to close the box
when clicked the box hides
WHAT I NEED:
when the close link is clicked and the box closes, i need the button to be shown again
SUMMARY:
button click toggles button hide / box show, close click toggles box hide / button show
current code
you just needed to add $('.showSingle').removeClass('selected'); to the $('.hide').click() function and add a return false at the end of it so that the link's href doesnt get called (putting the # in the url) I also rewrote the first click event so that its consistent with the second.
$(function(){
$('.showSingle').click(function() {
$(this).addClass('selected').siblings().removeClass('selected');
$('.targetDiv').hide();
$('#div' + $(this).data('target')).show();
});
$('.hide').click(function() {
$('.targetDiv').hide();
$('.showSingle').removeClass('selected');
return false;
});
});
When you click on each button you have a call that adds the class 'selected' to the button pressed and removes the same from all other buttons. This class is making the button hidden. What you need to do then is when the close link is pressed, remove the class from all buttons.
$('.hide').click(function() {
$('.targetDiv').hide();
$('.showSingle').removeClass('selected');
});
Try this.
$(window).load(function(){
$('.showSingle').on('click', function () {
$(this).addClass('selected').siblings().removeClass('selected');
$('.targetDiv').hide();
var srcId = $(this).data('target');
$('#div' + srcId).show();
$('.targetDiv').click(function(){
$('.targetDiv').hide();
$(".showSingle[data-target='" +srcId +"']").show();
});
});
Here's a code that work with your current HTML. It comes with two options, hide the button text or hide the button itself. Also as a side note, if you use on() keep using it--don't switch to .click()
JSFiddle Demo
$(function() {
$('.targetDiv').hide(); //Start off with boxes hidden
$('.showSingle').on('click', function() { //Link clicked
$('.targetDiv').hide(); //Hide any open boxes
$('.selected').removeClass('selected'); //Show all buttons
//$(this).children('div').addClass('selected'); //Hide button text
$(this).addClass('selected'); //Hide button box
var id = $(this).data('target'); //Get desired target
$('#div'+id).show(); //Show target box
return false; //Stop link from going anywhere
});
$('.hide').on('click', function() {
$('.targetDiv').hide(); //Hide any open boxes
$('.selected').removeClass('selected'); //Show all buttons
return false; //Stop link from going anywhere
});
});
I'm thinking about making a website for my business where all the content is on one long page which the user will not be able to scroll through and you will have to navigate through the site by clicking the buttons which will then animate between the anchor points to the next page. I'm will make a long image with the home point being an office and the user then can go up into the sky then space for different pages.
So how would I stop the user from being able to scroll and how would I make it animate or slowly scroll between each anchor. Would it be possible to scroll horizontally as well?
I would try to solve your problem by disabling temporally the scrolling functionality of the browser. You can achieve this by unbinding any event listeners associated with keypress or mouse scroll.
You can deny the mouse scroll to get triggered by preventing it's default action associated with the event handler. Technically this is how can be done in Javascript:
window.onload = function() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', disableScroll, false);
} else if (window.attachEvent) { //IE event handler
window.attachEvent('DOMMouseScroll', disableScroll);
} else {
window.onscroll = disableScroll;
}
}
function disableScroll(event) {
event = event || window.event;
if (event.preventDefault) {
event.preventDefault(); // prevent the default action to get triggered\
}
event.returnValue = false; // IE method
}
var keys = [37, 38, 39, 40];
function onKeydown(event) {
var e = event || window.event;
for (var i = 0, len = keys.length; i < len; i++) {
if (e.keyCode == keys[i]) {
console.log("Forbidden event");
e.preventDefault();
}
}
}
document.onkeydown = onKeydown;
Then you can construct your code by using anchor points and on click advanced to the desired place. That's it.