在click事件上只加载一次脚本

时间:2016-03-05 00:09:14

标签: javascript onclick getelementbyid typeof getelementsbytagname

我已经将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。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

触发后删除事件侦听器:

var searchLabel = document.getElementById('search-toggle-label');
searchLabel.addEventListener('click', loadScript, false);

function loadScript(){
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "wp-content/themes/2016/js/cse.js."; 
    document.getElementsByTagName("head")[0].appendChild(script);
    searchLabel.removeEventListener('click', loadScript, false);
    return false;
}

答案 1 :(得分:0)

如果DOM中存在脚本,则添加一个函数以返回true / false。这是一个:

function isScriptLoaded(src) {
  return !!Array.prototype.filter.call(document.getElementsByTagName('script'), function(node) {
    return node.src === src;
  });
}

然后使用它来测试脚本是否已插入DOM。

答案 2 :(得分:0)

也许尝试在函数定义之前设置一个标志。这样你可以检查函数开头的标志,省略其余部分。你也有一个我在互联网上找到的很好的例子。查看此solution

答案 3 :(得分:0)

使用它来同步加载脚本(并且只加载一次):

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')
    
  },
  ...