:type => :synchronousで処理中はブラウザをロック

link_to_remoteなどによるajaxリクエストは、通常、非同期で処理*1される。ところが、:type => :synchronousオプションを設定することで、同期処理*2になることを知った。

  • :type => :synchronousを設定すると、asynchronous:falseに展開される。(指定が無い場合は、asynchronous:trueに展開される。)
  • 送信ボタンをクリックすると、処理が完了するまでボタンが押されたままの状態が続き、マウスやキーの操作を受け付けなくなる。
<%= form_remote_tag :update => 'default_update', 
                    :submit => 'default_params', 
                    :url => {:action => 'update_preference'}, 
                    :type => :synchronous %>

上記ヘルパメソッドは、以下のように展開される...

<form onsubmit="new Ajax.Updater('default_update', 
                                 '/defaults/update_preference', 
                                 {asynchronous:false, 
                                  evalScripts:true, 
                                  parameters:Form.serialize(this)}); 
                 return false;" 
      method="post" 
      action="/defaults/update_preference">
  • 今まで、asynchronous:trueの意味がよく分かっていなかったが、非同期と同期を区別すると、上記のような効果があることが分かった。
  • 処理内容は違うが、submit_tagの:disable_withと同じように、このオプションでも二重送信を防止することが出来ると思った。(ボタンの表記は変更できないが...。)

副作用

:type => :synchronousを設定すると...

  • Safariではなぜか日本語が文字化けしてしまう。なぜだろう?原因不明。firefox、IE6は問題なし。
  • :loadingに設定したコールバックが無視される。(Safari、IE6)
  • :loading、:loaded、:interactiveに設定したコールバックが無視される。(Firefox

Safariが文字化けしなかったら、このオプションを使いたい場面も結構ありそう。でもなぜ文字化けしてしまう...。

*1:処理中であっても、ブラウザに対してマウスやキー入力等の操作が続けられる状態

*2:処理中はブラウザの操作が出来ない状態