html多语言的方法,百度即可获得,这里不多说了。
iOS下,ajax不能用,可以看这个https://ask.dcloud.net.cn/article/36858。这个方法写在调用多语言之前即可。
下面关键点来了,按照上面方法配置完成。用苹果手机测试时,会报错:编码错误。查找论坛,发现需要在路径前面加上 file:// ,加过之后开始报其他错误:不允许读。经过多番尝试,好像是路径不对。于是我想起使用 plus.io.convertLocalFileSystemURL 来拼接全路径,经过测试,iOS也可以了。
但是还是有一个问题,plus.io.resolveLocalFileSystemURL是异步。国际化获取值需要想获取完数据才可以,于是我修改了一下jquery.i18n.properties.js文件。
$.i18n.properties = async function(settings) {
// set up settings
var defaults = {
name: 'Messages',
language: '',
path: '',
mode: 'vars',
cache: false,
encoding: 'UTF-8',
callback: null
};
settings = $.extend(defaults, settings);
if (settings.language === null || settings.language == '') {
settings.language = $.i18n.browserLang();
}
if (settings.language === null) {
settings.language = '';
}
// load and parse bundle files
var files = getFiles(settings.name);
for (i = 0; i < files.length; i++) {
await loadAndParseFile(settings.path + files[i] + '_' + settings.language + '.properties', settings);
// // 1. load base (eg, Messages.properties)
// loadAndParseFile(settings.path + files[i] + '.properties', settings);
// // 2. with language code (eg, Messages_pt.properties)
// if (settings.language.length >= 2) {
// loadAndParseFile(settings.path + files[i] + '_' + settings.language.substring(0, 2) + '.properties', settings);
// }
// // 3. with language code and country code (eg, Messages_pt_PT.properties)
// if (settings.language.length >= 5) {
// loadAndParseFile(settings.path + files[i] + '_' + settings.language.substring(0, 5) + '.properties', settings);
// }
}
// call callback
if (settings.callback) {
settings.callback();
}
};
使用async和await完成同步。
此外,为了是iOS和安卓一致,对my-xmlhttprequest.js文件也进行了修改。在fXMLHttpRequest_send方法中对路径进行优化
function fXMLHttpRequest_send(oRequest) {
oRequest.readyState = MyXmlHttpRequest.OPENED;
var path = "file://" + plus.io.convertLocalFileSystemURL(oRequest.url);
plus.io.resolveLocalFileSystemURL(path, function(entry) {
entry.file( function(file) {
var fileReader = new plus.io.FileReader();
fileReader.readAsText(file, 'utf-8');
fileReader.onloadend = function(evt) {
//console.log("evt.target.result: " + evt.target.result);
oRequest.readyState = 4;
var responseText = evt.target.result;
var parser = new DOMParser();
var responseXML = parser.parseFromString(responseText, 'text/xml');
//console.log('responseText: ' + responseText);
oRequest.fChangeValues(responseText, responseXML, 200, 'success');
if (oRequest.onload) {
console.log('xmlhttprequest callback onload');
oRequest.onload();
}
fReadyStateChange(oRequest);
}
});
}, function (e) {
console.log("Resolve file URL failed: " + e.message);
oRequest.readyState = 4;
oRequest.fChangeValues('', null, 404, 'error');
if (oRequest.onerror) {
console.log('xmlhttprequest callback onerror');
oRequest.onerror();
}
fReadyStateChange(oRequest);
});
}
这样问题就解决了。
下面附上改过的jquery.i18n.properties.js和my-xmlhttprequest.js文件
jquery.i18n.properties.js
(function() {
function MyXmlHttpRequest() {
this._listeners = [];
}
MyXmlHttpRequest.UNSENT = 0;
MyXmlHttpRequest.OPENED = 1;
MyXmlHttpRequest.HEADERS_RECEIVED = 2;
MyXmlHttpRequest.LOADING = 3;
MyXmlHttpRequest.DONE = 4;
// Interface level constants
MyXmlHttpRequest.prototype.UNSENT = MyXmlHttpRequest.UNSENT;
MyXmlHttpRequest.prototype.OPENED = MyXmlHttpRequest.OPENED;
MyXmlHttpRequest.prototype.HEADERS_RECEIVED = MyXmlHttpRequest.HEADERS_RECEIVED;
MyXmlHttpRequest.prototype.LOADING = MyXmlHttpRequest.LOADING;
MyXmlHttpRequest.prototype.DONE = MyXmlHttpRequest.DONE;
// Public Properties
MyXmlHttpRequest.prototype.readyState = MyXmlHttpRequest.UNSENT;
MyXmlHttpRequest.prototype.responseText = '';
MyXmlHttpRequest.prototype.responseXML = null;
MyXmlHttpRequest.prototype.status = 0;
MyXmlHttpRequest.prototype.statusText = '';
// Priority proposal
MyXmlHttpRequest.prototype.priority = "NORMAL";
MyXmlHttpRequest.prototype.method = '';
MyXmlHttpRequest.prototype.url = '';
MyXmlHttpRequest.prototype.async = true;
MyXmlHttpRequest.prototype.user = '';
MyXmlHttpRequest.prototype.password = '';
// Instance-level Events Handlers
MyXmlHttpRequest.prototype.onreadystatechange = null;
// Class-level Events Handlers
MyXmlHttpRequest.onreadystatechange = null;
MyXmlHttpRequest.onopen = null;
MyXmlHttpRequest.onsend = null;
MyXmlHttpRequest.onabort = null;
MyXmlHttpRequest.onload = null;
MyXmlHttpRequest.onerror = null;
// Public Methods
MyXmlHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
// http://www.w3.org/TR/XMLHttpRequest/#the-open-method
var sLowerCaseMethod = sMethod.toLowerCase();
if (sLowerCaseMethod == "connect" || sLowerCaseMethod == "trace" || sLowerCaseMethod == "track") {
throw new Error(18);
}
delete this._headers;
this.method = sMethod;
this.url = sUrl;
this.async = bAsync;
this.user = sUser;
this.password = sPassword;
if (MyXmlHttpRequest.onopen) {
MyXmlHttpRequest.onopen.apply(this, arguments);
}
this.readyState = MyXmlHttpRequest.OPENED;
fReadyStateChange(this);
};
MyXmlHttpRequest.prototype.send = function(vData) {
// Add method sniffer
if (MyXmlHttpRequest.onsend) {
MyXmlHttpRequest.onsend.apply(this, arguments);
}
if (!arguments.length) {
vData = null;
}
if (vData && vData.nodeType) {
vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
if (!this._headers["Content-Type"]) {
this.setRequestHeader("Content-Type", "application/xml");
}
}
this._data = vData;
fXMLHttpRequest_send(this);
};
MyXmlHttpRequest.prototype.abort = function() {
if (MyXmlHttpRequest.onabort) {
MyXmlHttpRequest.onabort.apply(this, arguments);
}
if (this.readyState > MyXmlHttpRequest.UNSENT) {
this._aborted = true;
}
fCleanTransport(this);
this.readyState = MyXmlHttpRequest.UNSENT;
delete this._data;
};
MyXmlHttpRequest.prototype.getAllResponseHeaders = function() {
return null;
};
MyXmlHttpRequest.prototype.getResponseHeader = function(sName) {
return null;
};
MyXmlHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
if (!this._headers) {
this._headers = {};
}
this._headers[sName] = sValue;
};
MyXmlHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
return;
}
}
// Add listener
this._listeners.push([sName, fHandler, bUseCapture]);
};
MyXmlHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
break;
}
}
// Remove listener
if (oListener) {
this._listeners.splice(nIndex, 1);
}
};
MyXmlHttpRequest.prototype.dispatchEvent = function(oEvent) {
var oEventPseudo = {
'type': oEvent.type,
'target': this,
'currentTarget': this,
'eventPhase': 2,
'bubbles': oEvent.bubbles,
'cancelable': oEvent.cancelable,
'timeStamp': oEvent.timeStamp,
'stopPropagation': function() {}, // There is no flow
'preventDefault': function() {}, // There is no default action
'initEvent': function() {} // Original event object should be initialized
};
// Execute onreadystatechange
if (oEventPseudo.type == "readystatechange" && this.onreadystatechange) {
(this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
}
// Execute listeners
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
if (oListener[0] == oEventPseudo.type && !oListener[2]) {
(oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
}
}
};
MyXmlHttpRequest.prototype.toString = function() {
return '[' + "object" + ' ' + "MyXmlHttpRequest" + ']';
};
MyXmlHttpRequest.toString = function() {
return '[' + "MyXmlHttpRequest" + ']';
};
MyXmlHttpRequest.prototype.fChangeValues = function(responseText, responseXML, status, statusText) {
this.responseText = responseText;
this.responseXML = responseXML;
this.status = status;
this.statusText = statusText;
}
// Helper function
function fXMLHttpRequest_send(oRequest) {
oRequest.readyState = MyXmlHttpRequest.OPENED;
var path = "file://" + plus.io.convertLocalFileSystemURL(oRequest.url);
console.log(path);
plus.io.resolveLocalFileSystemURL(path, function(entry) {
entry.file( function(file) {
var fileReader = new plus.io.FileReader();
fileReader.readAsText(file, 'utf-8');
fileReader.onloadend = function(evt) {
//console.log("evt.target.result: " + evt.target.result);
oRequest.readyState = 4;
var responseText = evt.target.result;
var parser = new DOMParser();
var responseXML = parser.parseFromString(responseText, 'text/xml');
//console.log('responseText: ' + responseText);
oRequest.fChangeValues(responseText, responseXML, 200, 'success');
if (oRequest.onload) {
console.log('xmlhttprequest callback onload');
oRequest.onload();
}
fReadyStateChange(oRequest);
}
});
}, function (e) {
console.log("Resolve file URL failed: " + e.message);
oRequest.readyState = 4;
oRequest.fChangeValues('', null, 404, 'error');
if (oRequest.onerror) {
console.log('xmlhttprequest callback onerror');
oRequest.onerror();
}
fReadyStateChange(oRequest);
});
}
function fReadyStateChange(oRequest) {
// Sniffing code
if (MyXmlHttpRequest.onreadystatechange){
MyXmlHttpRequest.onreadystatechange.apply(oRequest);
}
// Fake event
oRequest.dispatchEvent({
'type': "readystatechange",
'bubbles': false,
'cancelable': false,
'timeStamp': new Date().getTime()
});
}
function fCleanTransport(oRequest) {
//
}
if (!window.Function.prototype.apply) {
window.Function.prototype.apply = function(oRequest, oArguments) {
if (!oArguments) {
oArguments = [];
}
oRequest.__func = this;
oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
delete oRequest.__func;
};
}
window.MyXmlHttpRequest = MyXmlHttpRequest;
})();
my-xmlhttprequest.js
(function() {
function MyXmlHttpRequest() {
this._listeners = [];
}
MyXmlHttpRequest.UNSENT = 0;
MyXmlHttpRequest.OPENED = 1;
MyXmlHttpRequest.HEADERS_RECEIVED = 2;
MyXmlHttpRequest.LOADING = 3;
MyXmlHttpRequest.DONE = 4;
// Interface level constants
MyXmlHttpRequest.prototype.UNSENT = MyXmlHttpRequest.UNSENT;
MyXmlHttpRequest.prototype.OPENED = MyXmlHttpRequest.OPENED;
MyXmlHttpRequest.prototype.HEADERS_RECEIVED = MyXmlHttpRequest.HEADERS_RECEIVED;
MyXmlHttpRequest.prototype.LOADING = MyXmlHttpRequest.LOADING;
MyXmlHttpRequest.prototype.DONE = MyXmlHttpRequest.DONE;
// Public Properties
MyXmlHttpRequest.prototype.readyState = MyXmlHttpRequest.UNSENT;
MyXmlHttpRequest.prototype.responseText = '';
MyXmlHttpRequest.prototype.responseXML = null;
MyXmlHttpRequest.prototype.status = 0;
MyXmlHttpRequest.prototype.statusText = '';
// Priority proposal
MyXmlHttpRequest.prototype.priority = "NORMAL";
MyXmlHttpRequest.prototype.method = '';
MyXmlHttpRequest.prototype.url = '';
MyXmlHttpRequest.prototype.async = true;
MyXmlHttpRequest.prototype.user = '';
MyXmlHttpRequest.prototype.password = '';
// Instance-level Events Handlers
MyXmlHttpRequest.prototype.onreadystatechange = null;
// Class-level Events Handlers
MyXmlHttpRequest.onreadystatechange = null;
MyXmlHttpRequest.onopen = null;
MyXmlHttpRequest.onsend = null;
MyXmlHttpRequest.onabort = null;
MyXmlHttpRequest.onload = null;
MyXmlHttpRequest.onerror = null;
// Public Methods
MyXmlHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
// http://www.w3.org/TR/XMLHttpRequest/#the-open-method
var sLowerCaseMethod = sMethod.toLowerCase();
if (sLowerCaseMethod == "connect" || sLowerCaseMethod == "trace" || sLowerCaseMethod == "track") {
throw new Error(18);
}
delete this._headers;
this.method = sMethod;
this.url = sUrl;
this.async = bAsync;
this.user = sUser;
this.password = sPassword;
if (MyXmlHttpRequest.onopen) {
MyXmlHttpRequest.onopen.apply(this, arguments);
}
this.readyState = MyXmlHttpRequest.OPENED;
fReadyStateChange(this);
};
MyXmlHttpRequest.prototype.send = function(vData) {
// Add method sniffer
if (MyXmlHttpRequest.onsend) {
MyXmlHttpRequest.onsend.apply(this, arguments);
}
if (!arguments.length) {
vData = null;
}
if (vData && vData.nodeType) {
vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
if (!this._headers["Content-Type"]) {
this.setRequestHeader("Content-Type", "application/xml");
}
}
this._data = vData;
fXMLHttpRequest_send(this);
};
MyXmlHttpRequest.prototype.abort = function() {
if (MyXmlHttpRequest.onabort) {
MyXmlHttpRequest.onabort.apply(this, arguments);
}
if (this.readyState > MyXmlHttpRequest.UNSENT) {
this._aborted = true;
}
fCleanTransport(this);
this.readyState = MyXmlHttpRequest.UNSENT;
delete this._data;
};
MyXmlHttpRequest.prototype.getAllResponseHeaders = function() {
return null;
};
MyXmlHttpRequest.prototype.getResponseHeader = function(sName) {
return null;
};
MyXmlHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
if (!this._headers) {
this._headers = {};
}
this._headers[sName] = sValue;
};
MyXmlHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
return;
}
}
// Add listener
this._listeners.push([sName, fHandler, bUseCapture]);
};
MyXmlHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
break;
}
}
// Remove listener
if (oListener) {
this._listeners.splice(nIndex, 1);
}
};
MyXmlHttpRequest.prototype.dispatchEvent = function(oEvent) {
var oEventPseudo = {
'type': oEvent.type,
'target': this,
'currentTarget': this,
'eventPhase': 2,
'bubbles': oEvent.bubbles,
'cancelable': oEvent.cancelable,
'timeStamp': oEvent.timeStamp,
'stopPropagation': function() {}, // There is no flow
'preventDefault': function() {}, // There is no default action
'initEvent': function() {} // Original event object should be initialized
};
// Execute onreadystatechange
if (oEventPseudo.type == "readystatechange" && this.onreadystatechange) {
(this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
}
// Execute listeners
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
if (oListener[0] == oEventPseudo.type && !oListener[2]) {
(oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
}
}
};
MyXmlHttpRequest.prototype.toString = function() {
return '[' + "object" + ' ' + "MyXmlHttpRequest" + ']';
};
MyXmlHttpRequest.toString = function() {
return '[' + "MyXmlHttpRequest" + ']';
};
MyXmlHttpRequest.prototype.fChangeValues = function(responseText, responseXML, status, statusText) {
this.responseText = responseText;
this.responseXML = responseXML;
this.status = status;
this.statusText = statusText;
}
// Helper function
function fXMLHttpRequest_send(oRequest) {
oRequest.readyState = MyXmlHttpRequest.OPENED;
var path = "file://" + plus.io.convertLocalFileSystemURL(oRequest.url);
console.log(path);
plus.io.resolveLocalFileSystemURL(path, function(entry) {
entry.file( function(file) {
var fileReader = new plus.io.FileReader();
fileReader.readAsText(file, 'utf-8');
fileReader.onloadend = function(evt) {
//console.log("evt.target.result: " + evt.target.result);
oRequest.readyState = 4;
var responseText = evt.target.result;
var parser = new DOMParser();
var responseXML = parser.parseFromString(responseText, 'text/xml');
//console.log('responseText: ' + responseText);
oRequest.fChangeValues(responseText, responseXML, 200, 'success');
if (oRequest.onload) {
console.log('xmlhttprequest callback onload');
oRequest.onload();
}
fReadyStateChange(oRequest);
}
});
}, function (e) {
console.log("Resolve file URL failed: " + e.message);
oRequest.readyState = 4;
oRequest.fChangeValues('', null, 404, 'error');
if (oRequest.onerror) {
console.log('xmlhttprequest callback onerror');
oRequest.onerror();
}
fReadyStateChange(oRequest);
});
}
function fReadyStateChange(oRequest) {
// Sniffing code
if (MyXmlHttpRequest.onreadystatechange){
MyXmlHttpRequest.onreadystatechange.apply(oRequest);
}
// Fake event
oRequest.dispatchEvent({
'type': "readystatechange",
'bubbles': false,
'cancelable': false,
'timeStamp': new Date().getTime()
});
}
function fCleanTransport(oRequest) {
//
}
if (!window.Function.prototype.apply) {
window.Function.prototype.apply = function(oRequest, oArguments) {
if (!oArguments) {
oArguments = [];
}
oRequest.__func = this;
oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
delete oRequest.__func;
};
}
window.MyXmlHttpRequest = MyXmlHttpRequest;
})();