Викликати функцію javascript після завантаження скрипта


82

У мене є сторінка html, де я динамічно додаю html за допомогою JavaScript, як показано нижче

<script type="text/javascript" src="/myapp/htmlCode"></script>

Я хочу викликати функцію js, наприклад, loadedContent (); як тільки вищезазначений сценарій додає динамічний html.

Хтось може мені допомогти, як я можу це зробити?

Відповіді:


141

ви можете досягти цього, не використовуючи head.js javascript.

function loadScript( url, callback ) {
  var script = document.createElement( "script" )
  script.type = "text/javascript";
  if(script.readyState) {  // only required for IE <9
    script.onreadystatechange = function() {
      if ( script.readyState === "loaded" || script.readyState === "complete" ) {
        script.onreadystatechange = null;
        callback();
      }
    };
  } else {  //Others
    script.onload = function() {
      callback();
    };
  }

  script.src = url;
  document.getElementsByTagName( "head" )[0].appendChild( script );
}


// call the function...
loadScript(pathtoscript, function() {
  alert('script ready!'); 
});

6
FYI: onloadце нормально для IE версій 9 і пізніших версій - так що просто налаштування onload, мабуть, нормально для більшості людей
— Simon_Weaver

3
Примітка onloadпочне зворотний виклик щохвилини, коли скрипт "ЗАГРУЗИТЬ", а не коли його фактично завершиться виконання, що невтішно
— Ма Чувак

@MaDude Чи можете ви посилатися на будь-яку документацію щодо цього?
— kontrollanten

2
onloadОброблювач не міг бути викликаний , коли сценарій ще не закінчив виконання, так як Javascript однопоточен. Це означає, що onloadобробник можна викликати лише ДО запуску сценарію або ПІСЛЯ завершення виконання. Я особисто ніколи не бачив, щоб колишній випадок стався ... КОЛИсь. Якщо хтось знає про відтворюваний випадок, коли onloadобробник може бути викликаний ДО того, як скрипт почне виконуватися, повідомте нам.
— GetFree

Просте розширення для завантаження масиву сценаріїв: function loadScripts (urls, callback) {var counter = 0 for (var i=0; i<urls.length; i++) { loadScript(urls[i], function () { if (++counter === urls.length) { callback() } }) } }
— sree

28

У мене була та ж проблема ... Моє рішення (без jQuery):

<script onload="loadedContent();" src ="/myapp/myCode.js"  ></script>

2
Зверніть увагу: це не буде сумісним із суворими CSP.
— Бредлі

14

Якщо ви читаєте цю публікацію в 2020 році, можливо, ви більше звикли до обіцянок. Більш сучасний підхід є кращим, якщо або всі цільові браузери підтримують ES6, або ви використовуєте поліфіл.

Це рішення працює як відповідь @JaykeshPatel , але воно базується на Promises:

// definition
function loadScript(scriptUrl) {
  const script = document.createElement('script');
  script.src = scriptUrl;
  document.body.appendChild(script);
  
  return new Promise((res, rej) => {
    script.onload = function() {
      res();
    }
    script.onerror = function () {
      rej();
    }
  });
}

// use
loadScript('http://your-cdn/jquery.js')
  .then(() => {
    console.log('Script loaded!');
  })
  .catch(() => {
    console.error('Script loading failed! Handle this error');
  });

Ви можете передавати деякі контекстуальні змінні в аргументи resзворотного виклику, або якщо ваша бібліотека імпортувала якийсь глобальний символ, ви можете посилатися на нього там.

Наприклад, оскільки jQuery вводить $глобальний символ, ви можете викликати res($)та створити для нього локальну область (ідеально, якщо ви використовуєте TypeScript і не хочете оголошувати змінну модуля у кожному файлі, таким чином ви можете писати const $ = await loadScript(..)).

Якщо ви не хочете передавати будь-який аргумент, ви можете просто скоротити свій код так:

script.onload = res;
script.onerror = rej;

1
script.onLoad = res;// спрощення
— Кунукн,

1
@Kunukn також є коротший return new Promise(res => script.onload = res). Але присвоєння функції onloadпростішому для читання і дозволяє передавати аргумент щодо вирішення
— Крістіан Трайна

12

спробуйте щось подібне

var script = document.createElement('script');

if(script.readyState) {  //IE
script.onreadystatechange = function() {
  if ( script.readyState === "loaded" || script.readyState === "complete" ) {
    script.onreadystatechange = null;
    alert(jQuery);
  }
};
 } else{//others
script.onload = function() {
  alert(jQuery); 
}
}
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"
document.documentElement.appendChild(script);

4

насправді ви можете просто поставити loadedContent()як останній рядок сценарію, який ви завантажуєте (це свого роду концепція JSONP)


4

Моя відповідь - продовження відповіді Джейкеша Пателя . Я застосував цей код для того, щоб завантажити кілька javascript . Сподіваюся, це комусь допомагає:

// RECURSIVE LOAD SCRIPTS
function load_scripts( urls, final_callback, index=0 )
{
    if( typeof urls[index+1] === "undefined" )
    {
        load_script( urls[index], final_callback );
    }
    else
    {
        load_script( urls[index], function() {
            load_scripts( urls, final_callback, index+1 );
        } );
    }
}

// LOAD SCRIPT
function load_script( url, callback )
{
    var script = document.createElement( "script" );
    script.type = "text/javascript";
    if(script.readyState) // IE
    {
        script.onreadystatechange = function()
        {
            if ( script.readyState === "loaded" || script.readyState === "complete" )
            {
                script.onreadystatechange = null;
                callback();
            }
        };
    }
    else // Others
    {  
        script.onload = function() { callback(); };
    }
    script.src = url;
    document.getElementsByTagName( "head" )[0].appendChild( script );
    debug("javascript included: "+url);
}

// EXAMPLE  
var main = function()
{
    console.log("main function executed");
}
var js = [ "path/to/script-1", "path/to/script-2", "path/to/script-3" ];
load_scripts( js, main );

1

Перевірте head.js . Він досягне того, що вам потрібно, забезпечуючи зворотні виклики, коли ваші файли успішно завантажуються та виконуються.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.