【问题标题】:Cannot read property 'replace' of undefined in json无法读取 json 中未定义的属性“替换”
【发布时间】:2015-04-04 12:05:27
【问题描述】:

我使用此代码在线获取我的 json 文件并将其转换为网站文本(翻译文件)。

browser = {
    i18n: {
        getMessage: function(e, t) {
            var n;
            if (typeof browser.i18n.strings === "undefined") {
                var r = [navigator.language.replace("-", "_")];
                if (navigator.language.length > 2) {
                    r.push(navigator.language.substring(0, 2))
                }
                if (navigator.language !== "en") {
                    r.push("en")
                }
                browser.i18n.strings = {};
                var i = function(e) {
                    var t = new XMLHttpRequest;
                    t.open("GET", "https://www.website.com/locales/" + e + "/translation.json", true);
                    t.onreadystatechange = function() {
                        if (this.readyState === 4 && this.responseText) {
                            var e = JSON.parse(this.responseText);
                            var t;
                            for (t in e) {
                                if (!browser.i18n.strings[t]) {
                                    var n = e[t].message;
                                    var r = e[t].placeholders;
                                    if (r) {
                                        var i;
                                        for (i in r) {
                                            var s = new RegExp("\\$" + i + "\\$");
                                            n = n.replace(s, r[i].content)
                                        }
                                    }
                                    browser.i18n.strings[t] = n
                                }
                            }
                        }
                    };
                    try {
                        t.send()
                    } catch (n) {}
                };
                for (n = 0; n < r.length; n++) {
                    i(r[n])
                }
            }
            if (typeof t === "string") {
                t = [t]
            } else if (!t) {
                t = []
            }
            var s = browser.i18n.strings[e].replace(/\$\$/g, "@@@@");
            for (n = 0; n < t.length; n++) {
                var o = new RegExp("(?!\\$\\$)\\$" + (n + 1), "g");
                s = s.replace(o, t[n])
            }
            return s.replace(/\@\@\@\@/g, "$$")
        }
    }
};
var items = document.querySelectorAll("[data-i18n]");
for (i = 0; i < items.length; i++) {
    var translation = browser.i18n.getMessage(items[i].getAttribute("data-i18n"));
    try {
        if (items[i].value === "i18n") {
            items[i].value = translation
        } else {
            items[i].innerHTML = translation
        }
    } catch (e) {}
}

在此之前在 Google Chrome 和 Opera 中运行良好。现在它不起作用。 它总是向我显示这个错误:

无法读取未定义的“替换”属性

知道如何解决这个问题吗?

更新: 这里是(翻译)json文件:

  {
  "uparrow":{
    "message":"Up"
  },
  "downarrow":{
    "message":"Down"
  },
  "nextbutton":{
    "message":"Next"
  },
  "slide1welcome":{
    "message":"Welcome User"
  }
}

阅读此 HTML 代码 ...TEXT HERE... 谢谢,

【问题讨论】:

  • 在替换之前添加一个调试器语句,并在每个阶段检查n 的值。在某些时候它变得不确定。防止它阻止错误发生。
  • 这是代码的缩小版吗?你有机会发布原件吗?
  • 这是完整的 Javascript 代码,在我的 HTML 页面中,我得到了示例 下一个按钮
  • 您在哪一行收到此错误?
  • 在此代码部分 "var s = browser.i18n.strings[e].replace(/\$\$/g, "@@@@");"

标签: javascript xml json html xmlhttprequest


【解决方案1】:

似乎"https://www.website.com/locales/" + e + "/translation.json" 内部没有这样的消息,其中e - 是一种语言。
据我所知,如果没有定义 browser.i18n.strings - 那么您从 "https://www.website.com/locales/" + e + "/translation.json" 加载消息的翻译并将其放入 browser.i18n.strings
下次当您要翻译一条消息时 - 您希望这条消息已经在 browser.i18n.strings 中。但似乎browser.i18n.strings 内部没有这样的密钥。这就是为什么会出错。作为一个热修复 - 我建议简单地添加一些代码,如:

...
} else if (!t) {
    t = []
}

var s = "";
if (browser.i18n.strings[e]) {
    s = browser.i18n.strings[e];
} else {
    s = e;
}
s = s.replace(/\$\$/g, "@@@@");

for (n = 0; n < t.length; n++) {
...

在这种情况下,您的消息仍然不会被翻译。但是不会有错误。
为了获得更好的支持,您可以添加一些特殊符号来检测此类未翻译消息并有效地添加适当的翻译。例如。用方括号括住未翻译的消息:

...
var s = "";
if (browser.i18n.strings[e]) {
    s = browser.i18n.strings[e];
} else {
    s = "[[" + e + "]]";
}

注意:查找翻译的代码是synchronous,但翻译加载是asynchronous。因此,当您首先请求翻译时 - 提出了请求,但您的代码将继续执行。当响应到来时 - 您的代码已经完成循环 DOM 节点。
作为一种解决方法 - 您可以尝试以同步方式加载翻译(只需将 t.open(...) 中的最后一个参数更改为 false但这不是一个好的解决方案:翻译请求正在进行时- 您的页面将不可用。从用户体验的角度来看,这并不好。
因此,我建议在初始页面加载期间检查您的架构并加载翻译。

【讨论】:

  • 现在它只显示“nextbutton”中的文本(来自 HTML 代码 data-i18n="nextbutton"。而且我的 fr/translation.json 没有翻译
  • @user1731468,您能提供您的fr/translation.json 文件吗?你确定里面有这样的钥匙吗?
  • 查看 json 文件的更新。
  • @user1731468,它适用于我这样的翻译文件。你能用你的非工作示例准备一个简短的jsFiddle
  • 这里是链接jsfiddle.net/0utk8ep1/3 正常我必须看到“en haut”、“vers le bas”。只显示文本“uparrow”
猜你喜欢
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多