在Web开发中,动态加载JavaScript脚本是一种常见的需求,尤其是在需要按需加载脚本以提高页面加载性能时。
function loadScript(url, callback) {
    var script = document.createElement('script');
    var loaded = false;
    
    // 加载成功处理
    function onLoad() {
        if (!loaded) {
            loaded = true;
            // 延迟执行确保脚本已解析
            setTimeout(function() {
                callback(null, script);
            }, 0);
        }
    }
    
    // 错误处理
    function onError(err) {
        if (!loaded) {
            loaded = true;
            callback(err || new Error('Failed to load script: ' + url), script);
        }
    }
    
    // 现代浏览器
    script.onload = onLoad;
    script.onerror = onError;
    
    // IE8及以下兼容
    if (script.readyState) {
        script.onreadystatechange = function() {
            if (script.readyState === 'loaded' || script.readyState === 'complete') {
                script.onreadystatechange = null;
                onLoad();
            }
        };
    }
    
    script.src = url;
    script.async = true;
    
    // 添加到文档
    document.body.appendChild(script);
    
    // 返回script元素以便后续操作
    return script;
}参数:
url: 要加载的脚本URL
callback: 脚本加载完成后的回调函数
工作原理:
创建script元素
根据浏览器兼容性设置加载完成事件监听
设置script的src属性
将script添加到body中开始加载
1. 动态加载第三方库
loadScript('https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js', function(err) {
    if (err) {
        console.error('加载失败:', err);
        return;
    }
    console.log('Lodash加载完成');
    // 使用加载的库
    console.log(_.VERSION);
});2. 按需加载模块
function loadComponent(componentName, callback) {
    loadScript('/js/components/' + componentName + '.js', function(err) {
        if (err) {
            console.error('组件加载失败:', componentName, err);
            return;
        }
        console.log('组件加载成功:', componentName);
        callback();
    });
}3. 依赖加载
// 顺序加载多个脚本
function loadDependencies(deps, finalCallback) {
    var loadedCount = 0;
    
    function loadNext() {
        if (loadedCount >= deps.length) {
            finalCallback();
            return;
        }
        
        loadScript(deps[loadedCount], function(err) {
            if (err) {
                console.error('依赖加载失败:', deps[loadedCount], err);
                return;
            }
            loadedCount++;
            loadNext();
        });
    }
    
    loadNext();
}
// 使用
loadDependencies([
    'https://code.jquery.com/jquery-3.6.0.min.js',
    'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js'
], function() {
    console.log('所有依赖加载完成');
    // 初始化应用
});4. 条件加载
// 根据条件动态加载脚本
function loadPolyfill(feature, polyfillUrl, callback) {
    if (feature in window) {
        callback(); // 特性已支持,无需加载
        return;
    }
    
    loadScript(polyfillUrl, function(err) {
        if (err) {
            console.error('Polyfill加载失败:', err);
            return;
        }
        console.log('Polyfill加载成功');
        callback();
    });
}
// 使用
loadPolyfill('Promise', '/js/polyfills/promise.js', function() {
    // 现在可以安全使用Promise
    new Promise(function(resolve) {
        setTimeout(resolve, 1000);
    });
});对于现代项目,可以考虑:
ES6 Modules (import())
webpack 动态导入
RequireJS (AMD)
SystemJS
这个loadScript函数在需要兼容老浏览器或简单动态加载场景下仍然很有用。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!