RubyonRails-动态生成部分中的JavaScript

RubyonRails-动态生成部分中的JavaScript,javascript,ruby-on-rails,partial-views,partial,dynamically-generated,Javascript,Ruby On Rails,Partial Views,Partial,Dynamically Generated,我知道将JavaScript放在片段中是个坏主意,因为每次加载新片段时,页面都必须加载新脚本。我知道并且读过,但它的答案对我来说并不适用(将脚本放入app/javascripts/application.js)。我认为这是因为我正在处理动态生成到页面上的部分。我认为动态生成的部分不会对初始页面上加载的脚本作出反应 例如,我有一个带有select输入的“Rule”div,当select输入被更改时,它有一个脚本来执行某些操作。这适用于页面加载时生成的每个规则div。但是,还有一个“+”或“ADD”

我知道将JavaScript放在片段中是个坏主意,因为每次加载新片段时,页面都必须加载新脚本。我知道并且读过,但它的答案对我来说并不适用(将脚本放入app/javascripts/application.js)。我认为这是因为我正在处理动态生成到页面上的部分。我认为动态生成的部分不会对初始页面上加载的脚本作出反应

例如,我有一个带有select输入的“Rule”div,当select输入被更改时,它有一个脚本来执行某些操作。这适用于页面加载时生成的每个规则div。但是,还有一个“+”或“ADD”按钮,它将动态生成更多不响应脚本的规则div,除非该脚本位于分部中


当动态生成分部时,有没有一种好方法可以防止脚本出现在分部之外?

只有在文档加载到DOM后,才能使用JQuery执行代码:

$( document ).ready(function() {
    //Call your functions here
});
这样,您的JS就可以访问页面上的任何内容,因为您要确保页面已完全加载

如果您的div在documentready上没有就位,您可以按照ptd的建议使用事件委派。基本上,这意味着在父div上安装一个处理程序(将出现在documentready上),该处理程序说,“嘿,当您在我内部单击这个动态div时,调用这个函数”


JQuery在页面加载时设置侦听器(即,
$(选择器).on(等)
),因此它不会侦听动态添加的元素上的事件。不过,还是有办法的。您需要使用所谓的委托

$(document).ready( function() { 
    $('body').on('change', 'input.selector', function(e) {
        // do something
    });
});

我不确定您正在使用的事件(这里我放置了
change
)或选择器(这里我放置了
input.selector
)是什么,但是如果您用适当的信息替换它们,它甚至可以用于动态添加的元素。

如果您使用AJAX调用向DOM添加元素,但是,如果您只想将JavaScript保存在资产文件夹中,这里有一个快速而干净的方法来实现这一点

// /app/assets/javascript/foo.js

// On intial page load
$(document).ready(function() {
  yourJavaScriptForPartials();
});

// After a subdomain field is loaded via AJAX
$(document).ajaxComplete(function() {
  yourJavaScriptForPartials();
});

function yourJavaScriptForPartials() {
  // Insert your javascript here. 
};

现在,您在
yourJavaScriptForPartials()
函数中放入的任何JavaScript都将对最初加载的DOM和通过AJAX添加的任何DOM元素可用。作为参考,对于
ajaxComplete
事件侦听器,这不起作用:(只是尝试确认它不起作用以确保。当文档“就绪”时,动态生成的div实际上不在页面上)。它们是在用户按下按钮后创建的。听起来用户单击按钮时,您已经有了一个事件处理程序。同时,您应该在放置在页面上的div上安装另一个事件处理程序。$(“div.new_div”)。在(“单击”,函数(){//install new handler here})这不是仍然会为每个新div的处理程序添加一个脚本吗?是的。解决方案确实是事件委派。你可以使用ptd的代码。但是它可以更具体,因此如果你要添加的所有div都在一个主div中,你可以对它进行事件委派。$('div#master')。on('click','div.dynamic',function(event){console.log(“action here”)});好的,我猜事件委托与使用body有关(与动态生成的div相反)。所以“body”知道它的select元素在更改时会执行某些操作,而添加这些元素时则无关紧要。对吗?…不幸的是,您的代码对我不起作用。我逐字复制了它,只是将“do something”更改为console.log(“hello”);但我无法获取“hello”"记录。你的想法是对的。我粘贴的代码将不起作用,除非你正在使用类选择器查看输入,我想你不是。将
input.selector
替换为要查看更改的输入的选择器。抱歉!我必须先处理一些具有更高优先级的内容,然后再回到这里。我感觉很抱歉我很抱歉现在不知道如何替换input.selector。还有一件事,有必要将侦听器放在$(document).ready(function(){})中;它现在与我的动态部分一起工作得非常好。谢谢!
// /app/assets/javascript/foo.js

// On intial page load
$(document).ready(function() {
  yourJavaScriptForPartials();
});

// After a subdomain field is loaded via AJAX
$(document).ajaxComplete(function() {
  yourJavaScriptForPartials();
});

function yourJavaScriptForPartials() {
  // Insert your javascript here. 
};