首页 > 解决方案 > Rails 6:渲染部分后执行 JS 函数

问题描述

这里是 Rails 和 Javascript 初学者,

在一个培训项目中,我flash使用 JQuery 让消息在几秒钟后消失。访问者会发送 AJAX 请求以将产品添加到他的购物车,然后会出现一个闪烁的部分“已添加到购物车”,并在几秒钟后自动淡出。


# application.html.erb

<div id='flash' class='flex-column'>
   <%= render partial: 'shared/flash'  %>
</div>
# shared/_flash.html.erb

<% flash.each do |key, value| %>
  <%= display_flash(key, value) %>
  <%= javascript_pack_tag 'custom/flash' %>  
  # this works, but injects the script each times the partial is rendered
<% end %>
# helpers/application_helper.rb

def display_flash(key, value)
  def display_flash(key, value)
    div_class = [flash_class(key), 'text-center fade show alert-dismissible'].join(' ')

    content_tag(:div, class: div_class) do
      content_tag(:p, value) +
      button_tag(class: 'ml-auto close', 'data-dismiss': 'alert', type: 'button') do
        content_tag(:span, '&times;'.html_safe, 'aria-hidden': 'true') +
        content_tag(:span, 'Close', class: 'sr-only')
      end
    end
  end
end
// app/javascript/packs/custom/flash.js

function closeFlash(){
  let lastAlert = $('#flash .alert:last')

  function fadeFlash() {
    lastAlert.animate( {opacity: 0}, 2000, function() {
      $(this).hide('slow', function() {
        $(this).remove()
      });
    });
  };

  setTimeout(fadeFlash, 2000)
};

closeFlash();

这样做的问题是它用不必要的<script>标签污染了我的 DOM: 不需要的脚本标签

这可以修复,但是在渲染(AJAX)部分后是否有合适的方法来执行一个特定的 javascript 函数?在我的情况下,closeFlash() 每次packs/custom/flash.js渲染部分时执行。

感谢您的帮助和时间


编辑解决方案:

来自 Amit Patel 的回答和这篇文章

# app/views/shared/_flash.html.erb

<% flash.each do |key, value| %>
  <%= display_flash(key, value) %>

  <script>
    $(function() {
      closeFlash();
    });
  </script>

<% end %>
// app/javascript/packs/custom/flash.js

window.closeFlash = function() {
    let lastAlert = $('#flash .alert:last')

    function fadeFlash() {
        lastAlert.animate( {opacity: 0}, 2000, function() {
            $(this).hide('slow', function() {
                $(this).remove()
            });
        });
    };

    setTimeout(fadeFlash, 2000)
};

它不会注入整个函数,而是(我相信)调用它的最小 javascript 代码。

标签: javascriptjqueryruby-on-railswebpackwebpacker

解决方案


移动<%= javascript_pack_tag 'custom/flash' %>到您的布局或您的 application.js` 以便它在整个应用程序中可用。

修改您的模板,例如

应用程序.html.erb

<div id='flash' class='flex-column'>
   <%= render partial: 'shared/flash'  %>
   <script>
     $(function(){
       closeFlash();
     });
   </script>
</div>

推荐阅读