我想用JavaScript加载jQuery插件jQuery contextMenu。
我尝试在Chrome开发者工具控制台上遵循JavaScript脚本,但收到错误VM4631:1 Uncaught TypeError: $.contextMenu is not a function
。
// setting up jQuery contextMenu Plugin
function dynamicallyLoadScript(url) {
var script = document.createElement("script");
script.src = url;
document.head.appendChild(script);
}
dynamicallyLoadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js')
var link = document.createElement( "link" );
link.href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.0/jquery.contextMenu.min.css" ;
link.type = "text/css";
link.rel = "stylesheet";
link.media = "screen,print";
document.getElementsByTagName( "head" )[0].appendChild( link );
dynamicallyLoadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.0/jquery.contextMenu.min.js')
dynamicallyLoadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.0/jquery.ui.position.js')
// testing
$.contextMenu({
selector: '#post-868 > div > header > h2 > a',
items: {
copy: {
name: "Copy",
callback: function(key, opt){
alert("Clicked on " + key);
}
}
}
});
答案 0 :(得分:0)
简短答案
问题在于user
的加载是异步操作。
而且由于您是动态插入这些脚本的,所以在执行<script>
指令时,尚未加载必需的脚本。
说明
当您在页面$.contextMenu
中使用<script>
标签静态地定义多个脚本时,浏览器将以并行方式获取它们并尽快执行它们,保持顺序(并阻止进一步解析页面)。
但是对于您来说,您是动态将<head>
标记一个接一个地插入页面<script>
,这意味着:
<head>
加载期间,执行继续,因此<script>
在确实加载$.contextMenu
之前执行。 为了说明这一点,我在<script>
指令之前添加了console.log
,并在$.contextMenu
函数中添加了console.time/timeEnd
:
dynamicallyLoadScript
我不知道为什么您要用这种方式加载脚本。
如果添加function dynamicallyLoadScript(url) {
var script = document.createElement("script");
script.src = url;
// Print log on script loaded
script.onload = () => { console.timeEnd(url); };
console.time(url);
document.head.appendChild(script);
}
dynamicallyLoadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js')
var link = document.createElement( "link" );
link.href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.0/jquery.contextMenu.min.css" ;
link.type = "text/css";
link.rel = "stylesheet";
link.media = "screen,print";
document.getElementsByTagName( "head" )[0].appendChild( link );
dynamicallyLoadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.0/jquery.contextMenu.min.js')
dynamicallyLoadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.0/jquery.ui.position.js')
console.log('Calling $.contextMenu');
$.contextMenu({
selector: '#post-868 > div > header > h2 > a',
items: {
copy: {
name: "Copy",
callback: function(key, opt){
alert("Clicked on " + key);
}
}
}
});
,将以正确的顺序加载脚本,但这不会阻止script.async = false;
首先执行。
我建议您看看this great HTML5 Rocks article处理脚本加载的问题。