Можете ли вы загрузить jQuery contextMenu с помощью JavaScript? - PullRequest
0 голосов
/ 09 сентября 2018

Я хочу загрузить плагин jQuery jQuery contextMenu с JavaScript.

Я попытался выполнить следующий сценарий JavaScript в консоли разработчика Chrome и получил ошибку 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);
            }
        }
    }
});

1 Ответ

0 голосов
/ 09 сентября 2018

Короткий ответ

Проблема в том, что загрузка <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 , касающуюся загрузки скриптов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...