同步加载外部JavaScript

时间:2019-05-20 14:51:33

标签: javascript html xmlhttprequest eval

我必须通过一些JavaScript 添加一个脚本标签,并且要使其完全执行,因为后面的语句会依赖它。

var logIt = (function() {
  var i = 0,
    logging = document.getElementById('logging');
  return function(s) {
    var heading = document.createElement('p');
    heading.innerText = `${++i}:  ${s}`;
    logging.appendChild(heading);
  }
}());

logIt('starting');
var newScriptTag = document.createElement('script');
newScriptTag.src = 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js';
newScriptTag.type = 'text/javascript';
document.head.appendChild(newScriptTag);
try {
  var now = moment().format('HH:mm');
  logIt(`moment loaded.  The time is ${now}`);
} catch (e) {
  logIt(`Moment not loaded: ${e}`);
}
<html>

<head>
  <title>Injecting Script Tags</title>
</head>

<body>
  <h1>Injecting Script Tags</h1>
  <div id="logging"></div>
</body>

</html>

如上面的代码片段所示,在插入标签之后,moment()在语句中不可用。

认为可以用eval(...)完成,但是这种选择并不受欢迎。

1 个答案:

答案 0 :(得分:1)

onload标签上使用<script>事件监听器:

const URL = 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js';

const onMomentReady = () => {
  console.log('Moment.js is loaded!');
  console.log(typeof moment);
}

var newScriptTag = document.createElement('script');
newScriptTag.onload = onMomentReady;
newScriptTag.src = URL;
// newScriptTag.type = 'text/javascript'; // no need for this

// optional
newScriptTag.async = true;
document.head.appendChild(newScriptTag);

请注意,在设置onload属性之前,我在 之前添加了src处理程序。如果先设置src,则处理程序功能可能不会触发