問題
- 例えば、マウスオーバーした時にピカッと光るように、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設定でハイライトすると、ハイライト後の背景色が黒で終わってしまうのだ...。
- 最終的には、白地に黒の状態に戻るのが希望。
- 思い付く解決策は二つある。
- cssでマウスオーバーの背景色を変化しないように設定する。
- visual_effectの変化する色を指定する。
- そもそも、ハイライトするリンクなら、cssのマウスオーバーの背景色の設定は不要な場合が多いと思うが...
- ここでは、この後の話を続けるために、2. visual_effect のオプション指定でやってみた。
<a class="action" id="test" onmouseover='<%= visual_effect(:highlight, 'test', :endcolor=>"#cccccc", :restorecolor=>"#cccccc") %>'>
test
</a>
<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')) %>
<a class="action" id="test" onmouseover="new Effect.Highlight("test",{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>