如何配置Featherlight以支持模态中的tabindex?

时间:2017-02-14 19:40:08

标签: featherlight.js

我的表单(look at the demo fiddle here,我也粘贴了下面的一些代码)似乎不支持Featherlight模式中的tabindex。

我认为这是因为this part of Featherlight here

如何在模式中显示表单,仍然让用户按TAB键退回到下一个字段?

似乎我需要在Featherlight库中添加一个hack,我宁愿不这样做。

谢谢!

<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>

7 个答案:

答案 0 :(得分:7)

我找到了一种覆盖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);
        }
    };

答案 1 :(得分:4)

不幸的是,接受的答案破坏了禁用滚动功能。

Luis Paulo Lohmann的答案好得多,恕我直言。这是它的稍微改进的版本:

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);
    });
}

改进:

答案 2 :(得分:2)

万一你想知道,@ 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
};

答案 3 :(得分:2)

我对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);
            });
        }

答案 4 :(得分:1)

我使用一个小的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();
        }
    });

也许有更好的方法来选择表格...

答案 5 :(得分:0)

似乎没有理由说明为什么羽毛灯内的buttons仍然可以列表而不是input

我将修复错误。

对此感到抱歉。

答案 6 :(得分:0)

@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);
};