我的表单(看看这里的演示小提琴,我也在下面粘贴了一些代码(似乎不支持 Featherlight 模态中的 tabindex。
我想是因为《羽毛之光》的这一部分。
如何在模式中显示窗体,同时仍允许用户按 TAB
键跳转到下一个字段?
似乎我需要在 Featherlight 库中添加一个黑客,我宁愿不这样做。
谢谢!
<div style="display: none;">
<div id="modal">
My form NEEDS to support tabindex. If Featherlight is going to set tabindex to -1 for anything (even temporarily), it should only be for elements that aren't inside the modal.
<div class="mainInputWrapper">
<input type="text" name="fullname" placeholder="Your Name" required id="firstname" /><span class="forValidationDisplay"></span>
</div>
<div class="mainInputWrapper">
<input type="email" name="email" placeholder="Your Best Email Address*" required id="email" /><span class="forValidationDisplay"></span>
</div>
<button>
Submit
</button>
</div>
</div>
<a class="role-element leadstyle-link" href="#" data-featherlight="#modal">Click here if you're interested</a>
我找到了一种方法来覆盖 Featherlight 并避免编辑其源代码。
$.featherlight._callbackChain.beforeOpen = function (event) {
//http://stackoverflow.com/q/42234790/470749
//By overriding this function, I can prevent the messing up of tabindex values done by: https://github.com/noelboss/featherlight/blob/master/src/featherlight.js#L559
};
$.featherlight._callbackChain.afterClose = function (event) {
//See note above in $.featherlight._callbackChain.beforeOpen
};
$.featherlight.defaults.afterContent = function (event) {
var firstInput = $('.featherlight-content #firstname');
console.log('Considering whether to focus on input depending on window size...', $(window).width(), $(window).height(), firstInput);
if (Math.min($(window).width(), $(window).height()) > 736) {//if the smallest dimension of the device is larger than iPhone6+
console.log('yes, focus');
firstInput.attr('autofocus', true);
}
};
不幸的是,接受的答案破坏了禁用滚动功能。
恕我直言,路易斯·保罗·洛曼的答案要好得多。这是它的略微改进版本:
afterContent: function () {
$('.featherlight-content').find('a, input[type!="hidden"], select, textarea, iframe, button:not(.featherlight-close), iframe, [contentEditable=true]').each(function (index) {
if (index === 0) {
$(this).prop('autofocus', true);
}
$(this).prop('tabindex', 0);
});
}
改进:
- 重置所有元素的
tabindex
,这些元素由 Featherlight 处理。 - 使用
tabindex="0"
以获得更好的可访问性和更少的订单问题。有关更多详细信息,请参阅 https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex。
以防万一你想知道,@Ryan代码的最后一条语句不是必需的。
我在源代码的末尾添加了这个(因为就我而言,我不介意编辑源代码(并且它起作用了:
$.featherlight._callbackChain.beforeOpen = function (event) {
//http://stackoverflow.com/q/42234790/470749
//By overriding this function, I can prevent the messing up of tabindex values done by: https://github.com/noelboss/featherlight/blob/master/src/featherlight.js#L559
};
$.featherlight._callbackChain.afterClose = function (event) {
//See note above in $.featherlight._callbackChain.beforeOpen
};
我对 tabindex=-1 问题的解决方法:
afterContent: function(event) {
$j('.featherlight-content input').each(function(index){
if(index == 1) {
$j(this).prop('autofocus',true);
}
$j(this).prop('tabindex',index);
});
}
我使用一个小的jquery函数来修复tabIndex:
$.fn.fixTabIndex = function(){
// We don't modify tabindex or focus for hidden inputs
this.find('input[type!="hidden"]').each(function(i, e){
var $this = $(this);
// Focus on first input with data-focus attribute
if($this.data('focus')){
$this.focus();
}
// Set tabindex with current index plus a random number (default 100)
$this.prop('tabindex', 100 + i);
});
return this; // chainable methods
};
应该在所需的输入中添加data-focus="true"
。
用法:
$(featherlight-selector).featherlight({
targetAttr: 'href',
afterContent: function(){
$(form-selector)fixTabIndex();
}
});
也许有更好的方法来选择表单...
似乎没有充分的理由为什么羽毛灯内的buttons
保持可选项卡,而不是input
。
我会修复这个错误。
对此感到抱歉。
@Ryan为我指明了正确的方向。我以一种绝对是黑客的方式工作。我没有重置 featherlight 中的内容,而是更新了原始 .not 以忽略 featherlight 实例中包含的任何内容。这给我留下了以下几点。这里肯定有一些不是最佳实践的部分可以使用一些工作,例如临时实例和超时等待内容更新,但我现在没有更多时间来处理它。
这是基于源,并更改了第二个.not
。它保持模式外的无制表符、无滚动并返回到原始焦点。
$.featherlight._callbackChain.beforeOpen = function (_super, event) {
$(document.documentElement).addClass('with-featherlight');
// Remember focus:
this._previouslyActive = document.activeElement;
// Disable tabbing outside the current instance:
// See http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus
// Starting point https://stackoverflow.com/questions/42234790/how-can-i-configure-featherlight-to-support-tabindex-within-the-modal/42235457#42235457.
// Updates here. Don't give the tabindex to elements within the currently open featherlight container.
// This wasn't working with the current state of the content. The intended content is not yet in the instance,
// the timeout forces its hand.
var tempInstance = this.$instance.get(0);
setTimeout(function() {
this._$previouslyTabbable = $("a, input, select, textarea, iframe, button, iframe, [contentEditable=true]")
.not('[tabindex]')
.not(function (index, element) {
return $.contains(tempInstance, element)
});
this._$previouslyWithTabIndex = $('[tabindex]').not('[tabindex="-1"]');
this._previousWithTabIndices = this._$previouslyWithTabIndex.map(function (_i, elem) {
return $(elem).attr('tabindex');
});
this._$previouslyWithTabIndex.add(this._$previouslyTabbable).attr('tabindex', -1);
}.bind(this), 100);
if (document.activeElement.blur) {
document.activeElement.blur();
}
return _super(event);
};