如果我有点困惑,请原谅我,我正在冒险进入我的编程新领域,并边走边学习。我正在努力解决的基本概念:
在我的 Rails 4 应用程序中,我使用 Leaflet(一个用于映射的 JS 库)并调用一些我自己的代码。长话短说,我无法让 Leaflet 和 Turbolinks 很好地协同工作,因此对于我网站中需要 Leaflet 的页面,我禁用了 Turbolinks,另外我还加载页面特定的 Coffeescript。
我现在决定添加一个后退按钮。用法如下 - 从使用 Leaflet 的页面,用户可以单击 map 的一部分,然后转到使用 Turbolinks 的页面(如果重要的话)。在 Turbolinks 页面上,我有一个后退按钮可带您返回 Leaflet map 。
但是,当我返回 Leaflet 页面时,我的 CoffeeScript 要么没有运行,要么在错误的时间运行(我收到了一些第一次运行时不存在的错误)。我猜我需要在 Coffeescript 的开头添加另一个事件或选择一个不同的事件,但我只是不确定它应该是什么。
如果您对如何使用 Turbolinks 有建议,并且它有助于使后退按钮正常工作,我绝对不会放弃在 Leaflet 页面上使用 Turbolinks。 :)
_navbar.html.erb
<li><%= link_to("By grid", grid_path, data: {turbolinks: false}) %></li>
grid.html.erb
... code for layout goes here ...
<% content_for :header do %>
<%= javascript_include_tag "leaflet" %>
<% end %>
<% content_for :javascript do %>
<%= javascript_include_tag "leaflet-maps/#{filename}" %>
<% end %>
传单 map /grid.coffee
$ ->
document.addEventListener 'page:restore', ->
app.init()
return
... rest of coffeescript goes here ...
... here is how the link is getting called
layer.on 'click', (e) ->
window.location.href='/show?grid='+feature.id
return
show.html.erb
<%= link_to "Back", :back %>
更新
grid.coffee
- 完整的 CoffeeScript 代码
ready = ->
#--------------------------------------------------
# Build tooltip with plant name
#--------------------------------------------------
onEachFeature = (feature, layer) ->
if feature.properties and feature.properties.grid_name
layer.bindTooltip feature.properties.grid_name
layer.on 'click', (e) ->
window.location.href='/show?grid='+feature.id
return
return
#--------------------------------------------------
# Variables
#--------------------------------------------------
L.Icon.Default.imagePath = '/assets'
gridStyle = {
"color": "#ff7800",
}
neCorner = L.latLng([47.635103, -122.320525])
swCorner = L.latLng([47.634083, -122.321129])
#--------------------------------------------------
# Set view and load Google Maps
#--------------------------------------------------
map = L.map("map", zoomSnap: .25)
map.fitBounds([swCorner, neCorner])
map.invalidateSize(false)
map.options.maxZoom = 22
map.options.bounceAtZoomLimits = true
googleLayer = L.gridLayer.googleMutant(type: 'roadmap').addTo(map)
map.addLayer googleLayer
#--------------------------------------------------
# Get Ajax data
#--------------------------------------------------
$.ajax
dataType: 'text'
url: 'grid.json'
success: (data) ->
L.geoJSON(JSON.parse(data), style: gridStyle, onEachFeature: onEachFeature ).addTo map
error: ->
alert "Failed to load AJAX data"
document.addEventListener 'turbolinks:load', ready()
document.addEventListener 'DOMContentLoaded', ready()
最佳答案
所以,有两个地方你可能会偏离正轨。第一个在这里:
$ ->
document.addEventListener 'page:restore', ->
app.init()
这句话的意思是......“当网页发出 DOMContentLoaded 事件时,然后,当其他东西发出 page:restore
事件时,然后运行我的 JavaScript 代码。”
让我们从 DOMContentLoaded
开始。这是浏览器默认发出的事件,jQuery 框架使用它来触发事件监听器。 You can read more about jQuery's .ready()
function here .
page:restore
事件不是标准发出的事件,而是 a custom event used in Turbolinks Classic (版本 <5.0,自 2016 年 2 月起已弃用),我相信自从您提到 Rails 4 以来您正在使用该版本。
无论哪种方式,将两个监听器堆叠在一起可能不是您想要做的。您可以做什么定义一个在 ready
和 page:restore
上运行的函数...
function ready() {
// All of the setup you want to do...
}
document.addEventListener("turbolinks:load", ready());
document.addEventListener("DOMContentLoaded", ready());
(抱歉,我知道您正在编写 CoffeeScript。那不是我的菜。我希望我的 JavaScript 没问题...)
就是一个。我看到了另一个改进的机会。
layer.on 'click', (e) ->
你的意思是“当文档加载时,监听layer
对象上的点击,然后做这件事。”
我不太确定 layer
是什么,如果它是特定于 Leaflet 的,我可能无法为您提供帮助。然而,实际上有一种更具弹性的方式来编写它。
$(document).on("click","layer", function() {
// do things with the layer
});
这可能看起来相同,但有细微的差别。它说“每当我单击文档时,如果我也碰巧单击了某个图层,则执行此操作。”
这更具弹性,因为您的 JavaScript 行在运行时始终可以找到文档
。如果您的图层
在该行代码运行时尚未呈现,则它永远不会捕获这些点击。
祝你 JavaScript 快乐! :)
关于javascript - Rails 4、turbolinks 和 Coffeescript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41244171/