Today's the day

向软件大牛炫耀我会焊单片机,向硬件大牛炫耀我会写 Rails,向软硬件大牛炫耀我生物,向软硬件生物大牛炫耀我会折腾期货 -_-bbb

return false 在 IE 下失效了?

link_to 有个 method 属性,经常拿来配合 confirm 属性做删除链接:

<%= link_to ' Delete', { :action => 'destroy'}, :confirm => "Delete this post?", :method => :post %>

其实就是在链接的 onclick 中创建了一个临时表单,提交请求,最后 return false,这样链接本身就不会被触发:

<a href="/admin/destroy/1234" onclick="...;return false;">Delete</a>

不过发现,在 IE 下这个 return false 并没有效果,onclick 中的表单提交了,链接也触发了,以上面这个为例,点这个链接,会向 /admin/destroy/1234 发送两次请求,一次 post 一次 get 

那么为什么原来没有发现这个问题呢,因为 Rails 生成的控制器代码中都会有这么一句:

  1. verify :method => :post, :only => [ :destroy, :create, :update ],
  2. :redirect_to => { :action => :list }

所以第二次错误的 get 请求就会被转到 list 方法上去,但是即使通过 post 删除成功后,大多数情况也会转到 list 上去,看起来是一样的汗,实际上被转了两次。

问题就在于 IE 忽略了 return false,google 了下,好像碰到这个问题的人不是很多汗,难道是我 rp 问题…… 最后搜到了这个:

onclick="return false;" don't work in IE

看来有人在 CakePHP 的 AjaxHelper 中也发现了这个问题,解决的方法就是在 return false 前面加上一句:

onclick="... event.returnValue = false; return false;"

这样问题就解决了,不过 Rails 链接的 onclick 都是自动生成的,要怎么改呢。

再次拜 Ruby 强大的 OpenClass 所赐:

  1. module ActionView
  2.  module Helpers
  3.   module UrlHelper
  4.    private
  5.    def convert_options_to_javascript!(html_options, url = '')
  6.     ...
  7.     when confirm && popup
  8.       "... ;event.returnValue = false; return false;"
  9.     when confirm && method
  10.       "... ;event.returnValue = false; return false;"
  11.     ...
  12.     when method
  13.       "... event.returnValue = false;return false;"
  14.     when popup
  15.       ... + 'event.returnValue = false;return false;'
  16.     ...    
  17.   end
  18.  end
  19. end

找到 conver_options_to_javascript 这个方法,copy 过来,再添加上高亮部分的代码即可。直接覆盖核心的 private 方法,这种事情干起来真爽……

针对 IE7 的 CSS Hack

IE7修复了很多IE6中和CSS相关的bug,不过这样以来,原来在IE6中可以使用的CSS Hack到IE7中也就失效了,比如 *html 之类,其实IE7中也有相应的CSS Hack~

阅读全文