最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Replace many text terms, using Tampermonkey, without affecting URLs and not looking for classes or ids - Stack Over

programmeradmin4浏览0评论

I'm writing a Google Chrome extension for a popular e-merce SAAS which will replace English text strings to Spanish inside its admin panel.

I've e with a solution which replaces EVERYTHING, so when finding an a href, it also replaces it which is not desired:

var els = document.getElementsByTagName("*");
for(var i = 0, l = els.length; i < l; i++) {
var el = els[i];
// ==Menu_left_dropdown==
el.innerHTML = el.innerHTML.replace(/View your user account/gi, 'Tu cuenta');
el.innerHTML = el.innerHTML.replace(/Terms of service/gi, 'Términos y condiciones');
el.innerHTML = el.innerHTML.replace(/Privacy policy/gi, 'Privacidad');
el.innerHTML = el.innerHTML.replace(/Log out/gi, 'Salir');
// ==Menu_left=
el.innerHTML = el.innerHTML.replace(/Search/gi, 'Buscar');
el.innerHTML = el.innerHTML.replace(/Dashboard/gi, 'Panel');
el.innerHTML = el.innerHTML.replace(/Orders/gi, 'Pedidos');
el.innerHTML = el.innerHTML.replace(/Customers/gi, 'Clientes');
el.innerHTML = el.innerHTML.replace(/Products/gi, 'Productos');
}

Getting elements by class or id, wouldn't be easy to maintain as they might change without the platform informing us. I also plan to add more locales so any suggestion on how to approach a cleaner way to organize the strings would be great.

I'm writing a Google Chrome extension for a popular e-merce SAAS which will replace English text strings to Spanish inside its admin panel.

I've e with a solution which replaces EVERYTHING, so when finding an a href, it also replaces it which is not desired:

var els = document.getElementsByTagName("*");
for(var i = 0, l = els.length; i < l; i++) {
var el = els[i];
// ==Menu_left_dropdown==
el.innerHTML = el.innerHTML.replace(/View your user account/gi, 'Tu cuenta');
el.innerHTML = el.innerHTML.replace(/Terms of service/gi, 'Términos y condiciones');
el.innerHTML = el.innerHTML.replace(/Privacy policy/gi, 'Privacidad');
el.innerHTML = el.innerHTML.replace(/Log out/gi, 'Salir');
// ==Menu_left=
el.innerHTML = el.innerHTML.replace(/Search/gi, 'Buscar');
el.innerHTML = el.innerHTML.replace(/Dashboard/gi, 'Panel');
el.innerHTML = el.innerHTML.replace(/Orders/gi, 'Pedidos');
el.innerHTML = el.innerHTML.replace(/Customers/gi, 'Clientes');
el.innerHTML = el.innerHTML.replace(/Products/gi, 'Productos');
}

Getting elements by class or id, wouldn't be easy to maintain as they might change without the platform informing us. I also plan to add more locales so any suggestion on how to approach a cleaner way to organize the strings would be great.

Share Improve this question edited Jun 25, 2014 at 22:48 Brock Adams 93.5k23 gold badges240 silver badges304 bronze badges asked Jun 25, 2014 at 20:18 alexandresaizalexandresaiz 2,7669 gold badges30 silver badges40 bronze badges 1
  • you can check for el.children, and if present, skip the text replacement on that non-child node. that should keep your href attribs intact. – dandavis Commented Jun 25, 2014 at 20:36
Add a ment  | 

1 Answer 1

Reset to default 15

To avoid trashing URL's, id's, event handler's, etc.; you need to act only on the TEXT_NODEs of a web page. Never use innerHTML.

An efficient way to act on text nodes is to use a Tree Walker.

For the replacement terms, use an array.

Putting it all together, the code looks like this:

var replaceArry = [
    [/View your user account/gi,    'Tu cuenta'],
    [/Terms of service/gi,          'Términos y condiciones'],
    [/Privacy policy/gi,            'Privacidad'],
    // etc.
];
var numTerms    = replaceArry.length;
var txtWalker   = document.createTreeWalker (
    document.body,
    NodeFilter.SHOW_TEXT,
    {   acceptNode: function (node) {
            //-- Skip whitespace-only nodes
            if (node.nodeValue.trim() )
                return NodeFilter.FILTER_ACCEPT;

            return NodeFilter.FILTER_SKIP;
        }
    },
    false
);
var txtNode     = null;

while (txtNode  = txtWalker.nextNode () ) {
    var oldTxt  = txtNode.nodeValue;

    for (var J  = 0;  J < numTerms;  J++) {
        oldTxt  = oldTxt.replace (replaceArry[J][0], replaceArry[J][1]);
    }
    txtNode.nodeValue = oldTxt;
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论