从HTML头读取JSON文件,没有服务器



我得到了一些翻译的json文件。我想在JS文件中使用这个文件来翻译一些字符串。但是我没有一个好的解决方案来加载这个文件和数据。

到目前为止,我得到的是在我的HTML文件:

<script type='application/json' src='lang/translations.json'></script>
<script src="Javascript/translator.js" charset="UTF-8"></script>

JSON文件:

{
"language": {
"en": {
"closure": "Closure",
"documents": "Documents",
"overview": "Overview"
},
"de": {
"closure": "Abschluss",
"documents": "Dokumente",
"overview": "Übersicht"
}
}
}

和我的JS文件:

let docLanguage = document.documentElement.lang;
let browserLanguage = navigator.language.substr(0, 2);
let lang = docLanguage ? docLanguage : browserLanguage;
let texts;
const Http = new XMLHttpRequest();
const url = "lang/" + lang + ".json";
Http.open("GET", url, false);
Http.send();
Http.onreadystatechange = function () {
texts = JSON.parse(Http.responseText);
return texts;
}
let getJson = jQuery.getJSON('lang/' + lang + '.json', {format: "json", async: false})
.done(function (data) {
// texts = data;
return data;
}).fail(function () {
console.log('empty');
});
class translator {
constructor(lang) {
this.lang = lang;
this.translations = texts;
}
_(keyName) {
// return texts.get(keyName);
//  todo get by keyName
}
transHtml(attribute = 'data-lang') {
let htmlElements = document.querySelectorAll('[' + attribute + ']');
for (let htmlElement of htmlElements) {
let keyName = htmlElement.getAttribute(attribute);
htmlElement.textContent = this._(keyName);
}
}
}
var translate = new translator(lang);

但问题是,翻译文件读到晚,在构造函数中我不能使用这部分,或者我做错了什么?

加载和读取存储在本地的json文件的最好方法是什么呢?

我不想要服务器或其他任何东西,只有纯Javascript可以在所有现代浏览器上运行。因为这是一个为用户设置的导出功能,他们应该能够观看这个页面,而不需要安装任何东西或需要互联网连接

如果你想坚持同步XHTTPRequest(不推荐),那么你只需要改变send()函数的顺序,如果您在附加onreadystatechange事件侦听器之前调用它,则必须在

之后调用它:
Http.open("GET", url, false);
Http.onreadystatechange = function () {
texts = JSON.parse(Http.responseText);
return texts;
}
Http.send(); // called after onreadystatechange

它将工作,但显示警告控制台[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.

建议在JavaScript中使用异步函数。异步构造函数不能工作,所以有一些模式可以帮助解决这个问题:https://stackoverflow.com/a/43433773/3075373

例如,最好这样使用.init()函数:

let docLanguage = document.documentElement.lang;
let browserLanguage = navigator.language.substr(0, 2);
let lang = docLanguage ? docLanguage : browserLanguage;
class translator {
constructor(lang) {
this.lang = lang;
}
init(cb) {
jQuery.getJSON('lang/' + this.lang + '.json', { format: "json" })
.done(result => {
this.translations = result;
cb.bind(this)();
})
.fail(err => console.log(err))
}
_(keyName) {
// return texts.get(keyName);
//  todo get by keyName
}
transHtml(attribute = 'data-lang') {
let htmlElements = document.querySelectorAll('[' + attribute + ']');

for (let htmlElement of htmlElements) {
let keyName = htmlElement.getAttribute(attribute);
htmlElement.textContent = this._(keyName);
}
}
}
var translate = new translator(lang);
translate.init(() => {
// inside you can use methods that rely on translations being loaded e.g:
translate.transHtml();
})

@回复评论:

可以添加例如另一个文件languages.js

const languages = {
"language": {
"en": {
"closure": "Closure",
"documents": "Documents",
"overview": "Overview"
},
"de": {
"closure": "Abschluss",
"documents": "Dokumente",
"overview": "Übersicht"
}
}
}
export default languages;

,然后在你的主脚本中添加type="module",这样你就可以导入另一个js文件(注意:它将主要在现代浏览器中工作,通常它是在webpack的帮助下完成的)等等,以帮助旧的浏览器,但这完全是另一个话题)

<script type="module">
import lngs from './languages.js'
let docLanguage = document.documentElement.lang;
...
...
...
rest of script

你也可以简单地粘贴languages对象在顶部到你的主脚本,然后就不需要导入另一个js文件。