Викликати функцію 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.