为啥我的 Mapbox GL JS 地图在通过 Turbolinks 首次访问时无法正确显示?

Posted

技术标签:

【中文标题】为啥我的 Mapbox GL JS 地图在通过 Turbolinks 首次访问时无法正确显示?【英文标题】:Why doesn't my Mapbox GL JS map display properly on first visit via Turbolinks?为什么我的 Mapbox GL JS 地图在通过 Turbolinks 首次访问时无法正确显示? 【发布时间】:2021-02-12 09:28:18 【问题描述】:

我正在尝试将 Turbolinks 添加到我的 Rails 6 应用程序(我参加聚会迟到了),但我遇到了 TailwindCSS 和 Mapbox GL JS 的显示问题。

如果我在带有地图的页面上开始我的旅程(新标签页或刷新页面),那么在我访问期间一切都会按预期进行(我可以反复离开并返回带有地图的页面并且每次一切都按预期工作)。我什至可以访问带有 other Mapbox 实例的页面,并且这些实例可以正确显示(我正在慢慢地从每个页面上的孤立的 script 标记转换到 StimulusJS,这让我只剩下几个 Mapbox-提供控制器,例如 mapcity_controller 和 mapstreet_controller - 我不认为这是问题的一部分,但我不想留下任何机会)。

但是,如果我在没有地图的其他页面上开始我的旅程(新标签或刷新页面),然后导航到带有 Mapbox 的页面,fixedw-* 样式不会'不工作。如果我滚动页面,地图会随着内容一起向上流动,并且地图不会填满它应该填满的整个 w-2/3 空间。

<div data-controller="mapbox" class="flex flex-col-reverse flex-wrap mt-10 md:flex-row">
  <div class="h-full p-2 mt-64 overflow-scroll md:mt-0 lg:mt-0 md:w-1/2 lg:w-1/3">
    CONTENT
  </div>

  <div class="md:w-1/2 lg:w-2/3">
    <div id="map" class="fixed w-full h-64 md:w-1/2 lg:w-2/3 md:bottom-0 md:right-0 md:h-full"></div>
  </div>
</div>

我认为它可能是父级 md:w-1/2 lg:w-2/3 容器 div,但删除它根本不会改变行为:

<div data-controller="mapbox" class="flex flex-col-reverse flex-wrap mt-10 md:flex-row">
  <div class="h-full p-2 mt-64 overflow-scroll md:mt-0 lg:mt-0 md:w-1/2 lg:w-1/3">
    CONTENT
  </div>

  <div id="map" class="fixed w-full h-64 md:w-1/2 lg:w-2/3 md:bottom-0 md:right-0 md:h-full"></div>
</div>

如果我从等式中删除 Mapbox,则在任一访问场景中一切都会按预期工作(无论该页面是否是我第一次访问,我总是有一个全宽、非滚动的右窗格):

<div class="flex flex-col-reverse flex-wrap mt-10 md:flex-row">
  <div class="h-full p-2 mt-64 overflow-scroll md:mt-0 lg:mt-0 md:w-1/2 lg:w-1/3">
    LOTS OF MULTI-LINE CONTENT TO CAUSE SCROLLING
  </div>

  <div class="fixed w-full h-64 bg-blue-300 md:w-1/2 lg:w-2/3 md:bottom-0 md:right-0 md:h-full">OTHER CONTENT</div>
</div>

我猜我的 StimulusJS 控制器的某些东西不能与 Turbolinks 一起正常工作。我已经删除了所有额外的代码(设置缩放级别、添加源和图层等),但问题仍然存在。我试过使用connectinitialize,结果相同。

import  Controller  from 'stimulus'
import mapboxgl from 'mapbox-gl'

export default class extends Controller 
  connect () 
    mapboxgl.accessToken = "my-access-token"
    this.map = new mapboxgl.Map(
      container: 'map',
      style: 'mapbox://styles/mapbox/satellite-streets-v11',
      center: [0,0],
      zoom: 2,
      minZoom: 1
    )
  

  disconnect () 
    this.map.remove()
    this.map = undefined
  

以防万一,这是我的index.js 文件:

import  Application  from 'stimulus'
import  definitionsFromContext  from 'stimulus/webpack-helpers'

const application = Application.start()
const context = require.context('controllers', true, /_controller\.js$/)
application.load(definitionsFromContext(context))

这是我的packs/application.js 文件:

require('@rails/ujs').start()
require('turbolinks').start()
require('stylesheets/application.scss')
require('stylesheets/custom.scss')
require('src')
import 'controllers'

application.scss 文件包含:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

custom.scss 中的任何自定义样式都不适用于地图或其容器 div。

【问题讨论】:

【参考方案1】:

深呼吸

好的?这真的很尴尬?

当我最初实现这个网站时,我采用了在头部添加&lt;%= yield :styles %&gt; 并在页面底部添加&lt;%= yield :scripts %&gt; 的方法,而&lt;% content_for(:scripts) do %&gt; 会在我想要的任何地方阻止javascript

旁白的声音:他不应该这样做。

<% content_for(:styles) do %>
  <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />
<% end %>

如果我删除我的 :styles 块并将样式表标签直接放在头部,一切都会按预期工作。

【讨论】:

以上是关于为啥我的 Mapbox GL JS 地图在通过 Turbolinks 首次访问时无法正确显示?的主要内容,如果未能解决你的问题,请参考以下文章

样式未完成加载:Mapbox GL JS

如何将自定义字段传递到 mapbox-gl js 以在地图上创建点?

点击 Mapbox GL JS 显示 Lat Lng 坐标

如何将 Mapbox Mapmatching API 输出与 mapbox-gl-js 一起使用?

Mapbox GL JS:如果单击标记,则忽略地图单击事件

mapbox-gl:从中心点、缩放级别和尺寸计算地图边界