Have a Question?

If you have any question you can ask below or enter what you are looking for!

Question Detial

I need help with a modal that fires when user is idle. It works great until I test on Firefox with NVDA running. There are issues with focus when using the arrow keys and when I swipe on a mobile. When the modal appears and the user uses arrow or swipes the focus will bounce from the yes button to the header after a few seconds if I wait to click it. I have loaded the working example to: https://jsfiddle.net/ncanqaam/

I changed the idle time period to one minute and removed a portion which calls the server to extend the user's session.

var state ="L";
var timeoutPeriod = 540000;
var oneMinute = 60000;
var sevenMinutes = 60000;

var lastActivity = new Date();

function getIdleTime() {
    return new Date().getTime() - lastActivity.getTime();
}

//Add Movement Detection
function addMovementListener() {
    $(document).on('mousemove',  onMovementHandler);
    $(document).on('keypress',  onMovementHandler);
    $(document).on('touchstart touchend',  onMovementHandler);
}
//Remove Movement Detection
function removeMovementListener() {
    $(document).off('mousemove', onMovementHandler);
    $(document).off('keypress',  onMovementHandler);
    $(document).off('touchstart touchend',  onMovementHandler);
}

//Create Movement Handler
function onMovementHandler(ev) {
    lastActivity = new Date();
    console.log("Something moved, idle time = " + lastActivity.getTime());
}

function hide() {
    $('#overlayTY').removeClass('opened'); // remove the overlay in order to  make the main screen available again
    $('#overlayTY, #modal-session-timeout').css('display', 'none'); // hide the modal window
    $('#modal-session-timeout').attr('aria-hidden', 'true'); // mark the modal window as hidden
    $('#modal-session-timeout').removeAttr('aria-hidden'); // mark the main page as visible
}

if (state == "L") {
    $(document).ready(function() {
        //Call Event Listerner to for movement detection
        addMovementListener();
        setInterval(checkIdleTime, 5000);
    });

    function endSession() {
        console.log('Goodbye!');
    }

    var modalActive = false;
    function checkIdleTime() {
        var idleTime = getIdleTime();
        console.log("The total idle time is " + idleTime / oneMinute + " minutes.");

        if (idleTime > sevenMinutes) {
            var prevFocus = $(document.activeElement);
            console.log('previously: ' + prevFocus);
            var modal = new window.AccessibleModal({
                mainPage: $('#oc-container'),
                overlay: $('#overlayTY').css('display', 'block'),
                modal: $('#modal-session-timeout')
            });

            if (modalActive === false) {
                console.log(modalActive);
                $('#modal-session-timeout').insertBefore('#oc-container');
                $('#overlayTY').insertBefore('#modal-session-timeout');
                modal.show();
                $('#modal-overlay').removeClass('opened');
                modalActive = true;
                console.log(modalActive);
                console.log('the modal is active');
                $('.js-timeout-refresh').on('click touchstart touchend', function(){
                    hide();
                    modalActive = false;
                    prevFocus.focus();
                    addMovementListener();
                    lastActivity = new Date();
                });

                $('.js-timeout-session-end').on('click touchstart touchend', function(){
                    hide();
                    $('#overlayTY').css('display', 'none');
                    endSession();
                });
            }   
        }
        if ($('#overlayTY').css('display') === 'block'){
            removeMovementListener();
        }

        if (idleTime > timeoutPeriod) {
            endSession();
        }
    }
}

Answers

Sven Marnach

9:37am 7th September 2016

Possibles solutions

  1. Disable pointer-events on body when overlay is visible. this will restrict keyboard/swipe events on body elements
  2. Use JS/jQuery to trigger focus on the yes button

Marc Gravell

2:00pm 9th September 2016

The issue is with Voiceover Safari when a user swipes on an anchor or button the focus is set on these elements; however, if the element is an H2 it will not receive focus because natively it is not supposed to receive any. To compensate I attempted to set gesture events on the H2 but, Voiceover Safari needs time to read the element text or label out load, so it prevents any event from firing and this creates a problem when trying to set focus on a modal which loads from a timeout function rather than a clickable element. Hopefully Apple will address this in the future.