这可能是一个简单的问题,但经过一些研究后我找不到任何有效的解决方案。
我使用carrierwave生成上传图片的多个版本。每张图片都有不同屏幕尺寸的特定尺寸。 例如(在我的上传器中)我有
version :xl
适用于大于1200像素的屏幕。
如何根据客户端屏幕尺寸使用rails显示特定图像?
我知道有响应式图像,但我不能使用尺寸 响应式图像的主题目前相当广泛,没有人似乎有相同的答案,尤其是使用javascript和html5。如何使用rails(即使它是服务器端)?
答案 0 :(得分:5)
以下是两种方法:
加载包含存储为数据属性的各种图像大小的所有路径的页面,使用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)
服务器端测试不是针对屏幕宽度,而是针对像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