Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/448.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 引导程序本机不适用于Turbo链接_Javascript_Ruby On Rails_Turbolinks_Turbolinks 5_Bootstrap Native - Fatal编程技术网

Javascript 引导程序本机不适用于Turbo链接

Javascript 引导程序本机不适用于Turbo链接,javascript,ruby-on-rails,turbolinks,turbolinks-5,bootstrap-native,Javascript,Ruby On Rails,Turbolinks,Turbolinks 5,Bootstrap Native,我正在尝试在Rails 5应用程序中使用。当我第一次加载页面时,引导下拉菜单工作正常,但导航到另一个页面后,引导下拉菜单不再工作。这就好像引导程序的事件侦听器断开了连接 在Bootstrap的jQuery实现方面,我已经看到了几个解决这个问题的问题,但是,我对使用jQuery并从我的JS堆栈中删除jQuery感兴趣 以下是一些细节: application.js # app/assets/javascript/application.js //= require turbolinks //= r

我正在尝试在Rails 5应用程序中使用。当我第一次加载页面时,引导下拉菜单工作正常,但导航到另一个页面后,引导下拉菜单不再工作。这就好像引导程序的事件侦听器断开了连接

在Bootstrap的jQuery实现方面,我已经看到了几个解决这个问题的问题,但是,我对使用jQuery并从我的JS堆栈中删除jQuery感兴趣

以下是一些细节:

application.js

# app/assets/javascript/application.js
//= require turbolinks
//= require rails-ujs
//= require polyfill
//= require bootstrap-native
//= require turbolinks
//= require rails-ujs
//= require polyfill
//= require bootstrap-native
//= require bootstrap-native-turbolinks
document.addEventListener('turbolinks:load', function(){
  Array.prototype.forEach.call(document.querySelectorAll('[data-spy="affix"]'), function(element){ new Affix(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-dismiss="alert"]'), function(element){ new Alert(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="buttons"]'), function(element){ new Button(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-ride="carousel"]'), function(element){ new Carousel(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="collapse"]'), function(element){ new Collapse(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="dropdown"]'), function(element){ new Dropdown(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="modal"]'), function(element){ new Modal(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="popover"]'), function(element){ new Popover(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-spy="scroll"]'), function(element){ new ScrollSpy(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="tab"]'), function(element){ new Tab(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="tooltip"]'), function(element){ new Tooltip(element) });
},false);
应用程序布局

# views/layout/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
    </div>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload', 'data-turbolinks-eval': 'false' %>
  </body>
</html>
#视图/layout/application.html.erb
本机引导程序 这是最新的

从我的Javascript标记中删除
“data-turbolinks-eval”:“false”
,从而在每个Turbolink导航上重新评估应用程序的所有Javascript,确实解决了引导本机问题,但它会导致rails ujs引发异常


有没有关于如何解决这个问题的想法?

使用TurboLink时,您很可能希望将应用程序JavaScript文件放在
中:

#视图/layout/application.html.erb
尽管这似乎与传统的最佳实践背道而驰,但Turbolinks的性能优势在于脚本只在初始页面加载时加载


