Vueでエンターキーの焦点を切り替える方法を実現します。


ほとんどのブラウザでは、Tabキーで焦点を切り替える機能があります。
しかし、わがままなユーザーは、必ずフォーカスを切り替える機能があることを強く求めています。
オンラインでお金をもらうために、もう一度お客さんの要求を無原則に受け入れました。
先代の人の多くはこのような操作習慣があります。保存を編集者にして、Tabを車に戻す習慣がある。これはマイクロソフトのエクセルの猛毒を受けた結果です。
最初はこの機能は簡単だと思いましたが、Enterキーの機能をTabボタンに接続して、分で解決できる問題だけです。
でも、すぐに困難が現れます。この道は通れないと思います。
私たちはしばしば、el.click()などのあるイベントをアクティブに起動することができます。クリックイベントを呼び出すことができます。またはdispatchEventを使用します。キーボードとマウスのイベントはだめです。
たくさんの資料を見て、いろいろ試しました。最後に結論をまとめました。ブラウザでは、JavaScriptはユーザーのキーボードやマウスを操作できません。これは安全策のためです。詳しく考えてみてください。JavaScriptのスクリプトでユーザーのキーボードとマウスを制御できたら、ユーザーはハッカーのウェブサイトを開くだけで、ハッカーは瞬時に彼のほしいものを得ることができます。
したがって、焦点切替がTabキー以外の方法でトリガされる場合、focusはほぼ唯一の選択である。
原生ページでエンターキー切り替えフォーカスを実現します。
プロジェクトはvueとelement-uiに基づいて作ったので、構想を実現するために先にはっきり言って、しばらくこれらを捨てて、原生のページの中から解答を探します。
以下は元のページです。

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width" />
 <title>Demo</title>
 </head>
 <body>
 <form>
 <input placeholder="  " />
 <input placeholder="  " />
 <input placeholder="  " />
 </form>
 </body>
