我是一名JavaScript新手,通过研究计算数学函数的纯 JavaScript“项目”来学习。这一切都运作良好。现在,作为进一步的步骤,我想使消息多语言。代码应该能够在运行时加载适当的语言文件。对于动态加载问题,我在this one等网页上阅读并找到了解决方案。
在编写动态代码之前,我静态加载它,测试代码运行良好。我要求帮助的代码只是加载“脚本”元素的细微差别。
我遇到问题的代码是 this.getString 函数,在该函数中无法访问语言文件中的 de 元素。在行 console.log(eval(language,tag)); ,我收到错误消息“ Uncaught ReferenceError:de is not defined ”。
//File: Utils/Lang/js/FileUtils.js
function Language(language) {
var __construct = function(dynamicLoad) {
if (typeof language == 'undefined') {
language = "en";
}
// Load the proper language file:
loadFile("js/resources/lang.de.js");
return;
} ()
this.getString = function(tag, strDefault) {
console.log("getString(" + tag + ", " + strDefault + "): ");
console.log("getString(...): document = " + document);
console.log("getString(...): eval(" + language + ", " + tag + ") = ");
console.log(eval(language, tag));
var strReturn = eval('eval(language).' + tag);
if (typeof strReturn != 'undefined') {
return strReturn;
} else {
return (typeof strDefault != 'undefined')
? strDefault
: eval('en.' + tag);
}
}
}
不包括有效的静态测试代码,我可以访问de元素。
我的问题:如何正确加载语言文件以便可以访问 de 标记?
感谢您的帮助!
//File: Utils/Files/js/FileUtils.js
function loadFile(filepathname) {
var reference = document.createElement('script');
reference.setAttribute("type", "text/javascript");
reference.setAttribute("src", filepathname);
if (typeof reference != 'undefined') {
document.getElementsByTagName("head")[0].appendChild(reference);
}
console.log("loadFile(\"" + filepathname + "\"): document = " + document);
}
//File: Utils/Lang/js/resources/lang.de.js:
de = {
pleaseWait: "Bitte warten..."
};
//File: Utils/Lang/js/resources/lang.en.js
en = {
pleaseWait: "Please wait..."
};
//File: Utils/Lang/js/TestLanguage.js:
function output() {
console.log("output()");
var codes = ['de', 'en'];
for (var i = 0; i < codes.length; i++) {
var translator = new Language(codes[i]);
var message = "output(): in " + translator.getLanguage() + ": ";
message += translator.getString('pleaseWait');
console.log(message);
}
}
<!--File: Utils/Lang/TestLang.html:-->
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Test languages</title>
<script type="text/javascript" src="../Files/js/FileUtils.js"></script>
<script type="text/javascript" src="js/Language.js"></script>
<script type="text/javascript" src="js/TestLanguage.js"></script>
</head>
<body>
<button name="outputButton" onclick="output();">Click</button>
<br>Please press [F12] so that you can see the test results.
</body>
</html>
答案 0 :(得分:3)
将脚本标记添加到文档时,不会同步加载它。您需要等待文件加载后才能使用其中的代码。
您可以重新设计代码以使用script.onload回调:
var reference = document.createElement('script');
// ...
reference.onload = function() {
alert("Script loaded and ready");
};
但是对于这种情况,如果你没有很多语言字符串,你可能最好只是静态加载它们。
答案 1 :(得分:0)
如何动态加载脚本文件(最基本的版本,还有多个选项):
function loadScriptFile(scriptPath, jsFile, callBack)
{
var scriptTag = document.createElement("script"); //creates a HTML script element
scriptTag.language = "JavaScript"; //sets the language attribute
scriptTag.type = "text/javascript";
scriptTag.src = scriptPath + jsFile + ".js"; //the source
if (callBack)
{
scriptTag.onload = callback; //when loaded execute call back
}
var scriptTagParent = document.getElementsByTagName("script")[0];
if (scriptTagParent)
{
scriptTagParent.parentNode.insertBefore(scriptTag, scriptTagParent);
}
else
{
document.body.appendChild(scriptTag);
}
}
工作原理:
运行loadScriptFile("scripts", "math", startProgram)
。前两个参数将指向您的文件和文件夹。最后一个参数是回调函数。定义后,一旦脚本标记完成加载并且脚本在全局范围内可用,将执行此操作。该脚本将动态添加到您的页面。如果页面上存在脚本元素,则会在此之前添加该脚本元素(以使标记保持良好)。如果不是它将被附加到身体。 (这只是视觉上的)。
回调部分是最有趣的。由于您的脚本现在将是 asynchronical
,因此您需要使用回调来告诉程序已加载必要的文件。加载脚本文件时会触发此回调,因此您不会收到脚本错误。
只是我在评论中的意思的基本示例:
这不是你问题的答案,它是一种替代方式(我认为管理更好)。纯Javascript(借助XML)
XML-file:language.xml 基本XML结构:
<language>
<l1033 name="english" tag="en-US">
<id1000>
<![CDATA[
Hello World!
]]>
</id1000>
</l1033>
<l1031 name="german" tag="de-DE">
<id1000>
<![CDATA[
Hallo Welt!
]]>
</id1000>
</l1031>
</language>
我做了什么:
我构造了一个名为language的根元素。在其中写了两个语言字符串,英语为l1033
,德语为l1031
。请注意,在语言代码之前添加了一个字母。当标记以数字开头时,XML将抛出错误。 CDATA
块用于防止特殊字符出现任何问题。
现在加载将由AJAX完成:
var xmlLoader = new XMLHttpRequest();
xmlLoader.onreadystatechange = trackRequest; //event to track the request, with call back
xmlLoader.open("get", "language.xml", true); //set asynchronous to true
xmlLoader.send(null);
function trackRequest()
{
if (this.status == 200 && this.readyState == 4) //all is good
{
globalLanguageFile = this.responseXML;
startProgram(); //fictive function that starts your program
}
}
现在加载了XML。如何从中加载字符串?
function loadLanguageString(code, id, fallback)
{
var word = fallback;
if (globalLanguageFile.getElementsByTagName("l"+code).length > 0)
{
if (globalLanguageFile.getElementsByTagName("l"+code).[0].getElementsByTagName("id"+id).length > 0)
{
//found the correct language tag and id tag. Now retrieve the content with textContent.
word = globalLanguageFile.getElementsByTagName("l"+code).[0].getElementsByTagName("id"+id)[0].textContent;
}
}
return word; //when failed return fall back string
}
如何调用该函数:
loadLanguageString(1031, 1000, "Hello World!");
答案 2 :(得分:0)
我使用GarethOwen的信息找到了我的问题的正确答案。以下是我必须做的代码修改:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Test languages</title>
<script type="text/javascript" src="../Arrays/js/ArrayUtils.js"></script>
<script type="text/javascript" src="../Files/js/FileUtils.js"></script>
<script type="text/javascript" src="../Logic/js/LogicalUtils.js"></script>
<script type="text/javascript" src="js/LanguageUtils.js"></script>
<script type="text/javascript" src="js/TestLanguageUtils.js"></script>
</head>
<!-- body onload="load(null, '../Maths/js/resources')" -->
<body onload="load();">
<button onclick="output();">Click</button><br>
Please press [F12] so that you can see the test results.
</body>
</html>
TestLanguage.html :增强了正文标记
<body onload="load()">
TestLanguage.js : 2A。现在添加了HTML页面请求的 load()函数:
var gCodes = ['de', 'en', 'tr'];
function load() {
console.log("load()");
for (var i = 0; i < codes.length; i++) {
new Language(codes[i]);
}
}
2B。在输出()函数中使用全局 gCodes 变量
Language.js :为了更好地测试整体,我通过更改函数语言中构造函数中的行,使函数语言中的代码更加精细一些(语言) to:
// Load the proper language file:
if (eval("gLoaded.indexOf('" + language + "') < 0")) {
loadFile("js/resources/lang." + language + ".js");
gLoaded[gLoaded.length] = language;
}
感谢您的支持! : - )
//Lang/js/Lang.js:
"use strict";
/**
* Object for multilingual message handling.
*
* @param language
*/
function Language(language) {
var __construct = function(dynamicLoad) {
if (typeof language == 'undefined') {
language = "en";
}
// Load the proper language file:
switch (language) {
case "de":
loadFile("js/resources/lang.de.js");
break;
case "tr":
loadFile("js/resources/lang.tr.js");
break;
default:
loadFile("js/resources/lang.en.js");
}
return;
}()
/**
* Returns the language of that object.
*
* @returns The language
*/
this.getLanguage = function() {
var strLanguage;
switch (language) {
case "de":
strLanguage = "German";
break;
case "tr":
strLanguage = "Turkish";
break;
default:
strLanguage = "English";
}
return strLanguage;
}
/**
* Returns the language code of that object.
*
* @returns The language code
*/
this.getString = function(tag, strDefault) {
var strReturn = eval('eval(language).' + tag);
if (typeof strReturn != 'undefined') {
return strReturn;
} else {
return (typeof strDefault != 'undefined') ? strDefault : eval('en.' + tag);
}
}
}
//Lang/js/TestLang.js:
"use strict";
var gCodes = ['de', 'en', 'tr'];
function load() {
console.log("load()");
for (var i = 0; i < gCodes.length; i++) {
new Language(gCodes[i]);
}
}
/**
* Object for multilingual message handling.
*
* @param language
*/
function output() {
console.log("output()");
for (var i = 0; i < gCodes.length; i++) {
var translator = new Language(gCodes[i]);
var message = "output(): in " + translator.getLanguage() + ": ";
message += translator.getString('pleaseWait');
console.log(message);
}
}
//Utils/Files/js/FileUtils.js:
"use strict";
/**
* Object with file utilities
*
* @param filepathname
*/
function loadFile(filepathname) {
var methodName = "loadFile(" + filepathname + "): "
var reference = document.createElement('script');
reference.setAttribute("type", "text/javascript");
reference.setAttribute("src", filepathname);
if (typeof reference != 'undefined') {
document.getElementsByTagName("head")[0].appendChild(reference);
}
reference.onload = function() {
console.log(methodName + "onload(): Language script loaded and ready!");
}
}
这是控制台输出:
Here is the output:
load()
loadFile(js/resources/lang.de.js): onload(): Language script loaded and ready!
loadFile(js/resources/lang.en.js): onload(): Language script loaded and ready!
loadFile(js/resources/lang.tr.js): onload(): Language script loaded and ready!
output()
output(): in German: Bitte warten...
output(): in English: Please wait...
output(): in Turkish: Lütfen bekleyiniz...
loadFile(js/resources/lang.de.js): onload(): Language script loaded and ready!
loadFile(js/resources/lang.en.js): onload(): Language script loaded and ready!
loadFile(js/resources/lang.tr.js): onload(): Language script loaded and ready!