Самый быстрый и надежный способ заменить различные вхождения строки в объектах dom на JavaScript / jQuery - PullRequest
1 голос
/ 08 июля 2019

Я написал функцию, которая заменяет все вхождения «@TransResource .....», например «@ TransResource.Contact.Send», заменой из массива json.

Примером вхождения может быть:

<button class="btn btn-primary btn-block js-send">@TransResource.Contact.Send</button>

<input type="text" class="form-control" id="LastName" name="LastName" placeholder="@TransResource.Contact.LastName">

<a href="#">@TransResource.Contact.LastName"</a>

Все прошло нормально, кроме IE / edge потерял некоторые переводы, и я не могу понять, почему.Можно ли решить эту проблему и / или использовать лучший или надежный подход?

Вы можете видеть, что скрипта отлично работает в Chrome, но кнопка перевода текста отсутствует в ребре.

вот скрипка

мой код JavaScript.

var
getLocalResource = function (key) {
    try {
        var retVal = key;
        retVal = StringResource[retVal] === null || StringResource[retVal] === undefined ? retVal : StringResource[retVal];
        return retVal;
    }
    catch (err) {
        console.log(arguments.callee.name + ": " + err);
    }
},
translate = function (node) {
    try {
        var pattern = /@TransResource.[a-zA-Z0-9.]+/g;
        if (!node) node = $("body *");

        node.contents().each(function () {
            if (this.nodeType === 3) {
                this.nodeValue = this.nodeValue.replace(pattern, function (match, entity) {
                    return getLocalResource(match.slice(15));
                });
            }

            if (this.attributes) {
                for (var i = 0, atts = this.attributes, n = atts.length, arr = []; i < n; i++) {
                    if (atts[i].nodeValue !== "") { // Ignore this node it is an empty text node
                        atts[i].nodeValue = atts[i].nodeValue.trim().replace(pattern, function (match, entity) {
                            return getLocalResource(match.slice(15));
                        });
                    }
                }
            }
        });
    }

    catch (err) {
        console.log(arguments.callee.name + ": " + err);
    }
};

и json:

var StringResource = {
    "Contact.EmailAddress": "Email address",
    "Contact.Headline": "Contact",
    "Contact.Description": "please leaf us a message...?",
    "Contact.Teasertext": "Please leaf us a message <b>bold text</b>",
    "Contact.Telephone": "Telephone",
    "Contact.Send": "Send",
    "Page.Contact": "Contact"
};

edit (теперь это мое решение): благодаря @ Chris-G его комментарий устраняет проблему с IE, а также благодаря @trincot за обновление производительности.Все вместе теперь это скрипт:

var
getLocalResource = function (key) {
    try {
        var retVal = key;
        retVal = StringResource[retVal] === null || StringResource[retVal] === undefined ? retVal : StringResource[retVal];
        return retVal;
    }
    catch (err) {
        console.log(arguments.callee.name + ": " + err);
    }
},
translate = function (node) {
    try {
        var pattern = /@TransResource.[a-zA-Z0-9.]+/g;
        if (!node) node = $("body *");

        node.contents().each(function () {
            if (this.nodeType === 3 && this.nodeValue.trim().length) {
                var s = this.nodeValue.replace(pattern, function (match, entity) {
                    return getLocalResource(match.slice(15));
                });
                if (this.nodeValue !== s) this.nodeValue = s;
            }

            if (this.attributes) {
                for (var i = 0, atts = this.attributes, n = atts.length, arr = []; i < n; i++) {
                    if (atts[i].nodeValue !== "") { // Ignore this node it is an empty text node
                        atts[i].nodeValue = atts[i].nodeValue.trim().replace(pattern, function (match, entity) {
                            return getLocalResource(match.slice(15));
                        });
                    }
                }
            }
        });
    }

    catch (err) {
        console.log(arguments.callee.name + ": " + err);
    }
};

1 Ответ

1 голос
/ 08 июля 2019

Проблема в IE заключается в том, что для узла textarea, когда у него нет содержимого, присваивание node.nodeValue вызовет исключение "Неверный аргумент".Не спрашивай меня почему.

Если вы добавите в HTML-код только пробел между открывающим и закрывающим тегом textarea, ошибка исчезнет, ​​но если вы это сделаете, атрибут placeholder станет бесполезным.

НоВы также можете обойти проблему в коде, присваивая node.nodeValue только когда назначенное значение отличается от его текущего значения:

if (this.nodeType === 3) {
    var s = this.nodeValue.replace(pattern, function (match, entity) {
        return getLocalResource(match.slice(15));
    });
    if (this.nodeValue !== s) this.nodeValue = s;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...