如果引导程序本机库在
DOMContentLoaded
上初始化其插件/函数,您可能还需要在
turbolinks:load
上手动调用这些函数,然后根据需要将它们拆下(通常在
turbolinks:before cache

在Bootstrap原生开发团队的一名成员接受了答案之后,我修改了我在应用程序中实现的解决方案。我的解决方案与公认的解决方案略有不同,因为我的侦听器将在整个DOM中搜索引导组件。相比之下,接受的解决方案将只在具有
id=“myContainer
的HTML标记中搜索。接受的解决方案将执行得更快,因为它只搜索DOM的子集。但是,它要求开发人员将相关引导组件包装在具有
myContainer
id的标记中

这两种解决方案都有效。我的解决方案运行速度会稍微慢一点,但会更容易编码,并且不太容易出现由开发人员引起的错误。以下是详细信息:

app/assets/javascript/application.js

# app/assets/javascript/application.js
//= require turbolinks
//= require rails-ujs
//= require polyfill
//= require bootstrap-native
//= require turbolinks
//= require rails-ujs
//= require polyfill
//= require bootstrap-native
//= require bootstrap-native-turbolinks
document.addEventListener('turbolinks:load', function(){
  Array.prototype.forEach.call(document.querySelectorAll('[data-spy="affix"]'), function(element){ new Affix(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-dismiss="alert"]'), function(element){ new Alert(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="buttons"]'), function(element){ new Button(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-ride="carousel"]'), function(element){ new Carousel(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="collapse"]'), function(element){ new Collapse(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="dropdown"]'), function(element){ new Dropdown(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="modal"]'), function(element){ new Modal(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="popover"]'), function(element){ new Popover(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-spy="scroll"]'), function(element){ new ScrollSpy(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="tab"]'), function(element){ new Tab(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="tooltip"]'), function(element){ new Tooltip(element) });
},false);
app/assets/javascript/bootstrap native turbolinks.js

# app/assets/javascript/application.js
//= require turbolinks
//= require rails-ujs
//= require polyfill
//= require bootstrap-native
//= require turbolinks
//= require rails-ujs
//= require polyfill
//= require bootstrap-native
//= require bootstrap-native-turbolinks
document.addEventListener('turbolinks:load', function(){
  Array.prototype.forEach.call(document.querySelectorAll('[data-spy="affix"]'), function(element){ new Affix(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-dismiss="alert"]'), function(element){ new Alert(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="buttons"]'), function(element){ new Button(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-ride="carousel"]'), function(element){ new Carousel(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="collapse"]'), function(element){ new Collapse(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="dropdown"]'), function(element){ new Dropdown(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="modal"]'), function(element){ new Modal(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="popover"]'), function(element){ new Popover(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-spy="scroll"]'), function(element){ new ScrollSpy(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="tab"]'), function(element){ new Tab(element) });
  Array.prototype.forEach.call(document.querySelectorAll('[data-toggle="tooltip"]'), function(element){ new Tooltip(element) });
},false);
供应商/资产/javascripts/

最后,我将我的应用程序javascript标记移动到
并在不使用tuborlinks eval和turbolinks track的情况下异步加载它。这将javascript配置为在初始页面加载时运行一次。每次访问turbolinks页面时都会调用
turbolinks:load
侦听器,并附加引导本机事件列表在DOM中的适当组件中调用

app/views/layouts/application.html.erb

...
<head>
  ...
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload', 'data-turbolinks-eval': 'false', async: true %>
</head>
...
。。。
...
...
在撰写本文时,此解决方案已在Rails 5.1应用程序的生产环境中


顺便说一句,application.js中列出的所有Javascript在连接和缩小时都小于20KB。相比之下,它本身就缩小了86KB。可以显著缩短应用程序的下载时间。

BSN开发者在这里想,为什么不在BSN库之外添加此自定义代码,以便于维护

var container = document.getElementById('myContainer');
document.addEventListener('turbolinks:load', function(){
  container = container || document.getElementById('myContainer');
  Array.prototype.forEach.call(container.querySelectorAll('[data-spy="affix"]'), function(element){ new Affix(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-dismiss="alert"]'), function(element){ new Alert(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-toggle="buttons"]'), function(element){ new Button(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-ride="carousel"]'), function(element){ new Carousel(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-toggle="collapse"]'), function(element){ new Collapse(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-toggle="dropdown"]'), function(element){ new Dropdown(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-toggle="modal"]'), function(element){ new Modal(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-toggle="popover"]'), function(element){ new Popover(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-spy="scroll"]'), function(element){ new ScrollSpy(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-toggle="tab"]'), function(element){ new Tab(element) });
  Array.prototype.forEach.call(container.querySelectorAll('[data-toggle="tooltip"]'), function(element){ new Tooltip(element) });
},false);
您应该只查看特定的容器turbolinks更新,因为您不更新任何其他内容,您需要尽快更新

我还更新了,添加了一个通用示例

更新 从BSN 2.0.20版开始,您可以使用站点中的库
,而无需任何其他脚本,并且您可以更轻松地执行此
TurboLink

var container = document.getElementById('myContainer');
document.addEventListener('turbolinks:load', function(){
  container = container || document.getElementById('myContainer');
  BSN.initCallback(container);
}, false);
如果在控制台中键入
BSN
点击回车键,则会得到以下对象:

BSN = {
  version: '2.0.20',
  initCallback: function(lookup){},
  supports: [ /* an array with supported components */ ]
}
请记住,您不必使用
myContainer
作为turbolinks目标的ID属性,您可以使用任何东西使该元素唯一,我建议使用类似
data function=“turbolinks autoload”
的选择器


下载最新的master并试一试。

谢谢。Bootstrap Native使用加载设置。我将尝试添加您推荐的侦听器。我将尝试此解决方案。我过去遇到的一个问题是,TurboLink通过AJAX加载
标记之间的所有内容,然后事件侦听器不会被清除。因此,事件l监听器会不断堆积在这些组件上。也许有办法清除监听器。现代浏览器会立即清除垃圾,但如果你真的想支持带有多填充之类的旧浏览器,你需要分叉/构建你自己的BSN版本,以利用一些
destroy()
公共方法。此更新破坏了我的代码。它在第3行抛出了一个
未捕获的TypeError:Cannot read属性'querySelectorAll'为null
。将我的整个页面包装在
标记中消除了错误,但仍然禁用了下拉列表。在侦听器中移动
var容器…
解决了问题。但是,在nce turbolinks会重新加载
标记之间的所有内容。无论如何,我认为这不会加快速度。我更喜欢你之前的答案。我建议你回过头来。我不同意这一点。对于你的具体情况和所有类似情况,查看单个特定容器而不是整个文档要好得多,在任何情况下,一周中的任何一天,我都会更新我的代码让你重新开始工作。
var bsn = require('bootstrap.native/dist/bootstrap-native-v4');

document.addEventListener('turbolinks:load', () => {
    BSN.initCallback();
});