Короткий ответ
Проблема в том, что загрузка <script>
s является асинхронной операцией.
И поскольку вы динамически вставляете эти сценарии, когда ваша инструкция $.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;
, ваши сценарии будут загружены в правильном порядке, но этоне помешает выполнить $.contextMenu
первым.
Я бы посоветовал вам взглянуть на эту замечательную статью HTML5 Rocks , касающуюся загрузки скриптов.