根据屏幕尺寸显示右图

时间:2014-11-26 21:41:34

标签: image ruby-on-rails-4 responsive-design

这可能是一个简单的问题,但经过一些研究后我找不到任何有效的解决方案。

我使用carrierwave生成上传图片的多个版本。每张图片都有不同屏幕尺寸的特定尺寸。 例如(在我的上传器中)我有

version :xl 

适用于大于1200像素的屏幕。

如何根据客户端屏幕尺寸使用rails显示特定图像?

我知道有响应式图像,但我不能使用尺寸 响应式图像的主题目前相当广泛,没有人似乎有相同的答案,尤其是使用javascript和html5。如何使用rails(即使它是服务器端)?

2 个答案:

答案 0 :(得分:5)

以下是两种方法:

  1. 加载包含存储为数据属性的各种图像大小的所有路径的页面,使用js获取屏幕宽度,然后将图像标记粘贴到您想要的正确路径。代码可能看起来像(未经过测试,我一直在使用coffeescript,因此可能缺少详细信息):

    # ruby command line
    $ @image.mobile_asset_url
    => "path/to/mobile/image"
    $ @image.desktop_asset_url
    => "path/to/desktop/image"
    
    
    # html.erb
    <img src="" class="placeholder" data-mobile-url=<%=@image.mobile_asset_url%> data-desktop-url=<%=@image.desktop_asset_url%>></div>
    
    # javascript
    el = $('.placeholder')
    data = el.data();
    width = $(window).width();
    mobile_breakpoint = 480;
    
    if (width <= mobile_breakpoint) {
      url = data.mobileUrl;
    } else {
      url = data.desktopUrl;
    }
    
    el.attr('src', url)
    
  2. 服务器端测试不是针对屏幕宽度,而是针对像browser这样的宝石的浏览器类型,并为iOS8等移动特定浏览器加载较小的图像。像这样的逻辑在装饰器中可能是最好的。我对Ruby更熟练,所以一个例子可能看起来像(这段代码没有经过测试):

    # user_decorator.rb, from the Draper gem
    class UserDecorator
    
      def profile_url
        if mobile_browser?
           "path/to/small/image"
        else
           "path/to/large/image"
        end
      end
    
      private
    
      def mobile_browser?
        browser.ios || browser.android || ...
      end
    
    end
    

答案 1 :(得分:1)

好吧,我真的想用更多的 rails方式来做。我最终使用了ajax:

在加载页面上激活ajax:

# assets/javascript/cards/index.js
// fire loading image
$.ajax({
  url: document.URL,
  data: {
    w: window.innerWidth
  }
});

在控制器中,回复ajax:

# controllers/cards_controller.rb
render 'cards/images/loadimage' if request.xhr?

然后加载图片

# cards/images/loadimage.js.erb
<% w = params[:w].to_i %>
document.getElementById('banner-container').innerHTML = "<%= j image_tag @card.banner_type_url(w), class: 'banner' %>";
document.getElementById('logo-container').innerHTML = "<%= j image_tag @card.logo_type(w), class: 'logo' %>";

我在我的模型中制作了一个方法来返回给定屏幕宽度的右图像(并基于载波版本):

 # models/card.rb
 # returns banner type based on width (w)
 def banner_type_url(w)
   return self.banner.s.url || banner_default('s') if(w <= 768) 
   return self.banner.m.url || banner_default('m') if(w <= 992) 
   return self.banner.l.url || banner_default('l') if(w <= 1200) 
   return self.banner.xl.url || banner_default('xl') if(w <= 1920) 
   return self.banner.full.url || banner_default('full')    
 end
 def banner_default(s)
   "card/banner/#{s}_default-banner.jpg"
 end