</html>
これから車のキーを押して焦点を切り替えることを実現します。考えを整理します。
  • コールバックキーがイベントを押した。
  • は、現在のフォーカス要素を取得する。
  • は、次の焦点を合わせる要素を取得する。
  • フォーカスを切り替える。
  • 構想ができて、実現するのもとても簡単です。
    1.回車ボタンを監督してイベントを押す
    ドキュメントにスクリプトタグを追加し、次のコードを書き込みます。
    
    function enterCallback(e) {
     if (e.keyCode === 13) {
     //         
     }
    }
    window.addEventListener("keydown", enterCallback);
    注意してください。enterCallbackは単独で持ち出して、傍受イベントをキャンセルします。
    キーイベントを傍受する最も一般的な方法は、イベント依頼を使用して、イベントをwindowオブジェクトに結びつけることである。各要素に比較して一つのイベントを結びつける方式は、メモリ空間を節約することが最大の利点であり、性能がより良い。
    どのキーを押すかを判断する方法は、e.keye.code、またはe.keyCodeなどが多い。しかし、ほとんどの場合はe.keyCodeを使用することを推奨している。以下はネットワークからのkeyCode表です。

    2.現在のフォーカス要素を取得する
    簡単にこのステップができます。
    よくあるのは二つの方法があります。第一はe.targetであり、第二はdocument.activeElementである。このような場合は、個人的には第二の種類を使うのがオススメです。
    
    function enterCallback(e) {
     if (e.keyCode === 13) {
     let activeEl = document.activeElement;
     }
    }
    3.次のフォーカス要素を取得します。
    このステップも比較的簡単です。el.nextElementSibling APIを使用して取得できます。
    
    function enterCallback(e) {
     if (e.keyCode === 13) {
     let activeEl = document.activeElement;
     let nextEl = activeEl.nextElementSibling;
     }
    }
    4.焦点を切り替える
    焦点コールfocusを切り替えることで実現できる。
    
    function enterCallback(e) {
     if (e.keyCode === 13) {
     let activeEl = document.activeElement;
     let nextEl = activeEl.nextElementSibling;
     nextEl && nextEl.focus();
     }
    }
    これで一番簡単なデモが実現しました。これからプロジェクトの実際の状況を見てみます。
    element-uiプロジェクトでは、リターンキーの切り替え焦点を実現します。
    コンポーネントを使って開発するので、スタイルなどの要素を加えて、domノードは上に書いた原生Demoほど簡単ではないです。実際には多層の入れ子です。以下は実際に発生したコード構造です。
    
    <div
     class="el-form-item el-form-item--small"
     style="margin-bottom: 0vh; width: 25%; display: inline-block;"
    >
     <label for="pactcode" class="el-form-item__label" style="width: 130px;"
     >   </label
     >
     <div class="el-form-item__content" style="margin-left: 130px;">
     <div class="el-input el-input--small">
     <!---->
     <input
     type="text"
     autocomplete="off"
     id="el-input"
     placeholder="      "
     class="el-input__inner"
     />
     <!---->
     </div>
     </div>
    </div>
    各入力ボックスがこのタイプの入れ子構造の場合、上記の方法は直接解決できないことが見られます。nextElementSibling APIは次の兄弟要素しか見つからないので、ここでinputは明らかに次の兄弟要素が見つからないです。
    考え方は、遡及する手段によって外層に探索し、el-form-itemおよびel-form-item--smallを含むクラス名が見つかった時点で、その祖レベル要素の次の兄弟要素から類名を探してel-input__innerのinput要素を含む。
    したがって、さらに2つの関数を書きます。それぞれ、コンポーネント要素を探しているfindFormItemと、input要素を探しているfindInputです。
    findFormItem:
    
    function findFormItem(el) {
     const parent = el.parentElement;
     if (!parent) return document.body;
     if (
     parent.className.includes("el-form-item") &&
     parent.className.includes("el-form-item--small")
     ) {
     return parent;
     }
     return findFormItem(parent);
    }
    findInput:
    
    function findInput(container) {
     let nextEl = container.nextElementSibling;
     if (!nextEl) return;
     let input = nextEl.querySelector("input");
     while (input.id === "el-select") {
     nextEl = nextEl.nextElementSibling;
     if (!nextEl) return;
     input = nextEl.querySelector("input");
     }
     if (input.className.includes("el-input__inner")) return input;
    }
    この二つの関数があれば、リターンフォーカスを実現するのはとても簡単です。コードは2行だけ実行します。
    
    const container = findFormItem(document.activeElement);
    findInput(container) && findInput(container).focus();
    完全なコードは大体このようです。
    3つの方法はmethodsにおいて宣言される。
    
    methods: {
     addEnterListener() {
     if (window.__completeEnterBind__) return;
     window.addEventListener("keydown", this.enterCallback);
     window.__completeEnterBind__ = true;
     },
     removeEnterListener() {
     window.removeEventListener("keydown", this.enterCallback);
     window.__completeEnterBind__ = false;
     },
     enterCallback(e) {
     function findFormItem(el) {
     const parent = el.parentElement;
     if (!parent) return document.body;
     if (
      parent.className.includes("el-form-item") &&
      parent.className.includes("el-form-item--small")
     ) {
      return parent;
     }
     return findFormItem(parent);
     }
     function findInput(container) {
     let nextEl = container.nextElementSibling;
     if (!nextEl) return;
     let input = nextEl.querySelector("input");
     while (input.id === "el-select") {
      nextEl = nextEl.nextElementSibling;
      if (!nextEl) return;
      input = nextEl.querySelector("input");
     }
     if (input.className.includes("el-input__inner")) return input;
     }
     if (e.keyCode === 13) {
     const container = findFormItem(document.activeElement);
     findInput(container) && findInput(container).focus();
     }
     }
    }
    その後、mountedに、エコカーの傍受を追加し、destroyにおいて、リターンキーの除去を行う。
    
    mounted() {
     this.addEnterListener();
    },
    destroy() {
     this.removeEnterListener();
    },
    なお、項目は複数のタブの形式であり、フォームコンポーネントは何度もレンダリングされる可能性があるので、Windowsオブジェクトに__completeEnterBind__フィールドを追加することによって、エコカーの改行イベントが正しくバインディングされていることを確認する。
    締め括りをつける
    以上は小编が皆さんに绍介したVueの中でエンターキーの焦点を切り替える方法です。皆さんに助けてほしいです。