javascript - Zurb Foundation:作为 ES 模块导入时,滑块插件不会触发事件
问题描述
我正在尝试在我的站点上仅使用 ES 模块,并且目前遇到了 Zurb Foundation 的问题。我使用Skypack导入 ES 模块并且不使用任何捆绑器。
当我在页面上放置一些经典的初始化代码时,滑块中的事件会按预期触发:
<!-- Basic slider template. See https://get.foundation/sites/docs/slider.html -->
<div id="test-slider" class="slider" data-slider data-initial-start="30" data-end="100">
<span class="slider-handle" data-slider-handle role="slider" tabindex="1"></span>
<span class="slider-fill" data-slider-fill></span>
<input type="hidden">
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.6.3/css/foundation.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.6.3/js/foundation.min.js"></script>
<script>
$(document).ready(function() {
// Init Foundation
//Foundation.addToJquery($);
$(document).foundation();
$('#test-slider').on('moved.zf.slider', function() {
console.log('This should work while slider slides!');
//console.log($._data($('#test-slider')[0]).events);
});
});
</script>
但是当我将上面的代码转换为 ES 模块时,滑块事件停止工作:
<h4>Drag the slider</h4>
<!-- Basic slider template. See https://get.foundation/sites/docs/slider.html -->
<div id="test-slider" class="slider" data-slider data-initial-start="30" data-end="100">
<span class="slider-handle" data-slider-handle role="slider" tabindex="1"></span>
<span class="slider-fill" data-slider-fill></span>
<input type="hidden">
</div>
<h4>Expected</h4>
<p>Drag slider and console should populated with <strong>'This should work while slider slides!'</strong> message.</p>
<h4>Current</h4>
<p>Drag slider and console shows nothing.</p>
<link rel="stylesheet" href="https://cdn.skypack.dev/foundation-sites/dist/css/foundation.css">
<script type="module">
import $ from 'https://cdn.skypack.dev/jquery?min'; // Latest jQuery from skypack.dev
import { Foundation } from 'https://cdn.skypack.dev/foundation-sites?min'; // Latest Foundation from skypack.dev
$(document).ready(function() {
Foundation.addToJquery($);
$(document).foundation();
$('#test-slider').on('moved.zf.slider', function () {
console.log('This should work while slider slides!');
//console.log($._data($('#test-slider')[0]).events);
});
// This will work because it is natural jQuery event, not the one from Foundation
//$('#test-slider').on('click', function () {
// console.log('Click works!');
//});
});
</script>
我错过了什么?以及如何解决?
带有问题代码的演示 Codepen 在这里!
解决方案
行。我想我找到了导致事件问题的原因。
在发布问题时,foundation-sites
模块导入使用了最新版本的 Zurb Foundation (v6.6.3),并且该版本是在内部使用 jQuery v3.5.1 导入编译的。可以通过跟踪https://cdn.skypack.dev/foundation-sites中的 url并检查代码来检查它。
但在问题的代码示例中,我使用import $ from 'https://cdn.skypack.dev/jquery?min'
导入最新的 jQuery 版本(v3.6.0)
因为我导入了 jQuery v3.6.0 并且 Foundation 模块在内部使用了 jQuery v3.5.1,所以事件侦听器被放置在不同的范围(某种)中,这与 Slider 或任何 Zurb Foundation UI 元素的范围不同,如果我'我在这里错了。
选项1。
所以解决方案是坚持使用某些版本的模块来与模块的内部 jQuery 版本“匹配” foundation-sites
。
替换这个:
import $ from 'https://cdn.skypack.dev/jquery?min'; // Latest jQuery from skypack.dev
import { Foundation } from 'https://cdn.skypack.dev/foundation-sites?min'; // Latest Foundation from skypack.dev
有了这个:
import $ from 'https://cdn.skypack.dev/jquery@3.5.1?min'; // jQuery v3.5.1 from skypack.dev
import { Foundation } from 'https://cdn.skypack.dev/foundation-sites@6.6.3?min'; // Foundation v6.6.3 from skypack.dev
选项 2。
如果有人有同样的问题,但不想“坚持”某些版本的 jQuery。
当 Foundation 包装元素时,它会向该元素添加jQuery{version}{some-kind-of-timestamp}
属性。像这样:
jQuery3510
Foundation 添加了两个以名称开头的属性。其中之一包含events
财产。但是当我们使用从不同 ES 模块导入的另一个 jQuery 版本时,还有另一个jQuery3600
带有events
. 当我这样做时
$('#test-slider').on('moved.zf.slider', function () {
// Do something
});
事件的注册moved.zf.slider
进入jQuery3600
,而不是jQuery3510
应该进入。
所以这里的解决方案是jQuery3510
使用events
来自jQuery3600
. 我使用执行此操作的函数扩展 jQuery:
$.fn.mutatedOn = function (events, callback) {
function getPropsByName(obj, startWith) {
return Object.keys(obj).filter((propertyName) => {
return propertyName.indexOf(startWith) === 0;
});
}
function findPropsWithEvents(obj) {
const props = getPropsByName(obj, "jQuery");
return props.find((element) => {
return obj[element].events !== undefined;
});
}
$(this).each((index, el) => {
// Let's find all properties which starts with 'jQuery'.
// And filter them to determine those which contains 'events'
// right before we attach the event listener.
const jqueryKeys = getPropsByName(el, "jQuery");
const jqueryKeysWithEvents = findPropsWithEvents(el);
$(el).on(events, callback);
// After the listener attached, another 'jQuery' property with 'events' was added for $(el).
// Let's find this newly added property using difference between new and old arrays.
const newJqueryKeys = getPropsByName(el, "jQuery");
const newJqueryKeysWithEvents = $(newJqueryKeys).not(jqueryKeys).get(0);
// After we determine new property with 'events'
// lets merge it into the old one to make Foundation events work as expected.
$.extend(el[jqueryKeysWithEvents], el[newJqueryKeysWithEvents]);
});
};
然后这个:
$('#test-slider').on('moved.zf.slider', function () {
// Do something
});
可以简单地替换为:
$('#test-slider').mutatedOn('moved.zf.slider', function () {
// Do something
});
推荐阅读
- c# - SslStream 在 .NET Core 2.1+ 中不调用 InnerStream 的 BeginRead 或 ReadAsync(与 .NET Framework 和 .NET Core 2.0 相反)
- python - 获取完整的正则表达式匹配
- reactjs - 如何在页面上显示新用户?
- postgresql - Homebrew MacOS 安装后在 postres 中加载扩展问题
- docker - Docker Registry 在重新启动时丢失图像数据
- forms - python形式的下拉菜单
- mysql - 如何从不同的表中选择百分比和计数计算
- sql - 在单行中创建表的实例?
- c++ - shared_ptr - 从包含的对象中访问
- bash - 将程序的输出重定向到shell脚本中的变量