css - 如何使用 Assets 管道更改 Rails 4 中的 link_to 悬停图像

标签 css ruby-on-rails hover asset-pipeline link-to

注意:此说明是针对初学者的。

当我将鼠标悬停在图片上时,我遇到了无法更改 link_to 中的图片的问题。我在 CSS 中所做的一切似乎都无法解决问题。我在下面介绍了我对这个问题的解决方案。

这是我的链接:

  <%= link_to image_tag('1487789814_back.png'),
      {controller: @controller_action_hash_from_params[:controller],
        action: @controller_action_hash_from_params[:action]},
        sql_text: @sql_text,
      :id => "ralph-back-button-black-img", :class => "ralph-fieldset-back-button" %>

1487789814_back.png是app/assets/images中的普通png。它恰好是一个指向左边的黑色箭头。同样,app/assets/images/1487789814_back_red.png(下面使用)是一个指向左的红色箭头。当我将鼠标悬停在包含黑色箭头的字段集上时,我希望红色箭头出现。


问题根源:

上面的 link_to 生成/生成了以下 HTML:

<img src="https://localhost:3000/assets/1487789814_back-731afaae70e04062b25988079e4ef8ab4e6b523f4ac11ff7d142a9ff01e63455.png" alt="1487789814 back">

注意: 文件https://localhost:3000/assets/1487789814_back-731afa...3455.png "对你来说不存在。它是由 Rails 自动生成的文件名

分析:

问题的部分原因是(我相信)css 不能覆盖 HTML。也就是说,如果您在 HTML 中指定了一个属性(例如宽度),则不能在 css 中覆盖它。同样,(我相信)你不能覆盖 src="https: ..."在 css 中。任何尝试(我相信)使用 :hover 都会失败。要完成这项工作,您需要一把更大的锤子:javascript 或 jquery。


我的解决方案:

请注意:我并不是说这个解决方案是最好的解决方案,甚至不是一个好的解决方案。我声称它适用于我的 Rails 4 环境。

如果您在 Rails 4(Rails 3?Rails 5?)中使用 Assets 管道,您的“友好”图像名称(在我的例子中为 1487789814_back.png 和 1487789814_back_red.png)将由 Assets 管道系统转换为名称附加了加密哈希。换句话说,要访问红色箭头图像,您需要知道 Rails 分配给图像的名称。这篇小文章无法解释为什么 Rails 会重命名您的图像文件;只知道它确实如此。 (当然,您的原始文件仍会保留其原始名称。)

因此我们必须以某种方式将友好名称(例如“1487789814_back.png”)“映射”到 Assets 管道中的名称。

我通过使用“display:none”css 创建一个 div 来实现这一点。

错误:

<%# This div has display:none.
    We do this in order to preload the images_path as well as create a "map"
      between the friendly name and the asset pipeline name
%>
<div class='ralph_preload'>
  <%= image_tag('1487789814_back.png',      options={class:'ralph_preload_class', id:'1487789814_back'}) %>
  <%= image_tag('1487789814_back_red.png',  options={class:'ralph_preload_class', id:'1487789814_back_red'}) %>
</div>

上面的 erb 生成了以下 HTML:

<div class="ralph_preload">
  <img class="ralph_preload_class" id="1487789814_back" src="/assets/1487789814_back-731afaae70e04062b25988079e4ef8ab4e6b523f4ac11ff7d142a9ff01e63455.png" alt="1487789814 back">
  <img class="ralph_preload_class" id="1487789814_back_red" src="/assets/1487789814_back_red-bbd0f2e34f3401cc46d2e4e1e853d472d8c01c9a75f96d78032738bd01b2133b.png" alt="1487789814 back red">
</div>

关联的 CSS 是:

.ralph_preload {
  display: none;
}

我创建了一些 jQuery 来在用户悬停时将黑色箭头更改为红色:

<script type="text/javascript">
  function get_precache_myStruct_array(outer_div_class){
    var myStruct_array = [];
    $('.'+outer_div_class).find(".ralph_preload_class").each(function(){
      var myStruct = {
        id: this.id,
        src: this.src
      };
      // myStruct_array.push(myStruct);
      myStruct_array[this.id] = myStruct;
    });
    return myStruct_array;
  }

  // See http://stackoverflow.com/questions/15352803/how-to-check-if-an-image-was-cached-in-js
  function is_cached(img_url){
    var imgEle = document.createElement("img");
    imgEle.src = img_url;
    return imgEle.complete || (imgEle.width+imgEle.height) > 0;
  }

  $(document).ready(function(){
    var precache_myStruct_array = get_precache_myStruct_array("ralph_preload");
    $.each(precache_myStruct_array,
      function (index, value) {
        if (!is_cached(value.src)) {
          alert("Not cached!: " + value.src);
        };
    });

    <% if true %>
      $('#ralph-back-button-filedset').hover(function(){
        var precache_myStruct_array = get_precache_myStruct_array("ralph_preload");
        var imageID   = '1487789814_back_red';
        $('#ralph-back-button-black-img > img:nth-child(1)').attr("src", precache_myStruct_array[imageID].src);
      }, function(){
        var precache_myStruct_array = get_precache_myStruct_array("ralph_preload");
        var imageID = '1487789814_back';
        $('#ralph-back-button-black-img > img:nth-child(1)').attr("src", precache_myStruct_array[imageID].src);
      });
    <% end %>

  });
</script>

您可能会注意到 jQuery 中的“<% if true %>”/<% end %> block 。由于 jQuery 被“内联”到 .erb 文件中,因此 jQuery 会经过 erb 处理。通过将 true 更改为 false,可以使浏览器调试器更易于使用。


结论:

我在网络上进行了搜索以找到问题的答案。我发现没有一个像律师所说的那样。

当然,我非常乐意接受更正和评论。

最佳答案

如果您将这些图像放在公共(public)文件夹中,它们将不会在图像名称中添加额外的哈希值。

话虽如此,我在我的 Controller 中运行了一个循环,它为我获取了图像的所有“Rails”文件名,并将它们存储在我可以轻松访问的地方。

关于css - 如何使用 Assets 管道更改 Rails 4 中的 link_to 悬停图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42795487/

相关文章:

css - 修改基础 CSS 框架的最佳实践

ruby-on-rails - ruby 从数组中删除一个元素

google-chrome - "Inspect"悬停元素?

javascript - 一页上的多个选项卡式区域(纯 Javascript)

html - UL list - 不同颜色的元素符号

ruby-on-rails - 基于路径的 Multi-Tenancy RoR 应用程序 URL 路由

MySQL 查询分析器

css - 如何在 primefaces 中更改鼠标悬停时的命令链接图像?

javascript - jQuery 图像悬停颜色叠加

python - 我可以仅使用 CSS 设置 GtkBox 边距/填充样式吗?