如何在Turbolinks中使用HTML初始化Flickity?

3

我正在使用 Flickity 库

以下是我的 HTML 代码:

<section class="controls-inside controls-light p-0" data-flickity='{ "imagesLoaded": true, "wrapAround": true }'>

它在第一次加载时表现良好,会创建这个HTML:
<section class="controls-inside controls-light p-0 flickity-enabled is-draggable" data-flickity="{ "imagesLoaded": true, "wrapAround": true }" tabindex="0">

但是当我导航到其他页面并尝试返回主页(其中包含此代码)时,它只生成顶部的第一个代码(即未初始化版本)。

这是目前我的TL代码:

$(document).on("turbolinks:load", () => {
  $('[data-toggle="tooltip"]').tooltip()
  $('[data-toggle="popover"]').popover()
})

鉴于我正在使用HTML初始化,那么我如何使用TL处理它?

编辑1

如果尚未通过HTML进行初始化,则我也可以通过JS初始化Flickity。 两种方式都可以,只要它能正常工作。

编辑2

现在,在我的 application.js 中,我有以下内容:

$(document).on("turbolinks:load", () => {
  var Flickity = require('flickity');
  var flkty = new Flickity( 'section[data-flickity]', {
      imagesLoaded: true,
      wrapAround: true,
  });
})

这有点管用。问题在于,当我尝试导航到另一页并返回具有滑块的页面时,我可以看到它加载两次。也就是说,它最初加载了滑块,我看到它,然后在加载栏进度的中途整个页面再次刷新。所以感觉它做了两倍的工作。我只想它加载一次。

它还会在我的浏览器控制台中产生以下错误。

在页面第一次加载时:

flickity.js:57 Uncaught TypeError: Cannot read property 'option' of undefined
    at new Flickity (flickity.js:57)
    at HTMLDocument.<anonymous> (application.js:43)
    at HTMLDocument.dispatch (jquery.js:4670)
    at HTMLDocument.elemData.handle (jquery.js:4490)
    at Object../node_modules/turbolinks/dist/turbolinks.js.e.dispatch (turbolinks.js:75)
    at r.notifyApplicationAfterPageLoad (turbolinks.js:994)
    at r.pageLoaded (turbolinks.js:948)
    at turbolinks.js:872
Flickity @ flickity.js:57
(anonymous) @ application.js:43
dispatch @ jquery.js:4670
elemData.handle @ jquery.js:4490
./node_modules/turbolinks/dist/turbolinks.js.e.dispatch @ turbolinks.js:75
r.notifyApplicationAfterPageLoad @ turbolinks.js:994
r.pageLoaded @ turbolinks.js:948
(anonymous) @ turbolinks.js:872
flickity.js:57 Uncaught TypeError: Cannot read property 'option' of undefined
    at new Flickity (flickity.js:57)
    at utils.js:217
    at Array.forEach (<anonymous>)
    at utils.js:201

如果我清除控制台中的错误,然后离开页面再回来,这个错误将是第二次加载页面时控制台中唯一的错误:
flickity.js:47 Bad element for Flickity: section[data-flickity]

这些错误的原因是什么,我该如何修复它?

编辑3

在我的application.js中,我已经相应地引入了Flickity。

import '../src/flickity.pkgd.min'

此外,我的package.json文件如下所示:

{
  "name": "myapp",
  "private": true,
  "dependencies": {
    "@rails/actioncable": "^6.0.0",
    "@rails/actiontext": "^6.0.2-2",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "4.2.2",
    "bootstrap": "^4.4.1",
    "data-confirm-modal": "^1.6.2",
    "expose-loader": "^0.7.5",
    "flickity": "^2.2.1",
    "jquery": "^3.5.0",
    "local-time": "^2.1.0",
    "popper.js": "^1.16.1",
    "stimulus": "^1.1.1",
    "trix": "^1.0.0",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.10.3"
  }
}

编辑4

这是我的application.js文件的内容:

import '../src/flickity.pkgd.min'

$(document).on("turbolinks:load", () => {
  var Flickity = require('flickity');
  var flkty = new Flickity( 'section[data-flickity]', {
      imagesLoaded: true,
      wrapAround: true,
  });
})

