Svelte and Jquery - Dropdown.svelte:7 Uncaught TypeError: jquery(...).dropdown is not a function
Svelte and Jquery - Dropdown.svelte:7 Uncaught TypeError: jquery(...).dropdown is not a function
我正在尝试在 Svelte 中使用语义 UI(使用 jQuery)。我正在尝试初始化下拉功能,但出现以下错误:Uncaught TypeError: jquery(...).dropdown is not a function。我不确定为什么会这样。
Dropdown.svelte
<svelte:head>
<script src="jquery.js"></script>
<script src="dropdown.js"></script>
<link rel="stylesheet" type="text/css" href="dropdown.css">
</svelte:head>
<script>
import { onMount } from 'svelte';
import jQ from 'jquery';
onMount(() => {
jQ( document ).ready(function() {
jQ('.ui.selection.dropdown').dropdown();
});
});
</script>
<div class="ui selection dropdown">
<input type="hidden" name="gender">
<i class="dropdown icon"></i>
<div class="default text">Gender</div>
<div class="menu">
<div class="item" data-value="1">Male</div>
<div class="item" data-value="0">Female</div>
</div>
</div>
问题是当您加载它们的 JS 时,Semantic 的组件期望 jQuery 已经作为 window.jQuery
可用。
例如,这是来自 dropdown.js
的摘录(参见 Github 上的 the line):
;(function ($, window, document, undefined) {
...
})( jQuery, window, document );
因此,在加载 Semantic 的 JS 之前,您必须确保 jQuery
已加载并附加到 window
。
您的代码无法实现此目的的原因是 <svelte:head>
的内容仅在呈现组件时附加到 DOM,而不是之前。 render后立即调用了onMount
,但是此时刚刚添加的<script>
标签还没有加载完毕
您可以通过侦听此脚本的 load
事件来进行同步,但这很复杂,不会让您走得太远。问题是这些 <svelte:head>
的内容被附加 组件的每个实例 。这不适用于可以在页面上多次出现的组件。
那么,我们能做什么呢?一种解决方案是在 index.html
:
中的捆绑包之前加载 jQuery
<script src="/vendor/jquery.js"></script>
<script type="module" defer src='/build/bundle.js'></script>
有了这个,你可以保证 jQuery 在你的包代码执行之前可用。在你的 Dropdown.svelte
中,你会有这样的代码:
<script>
import { onMount } from 'svelte'
import '../semantic/dist/components/transition.js'
import '../semantic/dist/components/dropdown.js'
// you should also probably make your bundler process & manage your
// CSS dependencies, because in <svelte:head>, CSS links could be
// duplicated at runtime -- you'll need a Rollup / Webpack CSS plugin
import '../semantic/dist/components/reset.css'
import '../semantic/dist/components/transition.css'
import '../semantic/dist/components/dropdown.css'
onMount(() => {
jQuery('.ui.selection.dropdown').dropdown()
})
</script>
...
另一种选择是同步导入。对于正常的 ES 导入,您无法保证它们的处理顺序。但是您可以使用动态导入来做到这一点。这会给你这样的代码:
<script>
import { onMount } from 'svelte'
import jQuery from 'jquery'
// import the required CSS, somehow
onMount(async () => {
if (!window.jQuery) window.jQuery = jQuery
await import('../semantic/dist/components/transition.js')
await import('../semantic/dist/components/dropdown.js')
jQuery('.ui.selection.dropdown').dropdown()
})
</script>
...
不过,您需要使您的捆绑器配置恰到好处才能在您的项目中启用动态导入。
我正在尝试在 Svelte 中使用语义 UI(使用 jQuery)。我正在尝试初始化下拉功能,但出现以下错误:Uncaught TypeError: jquery(...).dropdown is not a function。我不确定为什么会这样。
Dropdown.svelte
<svelte:head>
<script src="jquery.js"></script>
<script src="dropdown.js"></script>
<link rel="stylesheet" type="text/css" href="dropdown.css">
</svelte:head>
<script>
import { onMount } from 'svelte';
import jQ from 'jquery';
onMount(() => {
jQ( document ).ready(function() {
jQ('.ui.selection.dropdown').dropdown();
});
});
</script>
<div class="ui selection dropdown">
<input type="hidden" name="gender">
<i class="dropdown icon"></i>
<div class="default text">Gender</div>
<div class="menu">
<div class="item" data-value="1">Male</div>
<div class="item" data-value="0">Female</div>
</div>
</div>
问题是当您加载它们的 JS 时,Semantic 的组件期望 jQuery 已经作为 window.jQuery
可用。
例如,这是来自 dropdown.js
的摘录(参见 Github 上的 the line):
;(function ($, window, document, undefined) {
...
})( jQuery, window, document );
因此,在加载 Semantic 的 JS 之前,您必须确保 jQuery
已加载并附加到 window
。
您的代码无法实现此目的的原因是 <svelte:head>
的内容仅在呈现组件时附加到 DOM,而不是之前。 render后立即调用了onMount
,但是此时刚刚添加的<script>
标签还没有加载完毕
您可以通过侦听此脚本的 load
事件来进行同步,但这很复杂,不会让您走得太远。问题是这些 <svelte:head>
的内容被附加 组件的每个实例 。这不适用于可以在页面上多次出现的组件。
那么,我们能做什么呢?一种解决方案是在 index.html
:
<script src="/vendor/jquery.js"></script>
<script type="module" defer src='/build/bundle.js'></script>
有了这个,你可以保证 jQuery 在你的包代码执行之前可用。在你的 Dropdown.svelte
中,你会有这样的代码:
<script>
import { onMount } from 'svelte'
import '../semantic/dist/components/transition.js'
import '../semantic/dist/components/dropdown.js'
// you should also probably make your bundler process & manage your
// CSS dependencies, because in <svelte:head>, CSS links could be
// duplicated at runtime -- you'll need a Rollup / Webpack CSS plugin
import '../semantic/dist/components/reset.css'
import '../semantic/dist/components/transition.css'
import '../semantic/dist/components/dropdown.css'
onMount(() => {
jQuery('.ui.selection.dropdown').dropdown()
})
</script>
...
另一种选择是同步导入。对于正常的 ES 导入,您无法保证它们的处理顺序。但是您可以使用动态导入来做到这一点。这会给你这样的代码:
<script>
import { onMount } from 'svelte'
import jQuery from 'jquery'
// import the required CSS, somehow
onMount(async () => {
if (!window.jQuery) window.jQuery = jQuery
await import('../semantic/dist/components/transition.js')
await import('../semantic/dist/components/dropdown.js')
jQuery('.ui.selection.dropdown').dropdown()
})
</script>
...
不过,您需要使您的捆绑器配置恰到好处才能在您的项目中启用动态导入。