1. ホーム
  2. スクリプト・コラム
  3. ルビートピックス

Ruby on Railsのjquery_ujsコンポーネントが遅くなる問題が解決された

2022-02-01 23:12:47

jquery_ujsはrailsにとって非常に重要なコンポーネントであり、railsのデフォルトのコンポーネントに含まれています。

jquery ujsには、確認ダイアログ、ajaxのトリガー、フォーム送信ボタンの自動無効化など、非常に便利な機能があります。この記事では、ajaxのトリガーに焦点を当てます。

jquery ujsは、簡単なタグのプロパティを追加することで、JavaScriptのコードを書かずに、通常のリンクやフォームをajax送信に変換することができます。

<%= link_to 'close_project', close_project_path(project), remote: true, method: :post %>


上記のコードでは、以下のようなコードが生成されます。

<a href="/projects/1/close" data-remote="true" data-method="post">Close project</a>


ユーザーがクリックすると、通常のgetリクエストの代わりにpostメソッドでアドレス/projects/1/closeへのajaxリクエストが発生し、ajaxコールを非常に簡単に実装することができます。

インターネットの通信速度が遅い場合に発生する問題
物事はいつもバラ色というわけではなく、このjquery ujsの実装は、ネットワークが遅いときに問題が発生します。ドキュメントの読み込みが終わる前にユーザーがリンクをクリックすると、ページがリンク先アドレスへのGETリクエストを開始し、ページがジャンプしますが、そのアドレスへのGETリクエストは存在しないことがあり、その場合はエラーになります。

関連する問題がユーザーから提起されましたが、開発者は取り上げませんでした。しかし、インターネットの遅さは中国の国家的な問題であり、今でも対処しなければなりませんし、CSS3のいくつかの機能を使えば、解決は難しいことではありません。

pointer-events
pointer-events: none;

The element is never the target of mouse events; however, mouse events may target its descendant elements if those descendants have pointer-events set to In these circumstances, mouse events will trigger event listeners on this parent element as appropriate on their way to/from the In these circumstances, mouse events will trigger event listeners on this parent element as appropriate on their way to/from the descendant during the event capture/bubble phases.



このプロパティは、要素のクリックイベントを無効にします。一般的にCSSは最初に読み込まれるので、ページが読み込まれる前にjquery ujsに関連する要素へのpointer-events: none;の適用を制御し、ページの読み込み後にスタイルを削除するだけです。 ページの読み込み時以外のリンクです。

解決方法
以下のグローバルスタイルを追加します。デフォルトでは、data-remote属性とdata-method属性を含むタグは、body要素にreadyというCSSクラスが含まれていないとクリックできないようになっています。

[data-remote], [data-method] {
 pointer-events: none;

 button, input[type=submit] {
  pointer-events: none;
 }
}

body.ready {
 [data-remote], [data-method] {
  pointer-events: auto;

  button, input[type=submit] {
   pointer-events: auto;
  }
 }
}



そして、ページが読み込まれた後に、簡単なスクリプトで body 要素に ready クラスを追加します。

$(document).ready ->
 $('body').addClass('ready')


だから、この問題は簡単に解決できる。