如何配置羽化光以支持模态中的选项卡索引



我的表单(看看这里的演示小提琴,我也在下面粘贴了一些代码(似乎不支持 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);
};

最新更新