进入我的博客

这里有您在其他地方看不到的web前端方面的技术、知识及资源

这里有您在其他地方看不到的web前端方面的技术、知识及资源
it's my whole life!

我的微码

« 查看全部微码

键盘可访问性之focus显示的下拉或浮层的索引和回车支持

2017-04-23 20:27

当我们使用CSS :focus或者JS的focus事件让下拉或浮层元素显示的时候,下拉或浮层元素里面的链接、按钮之类的不方便使用键盘进行访问,而此脚本就是解决这种需求的。兼容IE9+,原生JS编写无依赖。高品质项目必备脚本。

相关文章:http://www.zhangxinx...om/wordpress/?p=6102

完整代码

(function (doc) {
    if (doc.addEventListener) {
        var keycode = {
            37: 'left',
            38: 'up',
            39: 'right',
            40: 'down',
            13: 'enter',
            9: 'tab'
        };
        // 键盘高亮类名
        var className = 'outline';
        // 高亮类名的添加与删除
        var classList = {
            add: function (ele) {
                ele.className = ele.className + ' ' + className;
            },
            remove: function (ele) {
                ele.className = ele.className.split(/\s+/).filter(function (cl) {
                    if (cl != className) {
                        return cl;    
                    }
                }).join(' ');
            },
            removeAll: function () {
                [].slice.call(doc.querySelectorAll('.' + className)).forEach(function (ele) {
                    classList.remove(ele);
                });
            },
            has: function (ele) {
                return ele.className.split(/\s+/).filter(function (cl) {
                    if (cl == className) {
                        return cl;    
                    }
                }).length > 0;
            }
        };
        
        //键盘事件
        doc.addEventListener('keydown', function (event) {
            // 是否是上下左右键
            var direction = keycode[event.keyCode];
            if (!direction) {
                return;    
            }
            if (direction == 'tab') {
                classList.removeAll();
                return;
            }
            // 当前激活元素
            var trigger = doc.activeElement;
            if (!trigger) {
                return;
            }
            // 对应的面板
            var attrTarget = trigger.getAttribute('target') || trigger.getAttribute('data-target');
            var target = attrTarget && doc.getElementById(attrTarget);
            if (!target) {
                return;    
            }
            // 需要是显示状态
            if (target.clientWidth == 0 && target.clientHeight == 0) {
                return;
            }
            // 如果是回车事件
            if (direction == 'enter') {
                var eleFocus = target.querySelector('.' + className);
                if (eleFocus) {
                    // 阻止默认的回车
                    event.preventDefault();
                    eleFocus.click();
                    return;
                }
            }
            // 如果都符合,同时有目标子元素
            var arrEleFocusable = target.storeFocusableEle, index = target.storeIndexFocus;
            if (!arrEleFocusable) {
                arrEleFocusable = [].slice.call(target.querySelectorAll('a[href], button:not(:disabled), input:not(:disabled)'));
                target.storeFocusableEle = arrEleFocusable;
                target.storeIndexFocus = -1;
                index = -1;
            }
            if (arrEleFocusable.length == 0) {
                return;    
            }
            // 先全部清除focus态
            arrEleFocusable.forEach(function (ele) {
                classList.remove(ele);
            });
            // 阻止默认的上下键滚屏
            event.preventDefault();
            // 索引加加减减
            if (direction == 'left' || direction == 'up') {
                index--;
                if (index < 0) {
                    index = -1;
                }
            } else if (direction == 'right' || direction == 'down') {
                index++;
                if (index > arrEleFocusable.length - 1) {
                    index = arrEleFocusable.length;
                }
            }
            // 如果有对应的索引元素
            if (arrEleFocusable[index]) {
                // 高亮对应的控件元素
                classList.add(arrEleFocusable[index]);
            }
            // 记录索引
            target.storeIndexFocus = index;
        });

        doc.addEventListener('mousedown', function (event) {
            var target = event.target;
            if (target && !classList.has(target)) {
                classList.removeAll();
            }
        });
    }    
})(document);

标签:JS

分享:新浪微博

评论

0人参与,0条评论)

抱歉,服务器忙,未能成功提交,稍后重试。

Designed & Powerd by zhangxinxu
Copyright© 2009-2017 张鑫旭-鑫空间-鑫生活
鄂ICP备09015569号