单击事件仅加载一次脚本
loading script only once on click event
我一起破解了 vanilla javascript 以在点击事件时加载外部脚本。
var searchLabel = document.getElementById('search-toggle-label');
searchLabel.onclick = function(){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "wp-content/themes/2016/js/cse.js.";
document.getElementsByTagName("head")[0].appendChild(script);
return false;
}
但每次点击事件时它都会加载相同的脚本。
所以我加入了一个 if 语句来检查值和类型。 "==="
var searchLabel = document.getElementById('search-toggle-label');
if (typeof searchLabel === 'undefined') {
searchLabel.onclick = function() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "wp-content/themes/2016/js/cse.js.";
document.getElementsByTagName("head")[0].appendChild(script);
return false;
}
}
else {
alert('loaded already');
}
显然,这是错误的,因为我在页面加载和点击事件时收到警告,脚本没有加载。
我很难过。我知道使用 jQuery 有一个简单的解决方案,但我正在尝试真正学习编写 javascript.
任何帮助将不胜感激。
如果 DOM 中存在脚本,则向 return true/false 添加一个函数。这是一个:
function isScriptLoaded(src) {
return !!Array.prototype.filter.call(document.getElementsByTagName('script'), function(node) {
return node.src === src;
});
}
然后用它来测试脚本是否已经插入 DOM。
也许可以尝试在函数定义之前设置一个标志。这样你就可以在函数开始时检查标志并忽略其余部分。你也有一个很好的例子,我在互联网上找到了。查一下这个 solution.
事件侦听器触发后将其移除:
var searchLabel = document.getElementById('search-toggle-label');
searchLabel.addEventListener('click', loadScript('wp-content/themes/2016/js/cse.js'), false);
function loadScript(src){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = src;
document.head.append(script);
return searchLabel.removeEventListener('click', loadScript, false);
}
使用它来同步加载脚本(并且只加载一次):
const isScriptLoaded = (src)=>{
const scripts = Array.from(document.getElementsByTagName('script')) || []
return scripts.filter((node) => node.src && node.src.indexOf(src)>-1).length>0
}
const loadScript = (src, once=true)=>{
if (once && isScriptLoaded(src)) return
return new Promise((resolve)=>{
const node = document.createElement('script')
node.setAttribute('src', src)
node.onload = ()=>{
setTimeout(()=>{ resolve() }, 0)
}
document.getElementsByTagName('head')[0].appendChild(node)
})
}
然后,在你的 vue 组件中:
...
async mounted () {
await loadScript('/js/globe.min.js') // wait for the script to be loaded
// this.scriptIsReadyLetsDoSomethingWithIt()
// Will do nothing if you call loadScript multiple times (as the script is already loaded)
// await loadScript('/js/globe.min.js')
},
...
我一起破解了 vanilla javascript 以在点击事件时加载外部脚本。
var searchLabel = document.getElementById('search-toggle-label');
searchLabel.onclick = function(){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "wp-content/themes/2016/js/cse.js.";
document.getElementsByTagName("head")[0].appendChild(script);
return false;
}
但每次点击事件时它都会加载相同的脚本。
所以我加入了一个 if 语句来检查值和类型。 "==="
var searchLabel = document.getElementById('search-toggle-label');
if (typeof searchLabel === 'undefined') {
searchLabel.onclick = function() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "wp-content/themes/2016/js/cse.js.";
document.getElementsByTagName("head")[0].appendChild(script);
return false;
}
}
else {
alert('loaded already');
}
显然,这是错误的,因为我在页面加载和点击事件时收到警告,脚本没有加载。
我很难过。我知道使用 jQuery 有一个简单的解决方案,但我正在尝试真正学习编写 javascript.
任何帮助将不胜感激。
如果 DOM 中存在脚本,则向 return true/false 添加一个函数。这是一个:
function isScriptLoaded(src) {
return !!Array.prototype.filter.call(document.getElementsByTagName('script'), function(node) {
return node.src === src;
});
}
然后用它来测试脚本是否已经插入 DOM。
也许可以尝试在函数定义之前设置一个标志。这样你就可以在函数开始时检查标志并忽略其余部分。你也有一个很好的例子,我在互联网上找到了。查一下这个 solution.
事件侦听器触发后将其移除:
var searchLabel = document.getElementById('search-toggle-label');
searchLabel.addEventListener('click', loadScript('wp-content/themes/2016/js/cse.js'), false);
function loadScript(src){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = src;
document.head.append(script);
return searchLabel.removeEventListener('click', loadScript, false);
}
使用它来同步加载脚本(并且只加载一次):
const isScriptLoaded = (src)=>{
const scripts = Array.from(document.getElementsByTagName('script')) || []
return scripts.filter((node) => node.src && node.src.indexOf(src)>-1).length>0
}
const loadScript = (src, once=true)=>{
if (once && isScriptLoaded(src)) return
return new Promise((resolve)=>{
const node = document.createElement('script')
node.setAttribute('src', src)
node.onload = ()=>{
setTimeout(()=>{ resolve() }, 0)
}
document.getElementsByTagName('head')[0].appendChild(node)
})
}
然后,在你的 vue 组件中:
...
async mounted () {
await loadScript('/js/globe.min.js') // wait for the script to be loaded
// this.scriptIsReadyLetsDoSomethingWithIt()
// Will do nothing if you call loadScript multiple times (as the script is already loaded)
// await loadScript('/js/globe.min.js')
},
...