以下のようなJavaScriptを介して動的にhtmlを追加しているhtmlページがあります
<script type="text/javascript" src="/myapp/htmlCode"></script>
ロードされたコンテンツ()などのjs関数を呼び出したい。上記のスクリプトがダイナミックHTMLを追加したら。
誰かが私がそれをどのように行うことができるか私を助けることができますか?
回答:
これは、head.jsjavascriptを使用せずに実現できます。
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!');
});
onload
スクリプト「LOADS」が実際に実行を終了したときではなく、すぐにコールバックを開始することに注意してください。これは残念です
onload
スクリプトが完成し、実行していない場合にはJavascriptがシングルスレッドであるため、ハンドラは、おそらく、呼び出すことができませんでした。つまり、onload
ハンドラーは、スクリプトが実行を開始する前、またはスクリプトが実行を終了した後にのみ呼び出すことができます。私は個人的に前者の事件が起こるのを見たことがありません...これまでに。onload
スクリプトの実行が開始される前にハンドラーを呼び出すことができる再現可能なケースについて誰かが知っている場合は、お知らせください。
function loadScripts (urls, callback) {var counter = 0 for (var i=0; i<urls.length; i++) { loadScript(urls[i], function () { if (++counter === urls.length) { callback() } }) } }
2020年にこの投稿を読んでいる場合は、おそらくPromisesに慣れているでしょう。すべてのターゲットブラウザがES6をサポートしている場合、またはポリフィルを使用している場合は、より最新のアプローチが推奨されます。
このソリューションは@JaykeshPatelの回答のように機能しますが、これはPromise
sに基づいています。
// 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;
script.onLoad = res;
//簡素化
return new Promise(res => script.onload = res)
ます。しかしに機能を割り当てることがonload
読みやすく、あなたが解決に引数を渡すことができますすることができ
このようなものを試してください
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);
私の答えは、JaykeshPatelの答えの拡張です。複数の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 );
onload
IEバージョン9以降でonload
は問題ありません。したがって、現在ほとんどの人にとって設定だけで問題ありません