src/common/init.js 初始化处理
源码:
Js 代码
// file: src/common/init.js define("cordova/init", function(require, exports, module) { var channel = require('cordova/channel'); var cordova = require('cordova'); var modulemapper = require('cordova/modulemapper'); var platform = require('cordova/platform'); var pluginloader = require('cordova/pluginloader'); // 定义平台初期化处理必须在onNativeReady和onPluginsReady之后进行 var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady]; // 输出事件通道名到日志 function logUnfiredChannels(arr) { for (var i = 0; i < arr.length; ++i) { if (arr[i].state != 2) { console.log('Channel not fired: ' + arr[i].type); } } } // 5秒之后deviceready事件还没有被调用将输出log提示 // 出现这个错误的情况比较复杂,比如,加载的plugin太多等等 window.setTimeout(function() { if (channel.onDeviceReady.state != 2) { console.log('deviceready has not fired after 5 seconds.'); logUnfiredChannels(platformInitChannelsArray); logUnfiredChannels(channel.deviceReadyChannelsArray); } }, 5000); // 替换window.navigator function replaceNavigator(origNavigator) { // 定义新的navigator,把navigator的原型链赋给新的navigator的原型链 var CordovaNavigator = function() {}; CordovaNavigator.prototype = origNavigator; var newNavigator = new CordovaNavigator(); // 判断是否存在Function.bind函数 if (CordovaNavigator.bind) { for (var key in origNavigator) { if (typeof origNavigator[key] == 'function') { // 通过bind创建一个新的函数(this指向navigator)后赋给新的navigator // 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind newNavigator[key] = origNavigator[key].bind(origNavigator); } } } return newNavigator; } // 替换webview的BOM对象navigator // Cordova提供的接口基本都是:navigator.<plugin_name>.<action_name> if (window.navigator) { window.navigator = replaceNavigator(window.navigator); } // 定义console.log() if (!window.console) { window.console = { log: function(){} }; } // 定义console.warn() if (!window.console.warn) { window.console.warn = function(msg) { this.log("warn: " + msg); }; } // 注册pause,resume,deviceready事件通道,并应用到Cordova自定义的事件拦截 // 这样页面定义的事件监听器就能订阅到相应的通道上了。 channel.onPause = cordova.addDocumentEventHandler('pause'); channel.onResume = cordova.addDocumentEventHandler('resume'); channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); // 如果此时DOM加载完成,触发onDOMContentLoaded事件通道中的事件处理 if (document.readyState == 'complete' || document.readyState == 'interactive') { channel.onDOMContentLoaded.fire(); } else { // 如果此时DOM没有加载完成,定义一个监听器在DOM完成后触发事件通道的处理 // 注意这里调用的webview的原生事件监听 document.addEventListener('DOMContentLoaded', function() { channel.onDOMContentLoaded.fire(); }, false); } // 以前版本是在CordovaLib中反向执行js把_nativeReady设置成true后触发事件通道 // 现在已经改成在平台启动处理中立即触发 // 参考:https://issues.apache.org/jira/browse/CB-3066 if (window._nativeReady) { channel.onNativeReady.fire(); } // 给常用的模块起个别名 // 比如:就可以直接使用cordova.exec(...)来代替var exec = require('cordova/exec'); exec(...); // 不过第一行第二个参数应该是“Cordova”,c应该大写!!! modulemapper.clobbers('cordova', 'cordova'); modulemapper.clobbers('cordova/exec', 'cordova.exec'); modulemapper.clobbers('cordova/exec', 'Cordova.exec'); // 调用平台初始化启动处理 platform.bootstrap && platform.bootstrap(); // 所有插件加载完成后,触发onPluginsReady事件通道中的事件处理 pluginloader.load(function() { channel.onPluginsReady.fire(); }); // 一旦本地代码准备就绪,创建cordova所需的所有对象 channel.join(function() { // 把所有模块附加到window对象上 modulemapper.mapModules(window); // 如果平台有特殊的初始化处理,调用它(目前来看都没有) platform.initialize && platform.initialize(); // 触发onCordovaReady事件通道,标示cordova准备完成 channel.onCordovaReady.fire(); // 一切准备就绪后,执行deviceready事件通道上的所有事件。 channel.join(function() { require('cordova').fireDocumentEvent('deviceready'); }, channel.deviceReadyChannelsArray); // onCordovaReady、onDOMContentLoaded }, platformInitChannelsArray); // onNativeReady、onPluginsReady });