Foundation 5 topbar incompatible with Rails Turbolinks
Closed this issue · 4 comments
I've built a simple Rails application that includes a Foundation 5 topbar. Here are the relevant files, in an implementation that works:
# app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require foundation
//= require_tree .
$(function() {
$(document).foundation();
});
# app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Test</title>
<%= stylesheet_link_tag "application", media: "all" %>
<%# Modernizr is required for Zurb Foundation %>
<%= javascript_include_tag "vendor/modernizr" %>
<%= csrf_meta_tags %>
</head>
<body>
<header>
<%# navigation styled for Zurb Foundation 5 %>
<nav class="top-bar" data-topbar>
<ul class="title-area">
<li class="name"><%= link_to 'Home', root_path %></li>
<li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
</ul>
<div class="top-bar-section">
<ul>
<li><%= link_to 'About', root_path %></li>
<li><%= link_to 'Contact', root_path %></li>
</ul>
</div>
</nav>
</header>
<main role="main">
<%= yield %>
</main>
<%= javascript_include_tag "application" %>
</body>
</html>
If I add Rails Turbolinks, the implementation fails.
Many Rails developers will attempt to use Turbolinks since Turbolinks is part of a standard Rails build. Turbolinks is part of a standard Rails build, with any new Rails application.
Here are the same files, with Turbolinks enabled:
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require foundation
//= require_tree .
$(function() {
$(document).foundation();
});
# app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= content_for?(:title) ? yield(:title) : "Learn Rails" %></title>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%# Modernizr is required for Zurb Foundation %>
<%= javascript_include_tag "vendor/modernizr" %>
<%= csrf_meta_tags %>
</head>
<body>
<header>
<%# navigation styled for Zurb Foundation 5 %>
<nav class="top-bar" data-topbar>
<ul class="title-area">
<li class="name"><%= link_to 'Home', root_path %></li>
<li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
</ul>
<div class="top-bar-section">
<ul>
<li><%= link_to 'About', root_path %></li>
<li><%= link_to 'Contact', root_path %></li>
</ul>
</div>
</nav>
</header>
<main role="main">
<%= yield %>
</main>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
</body>
</html>
The JavaScript console shows an error:
Uncaught TypeError: Cannot read property 'scrolltop' of undefined foundation.topbar.js?body=1:93
+1 this sucks.
Specifically this won't work because you must include the foundation.js in the BODY tag. With turbolinks JS has to be included in HEAD, as the body gets wiped on each request — as noted in Issue #3643
There's a pretty simple fix: /pull/3668
You just need to (re)move FastClick or wrap Foundation in a closure and load when the DOM is ready.
I've written a more detailed explanation in a comment of a related issue.
What solved for me was to include "jquery.turbolinks" and bind the initialization to the jquery document ready