我一直在尝试在 jQuery 日期选择器中的“下个月”按钮上启用 keydown 事件。
这个想法是让用户不使用鼠标,仅使用制表键和 Enter 键来选择日期。
我知道日期选择器有一个按键映射(http://hanshillen.github.io/jqtest/#goto_datepicker),但我想要一些更简单且直观易懂的东西。顺便说一句,我的 Mac 上没有“向下翻页”按钮(为“下个月”保留),因此我无法使用此默认键设置浏览日期选择器。
默认情况下,表格上的“上个月”和“下个月”按钮甚至不会成为焦点。不过,我可以通过向相应的 div 添加“tabindex”属性来解决这个问题。但即使在焦点中,该按钮也不会响应 Enter 键。只需点击即可。
这是这段日期选择器的 html:
<a class="ui-datepicker-next ui-corner-all ui-state-hover
ui-datepicker-next-hover ui-state-active" data-handler="next"
data-event="click" title="Next" tabindex="1"><span class="ui-icon
ui-icon-circle-triangle-e">Next</span></a>
(我使用我的 javascript 函数添加了类
"ui-state-hover ui-datepicker-next-hover ui-state-active"
)。
下一步是什么?这是把
data-event="click"
改成别的东西的问题吗?我尝试这样做,并在 jquery.js 和 jquery-ui.js 文件中找到相应的函数或处理程序,但失败了。我对高级 javascript 和 jQuery UI 的了解确实很差,因为必须有一些简单的解决方案来解决这个问题。
感谢任何帮助,谢谢。
附注在这里,在 StackOverflow 中,我阅读了很多讨论,但只阅读了这一讨论:使用 TAB 键关注 jQuery UI 日历可访问性似乎处理日期选择器可访问性/制表问题,但仍然没有提到选择月份。
这是我的解决方案,基于以下事实:下个月/上个月的锚标记缺少 href 属性,这是它们没有获得焦点的原因(至少在 Chrome 中):
$('.js-calendar').datepicker({
inline: true,
altField: '.js-date-input',
onChangeMonthYear: function (year, month, inst) {
setTimeout(function () {
// add href to prev/next anchors so that they can receive TAB focus
$('.ui-datepicker-prev, .ui-datepicker-next').attr("href", "#");
}, 50);
}
});
// add href to prev/next anchors so that they can receive TAB focus
$('.ui-datepicker-prev, .ui-datepicker-next').attr("href", "#");
注意,我在 datepicker 调用之外添加了 href(出于初始目的),也在 onChangeMonthYear 函数中添加了 href(否则,它们会在更改月份后丢失)。
注意:使用jquery-ui-1.11.2
使用jquery-ui-1.13,您可以使用
onUpdateDatepicker
$('.js-calendar').datepicker({
inline: true,
altField: '.js-date-input',
onUpdateDatepicker: function (year, month, inst) {
// add href to prev/next anchors so that they can receive TAB focus
$('.ui-datepicker-prev, .ui-datepicker-next').attr("href", "#");
}
});
我对这个解决方案并不完全满意,但这段代码仍然达到了我想要的效果:
主要问题是,选择下个月后,日期选择器上的“下一个”按钮失去焦点,即使我管理它,该按钮也没有响应 Enter 键。这可能是因为该按钮是通过类名访问的,并且在日期选择器中更改月份后,该类引用的元素也会更改(例如,不是链接到九月,而是链接到十月)。因此,尝试在“同一个”元素上第二次(或第三次、第四次等)触发 keydown (Enter) 事件是行不通的。我想这也是为什么我无法在 jQuery 选择器中使用 this
而不是
className
的原因。我通过在单独的函数内触发 keydown 事件来解决这个问题,该函数调用自身。 这是代码(其中还包括按钮的一些基本样式,具体取决于按钮是否处于焦点状态):
function out_of_focus(id) {
$(id).blur(function() {
$(this).removeClass("ui-state-active");
});
}
$(".ui-datepicker-next").attr("tabindex", "1");
$(".ui-datepicker-next").focus(function() {
tabulation();
});
function tabulation() {
$(".ui-datepicker-next").addClass("ui-state-active");
$(".ui-datepicker-next").keydown(function(evt) {
if (evt.which == 13) {
$.datepicker._adjustDate("#datepicker", +1, "M");
$(".ui-datepicker-next").attr("tabindex", "2");
$(".ui-datepicker-next").focus();
tabulation();
out_of_focus(".ui-datepicker-next");
}
});
}
out_of_focus(".ui-datepicker-next");
任何有关如何改进这一点的建议都将受到赞赏。