ScriptaculousHelper等を利用する時の「"」「'」の悩み

問題

  • 例えば、マウスオーバーした時にピカッと光るように、visual_effect :highlightで以下のようにやりたくなる。
<a href="#" id="test" onmouseover="<%= visual_effect(:highlight, 'test') %>">
  test
</a>
  • 一見、うまく動いてくれそうなんだけど、実はちゃんと動作しない。
  • 生成されたHTMLソースを見てみると、以下のようになっていた。
<a href="#" id="test" onmouseover="new Effect.Highlight("test",{});"> 
  test
</a> 
  • 何が問題かというと...
    • onmouseover属性が「"」で囲まれているのに、
    • さらにその中のjavascriptコードで「"」が使われている。("test"の部分)
  • これでは「onmouseover="new Effect.Highlight("」と解釈されてしまって、正常に動くはずない...。
  • そこで、以下のように修正して、正常に動くようになった。(onmouseover = ' ... 'に変更)
<a href="#" id="test" onmouseover='<%= visual_effect(:highlight, 'test') %>'>
  test
</a>

試行錯誤

  • ところで、scaffoldなcssを利用していると、リンクに対してマウスオーバーすると、背景が黒で、文字が白に変化する。
  • そのようなcss設定でハイライトすると、ハイライト後の背景色が黒で終わってしまうのだ...。
  • 最終的には、白地に黒の状態に戻るのが希望。
  • 思い付く解決策は二つある。
    1. cssでマウスオーバーの背景色を変化しないように設定する。
    2. visual_effectの変化する色を指定する。
  • そもそも、ハイライトするリンクなら、cssのマウスオーバーの背景色の設定は不要な場合が多いと思うが...
  • ここでは、この後の話を続けるために、2. visual_effect のオプション指定でやってみた。
<a class="action" id="test" onmouseover='<%= visual_effect(:highlight, 'test', :endcolor=>"#cccccc", :restorecolor=>"#cccccc") %>'>
  test
</a>
  • 上記コードは以下のhtmlを生成した。
<a class="action" id="test" onmouseover='new Effect.Highlight("test",{endcolor:'#cccccc', restorecolor:'#cccccc'});'> 
  test
</a> 
  • 今度は、オプションで指定したカラーコードが「'」で囲まれてしまった...。('#cccccc'の部分)
  • これでは「onmouseover='new Effect.Highlight("test",{endcolor:'」と解釈されてしまう...。
  • Railsの過去のバージョンでは、以下のように指定する仕様だった。('"#cccccc"'、あるいは"'#cccccc'")
<a class="action" id="test" onmouseover='<%= visual_effect(:highlight, 'test', :endcolor=>'"#cccccc"', :restorecolor=>'"#cccccc"') %>'>
  test
</a>
  • '"#cccccc"'の部分。つまり、ダブルクォーテーションまで含めた "#cccccc" を渡している。
  • Rails2.1では仕様が変わって、カラーコードのみを渡す仕様になってしまったのだ...。(そして強制的に '#cccccc' になってしまう)
  • 当初は何故カラーコードはクォーテーションで囲って渡す必要があるのか疑問だったが、このような背景があったのかもしれない。

結論

  • それでは、Rails2.1ではどうすべきか考えてみたが、以下のようにするのが良さそう。
<%= content_tag(:a, 'test', :class=>'action', :id=>'test', :onmouseover=>visual_effect(:highlight, 'test', :endcolor=>'#cccccc', :restorecolor=>'#cccccc')) %>
  • 上記コードは以下のhtmlを生成した。
<a class="action" id="test" onmouseover="new Effect.Highlight(&quot;test&quot;,{endcolor:'#cccccc', restorecolor:'#cccccc'});">test</a>
  • 「"」が「&quot;」にエスケープされている。
  • これなら「"」や「'」のことは全く気にしなくてOK。
  • 同様の結果は、以下のように書くこともできた。
    • <%=h ... %>で囲んでエスケープしている。
    • 但し、onmouseover属性を必ず「"」で囲う必要がある。(「'」で囲ってしまうと正常に動かない。)
<a class="action" id="test" onmouseover="<%=h visual_effect(:highlight, 'test', :endcolor=>'#cccccc', :restorecolor=>'#cccccc') %>">
  test
</a>