要回答您的问题,需要解决两个不同的问题:
- 如何在 VuePress 中运行自定义 JavaSCript?
- 如何使用 JavaScript 在我当前的 VuePress 主题中关闭任何以前打开的下拉菜单?
对于第一个问题,有几个解决方案(其中一个是使用自定义组件,其代码在其 mounted() 挂钩中运行,但这需要您在每个页面中包含该组件并确保它不会运行多次(因为您想将事件绑定到元素)。
我相信最干净的方法是在<head> 中添加<script>,这可以通过将其添加到.vuepress/config.js 导出的head 属性中来实现:
head: [
// ...existing stuff, if any,
['script', {}, `
(function() {
// your code here...
})();
`]
]
但是,上述解决方案存在一些问题。首先,它将在解析后立即运行,并且位于 <head> 标记内。这意味着尚未呈现您页面的任何内容。第二个问题是您在模板文字中。您真的不想在模板文字中编写 JavaScript 代码。理想情况下,您应该能够将您的代码放在“.js”文件中并将其附加为<script> 标记。
为此,您需要创建一个.vuepress/public/ 文件夹(如果您还没有)。将您的.js 文件放在那里(我使用了test.js,但您可以随意命名)。将以上代码修改为:
['script', {}, `
(function() {
var s = document.createElement('script');
s.src = './test.js';
var h = document.querySelector('head');
h.appendChild(s);
})();
`]
将./test.js 更改为您的文件名。
现在您的文件已包含干净的 JavaScript,并且大门已打开。您的代码在窗口对象上下文中执行。
要回答您问题的第二部分,嗯...,这在很大程度上取决于您使用的主题。如果您使用的是默认主题(似乎是这种情况,来自您发布的 SS),如果放置在您的 .js 文件中,这应该可以工作:
document.addEventListener('DOMContentLoaded', fixDropDowns);
function fixDropDowns() {
document.body.addEventListener('click', (ev) => {
const header = document.querySelector('header');
if (header) {
const dds = header.querySelectorAll('.dropdown-wrapper');
[...dds].forEach(el => el.classList.remove('open'));
const curr = ev.target.closest('.dropdown-wrapper');
if (curr) {
curr.classList.add('open');
}
}
})
}
但它基于对生成的标记的仔细检查。
具体来说,下拉列表有一个 .dropdown-wrapper 类,并且它们是通过在它们上切换类 open 来打开的。以上只是一个示例,可能不适用于其他主题,甚至可能在将来的某个版本中停止使用默认主题。