как получить и заменить текст внутри тегов и вложенных тегов, элементы на сайте (не мое) в js - PullRequest
0 голосов
/ 12 февраля 2019

Я работаю над JavaScript, который действует как переводчик Google, когда вы щелкаете правой кнопкой мыши на странице и выбираете опцию перевода на английский,

Моя проблема в том, что я застрял на этапе алгоритма, который должендостичь каждого текста в DOM сайта (не моего), в некоторых случаях есть вложенные теги, а внутри есть текст, который необходимо изменить на другой язык. Очень нужна ваша помощь, чтобы узнать, как я могу это сделать

var elements = document.querySelector('.ocms-container').querySelectorAll('*');
var elementsToArray= Array.from(elements);
let array = [...elementsToArray];
for (var i = 0; i < array.length; i++) {
    console.log(array[i].textContent);
}

Это то, что я уже пробовал, но я хочу знать, где каждый текст, который я заменяю, должен быть заменен на

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

В приведенном ниже рекурсивном примере будут найдены узлы, содержащие текст без дочерних элементов.

<html>
<head>
    <title>Example</title>
</head>
<body>

    <div>
        text1
    </div>
    <div>
        <p>text2</p>
        <span>text3 span</span>
    </div>
    <div>
        <div>
            text4
        </div>
        <div>
            <ul>
                <li>
                    li1
                </li>
                <li>
                    li2
                </li>
                <li>
                    li3
                </li>
            </ul>
        </div>
    </div>

</body>
<script>
    class DOMNodeToTranslate {
        constructor(elName, elText) {
            this.elName = elName;
            this.elText = elText;
        }

        translate() {
            // translation algorithm
        }

        // ...other methods
    }

    function findTextNodes(root) {
        if (root.childNodes.length > 1) {

            root.childNodes.forEach(node => {

                findTextNodes(node);

                let nodeText = node.textContent.replace(/(^(\s|\n|\t)+)|((\s|\n|\t)+$)/gm, '');
                if (nodeText != '' && node.childNodes.length == 1 && node.nodeName != 'SCRIPT') {
                    let elObject = new DOMNodeToTranslate(node.nodeName, nodeText);
                    toTanslate.push(elObject);
                }

            });

        }
    }

    let toTanslate = [];
    let rootElement = document.querySelector('body');
    findTextNodes(rootElement);

    console.log(toTanslate);
</script>

0 голосов
/ 13 февраля 2019

Вам необходимо выполнить цикл для каждого дочернего узла, начиная с корневого элемента, чтобы вы могли сделать это, проверив, имеет ли текущий узел childNodes, теперь, чтобы получить текст внутри узла, вы можете проверить их nodeType,проверьте это Документация по NodeType , это поможет вам понять, какие узлы есть в DOM, поэтому рабочий код для сбора всех текстовых узлов может быть:

const root = document.querySelector('body');
const queue = [root];
const textNodes = [];
const NODE_TEXT = 3;

while(queue.length) {
    const node = queue.shift();
    const children = node.childNodes;
    if (children && children.length > 0) {
        const childrenAsArray = Array.prototype.slice.call(children);
        Array.prototype.push.apply(queue, childrenAsArray);
    }
    if (node.nodeType === NODE_TEXT) {
        textNodes.push(node);
    }
}

// finally you can console.log all the text nodes collected
console.log(textNodes);

Если выЗапустите этот код на любом сайте в инструментах разработчика консоли Chrome, вы можете разместить весь текстовый узел на сайте.

Надеюсь, вы найдете его полезным.

РЕДАКТИРОВАТЬ

чтобы получить текстовое значение для каждого узла, вы должны сначала проверить некоторые правила, прежде чем получать текст, поэтому давайте начнем.

  1. исключите script, 'style', 'noscript' иcode tags
  2. проверить, есть ли у текущего узла один дочерний узел
  3. проверить, является ли дочерний узел текстовым узлом (NODE_TEXT = 3)
  4. проверить, является ли дочерний узелне пусто

Итак, начнем, надстройкаg эти правила

const root = document.querySelector('body');
const queue = [root];
const textNodes = [];
const NODE_TEXT = 3;
const exclude = ["SCRIPT", "STYLE", "CODE", "NOSCRIPT"]; // add exclude tags

// check if node is not the exclude one
function isNodeAllow(node){
return exclude.indexOf(node.tagName) === -1;
}

// define a helper function to check if has one child node
function hasOneChildNode(node){
return node.childNodes && node.childNodes.length === 1;
}

// check if node is not the exclude one
function isChildNodeText(node){
return node.childNodes[0].nodeType === NODE_TEXT;
}

// check if node is not the exclude one
function isNotEmpty(node){
return Boolean(node.innerText.trim());
}

while(queue.length) {
    const node = queue.shift();
    const children = node.children;
    if (children && children.length > 0) {
        const childrenAsArray = Array.prototype.slice.call(children);
        Array.prototype.push.apply(queue, childrenAsArray);
    }
    if (isNodeAllow(node) && hasOneChildNode(node) && isChildNodeText(node) && isNotEmpty(node)) {
        // here you can translate the text.
        // node.innerText will return the text to be translated
        textNodes.push(node);
    }
}

// finally you can have all the collected text into the site
console.log(textNodes)

Надеюсь, это поможет вам.

...