以下是我在JS控制台中第一次加载页面时得到的错误。

first-load-errors-flickity

第五次编辑

所有问题基本上都已经解决了,但是每当我返回到之前用Flickity加载过的页面时,仍然会看到双重刷新。

例如,考虑以下流程:

  • 进入带有Flickity的主页(home page) (只加载一次)
  • 进入不带Flickity的文章#新(Article#New)(只加载一次,并且根据最新更新,Flickity不会加载或抛出JS错误)。
  • 返回带有Flickity的主页(home page) (它开始加载,并且在初始页面加载大约1/4或1/3的进度时,它会进行完全的页面刷新并加载整个页面)。该页面刷新是明显可见的,因为它发生在页面开始加载大约1-2秒后。

我最初认为这是因为我两次初始化了Flickity,即一次使用下面答案中的JS,一次通过HTML进行如下操作:

<section id="featured-header" class="controls-inside controls-light p-0" data-flickity='{ "imagesLoaded": true, "wrapAround": true }'>

因此,我将JS选择器替换为此标记的id并删除了data-flickity的HTML初始化,但它仍然具有相同的行为。例如,我测试了以下代码:

<section id="featured-header" class="controls-inside controls-light p-0">

因此我认为这与JS有关。

顺便说一下,看起来它实际上只是重新加载了 section[data-flickity]而不一定是整个页面。 当我通过各种链接导航时,它也不会重新加载任何其他页面。 这仅适用于 section[data-flickity]元素。

1个回答

4

您可以删除应用程序src目录中的JS文件,并使用NPM进行安装。

npm install flickity

接下来,在application.css文件中引入Flickity CSS文件。

*= require flickity.css

接下来,在你的JS文件中,你可以在turbolinks:load上初始化Flickity,就像你为tooltip和popover所做的那样。

import Flickity from 'flickity';

$(document).on("turbolinks:load", () => {
    if($('section[data-flickity]').length > 0) {
        var flkty = new Flickity( 'section[data-flickity]', {
            imagesLoaded: true,
            wrapAround: true,
        });
    }
})

谢谢您。但是我遇到了一个错误:Uncaught TypeError: $(...).flickity is not a function at HTMLDocument.<anonymous> (application.js:40) at HTMLDocument.dispatch (jquery.js:4670) at HTMLDocument.elemData.handle (jquery.js:4490) at Object../node_modules/turbolinks/dist/turbolinks.js.e.dispatch (turbolinks.js:75) at r.notifyApplicationAfterPageLoad (turbolinks.js:994) at r.pageLoaded (turbolinks.js:948) at turbolinks.js:872。这可能是什么原因引起的? - marcamillion
你是通过NPM安装了这个插件吗?如果是,你能否检查一下在使用require('flickity')时是否有任何控制台错误? - Gokul
我两种方法都尝试了。我通过NPM安装了这个插件,当我通过控制台检查时,出现了以下错误:require('flickity') VM876:1 Uncaught ReferenceError: require is not defined at <anonymous>:1:1. 我还将JS文件放在../src/目录中。当我尝试使用require('../src/..')时,它可以正常呈现,但仍会在我的控制台中产生错误,并在第二次加载页面时产生奇怪的双重刷新。即那并没有起作用。 - marcamillion
1
说得明白一点,我没有 application.css,只有 application.scss。那么我应该在那里做必要的 require 呢?比如说 //= require flickity,而不是 *= require flickity.css - marcamillion
1
好的,我们已经取得了很大的进展。我做了我说过的事情,它运行得非常好。我不再在控制台中看到那些错误了。但是,当我回到带有Flickity的页面时,我看到第二次重新加载(尽管此时可能是不可避免的?)。我还看到的另一件事是,当我导航到任何没有 section[data-flickity] 的页面时,它会抛出一个 Bad element for Flickity: section[data-flickity]。那么,我该如何仅在存在特定页面上时触发TL呢?或者,如果它存在于页面上,我该如何仅触发它? - marcamillion
显示剩余14条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接