66 lines
1.6 KiB
JavaScript
66 lines
1.6 KiB
JavaScript
|
|
module.exports = function load (src, opts, cb) {
|
|
var head = document.head || document.getElementsByTagName('head')[0]
|
|
var script = document.createElement('script')
|
|
|
|
if (typeof opts === 'function') {
|
|
cb = opts
|
|
opts = {}
|
|
}
|
|
|
|
opts = opts || {}
|
|
cb = cb || function() {}
|
|
|
|
script.type = opts.type || 'text/javascript'
|
|
script.charset = opts.charset || 'utf8';
|
|
script.async = 'async' in opts ? !!opts.async : true
|
|
script.src = src
|
|
|
|
if (opts.attrs) {
|
|
setAttributes(script, opts.attrs)
|
|
}
|
|
|
|
if (opts.text) {
|
|
script.text = '' + opts.text
|
|
}
|
|
|
|
var onend = 'onload' in script ? stdOnEnd : ieOnEnd
|
|
onend(script, cb)
|
|
|
|
// some good legacy browsers (firefox) fail the 'in' detection above
|
|
// so as a fallback we always set onload
|
|
// old IE will ignore this and new IE will set onload
|
|
if (!script.onload) {
|
|
stdOnEnd(script, cb);
|
|
}
|
|
|
|
head.appendChild(script)
|
|
}
|
|
|
|
function setAttributes(script, attrs) {
|
|
for (var attr in attrs) {
|
|
script.setAttribute(attr, attrs[attr]);
|
|
}
|
|
}
|
|
|
|
function stdOnEnd (script, cb) {
|
|
script.onload = function () {
|
|
this.onerror = this.onload = null
|
|
cb(null, script)
|
|
}
|
|
script.onerror = function () {
|
|
// this.onload = null here is necessary
|
|
// because even IE9 works not like others
|
|
this.onerror = this.onload = null
|
|
cb(new Error('Failed to load ' + this.src), script)
|
|
}
|
|
}
|
|
|
|
function ieOnEnd (script, cb) {
|
|
script.onreadystatechange = function () {
|
|
if (this.readyState != 'complete' && this.readyState != 'loaded') return
|
|
this.onreadystatechange = null
|
|
cb(null, script) // there is no way to catch loading errors in IE8
|
|
}
|
|
}
|