Javascript Vue.js元素Ui-el对话框打开时陷阱/锁定焦点

Javascript Vue.js元素Ui-el对话框打开时陷阱/锁定焦点,javascript,html,vue.js,element-ui,Javascript,Html,Vue.js,Element Ui,如您所见,当您打开任何对话框示例并开始按tab键时,焦点将开始高亮显示对话框外部/后面的元素。我想知道元素ui是否提供了我没有注意到的东西 无论如何,目前我正在使用,但我希望element ui能够提供一些本地的东西,而不是通过拉一个库来解决这个问题。这似乎是一个bug,element ui还没有解决。如果你想要一个纯本地的解决方案,这里有一个主意:你可以在选项卡上监听按键下的事件。在这种情况下,您可以访问对话框中的最后一个元素(document.activeElement),并防止进一步按下制

如您所见,当您打开任何对话框示例并开始按tab键时,焦点将开始高亮显示对话框外部/后面的元素。我想知道元素ui是否提供了我没有注意到的东西


无论如何,目前我正在使用,但我希望element ui能够提供一些本地的东西,而不是通过拉一个库来解决这个问题。

这似乎是一个bug,element ui还没有解决。如果你想要一个纯本地的解决方案,这里有一个主意:你可以在
选项卡上监听
按键下的
事件。在这种情况下,您可以访问对话框中的最后一个元素(
document.activeElement
),并防止进一步按下制表符。如果这样做,请不要忘记在对话框关闭时删除事件侦听器。希望这能有所帮助。

以下是我自己问题的答案:

首先,我尝试使用
vue focus lock
插件,它可以工作,但在选择
el checkbox
el radio
等组件时也会出现问题。当
el对话框
的外部/后面内容更多(在折叠下方)时,您可以看到问题,然后复选框或收音机将不会被选中

无论如何,这是我的解决方案,我创建了一个组件
FocusLock.vue

<template lang="pug">
  div.dialog-focus-lock
    slot
</template>

<script>
export default {
  name: 'focus-lock',

  data() {
    return {
      focusableEls: [],
      firstFocusableEl: [],
      lastFocusableEl: [],
      focusedElBeforeOpen: document.activeElement,
    };
  },

  methods: {
    handleDialogFocusLock() {
      const selectors = '' +
        'a[href], ' +
        'input:not([disabled]), ' +
        'select:not([disabled]), ' +
        'textarea:not([disabled]), ' +
        'button:not([disabled])';

      const getEls = this.$el.querySelectorAll(selectors);

      this.focusableEls = Array.prototype.slice.call(getEls);
      [this.firstFocusableEl] = this.focusableEls; // get first array item
      [this.lastFocusableEl] = this.focusableEls.slice(-1); // get last array item

      this.$el.addEventListener('keydown', e => this.handleKeyDown(e));
      this.firstFocusableEl.focus();
    },

    handleBackwardTab(e) {
      if (document.activeElement === this.firstFocusableEl) {
        e.preventDefault();
        this.lastFocusableEl.focus();
      }
    },

    handleForwardTab(e) {
      if (document.activeElement === this.lastFocusableEl) {
        e.preventDefault();
        this.firstFocusableEl.focus();
      }
    },

    handleKeyDown(e) {
      const KEY_TAB = 9;

      switch (e.keyCode) {
        case KEY_TAB:
          if (this.focusableEls.length === 1) {
            e.preventDefault();
            break;
          }
          if (e.shiftKey) {
            this.handleBackwardTab(e);
          } else {
            this.handleForwardTab(e);
          }
          break;
        default:
          break;
      }
    },
  },

  mounted() {
    this.handleDialogFocusLock();
  },
};
</script>
在我需要的地方使用它们,就像这样:

<template lang="pug">
  focus-lock
    el-dialog(:visible.sync="dialogVisible")
      el-form(:model="editedItem")
        // form elements goes here
</template>

我真的需要一个快速修复,而不是做你建议的事情,因为我正在构建的应用程序中有将近30个对话框。每个都有不同的形式元素。不过谢谢你的建议。在这种情况下,最好创建一个指令,并在任何需要的对话框中使用它。
<template lang="pug">
  focus-lock
    el-dialog(:visible.sync="dialogVisible")
      el-form(:model="editedItem")
        // form elements goes here
</template>
Array.from(document.querySelectorAll('*'))
  .reduce(function(pre, dom){
    var clks = getEventListeners(dom).click;
    pre += clks ? clks.length || 0 : 0;
    return pre
  }, 0)