实现像Data-Reactid这样的系统

implementing a system like data-reactid

本文关键字:系统 Data-Reactid 实现      更新时间:2023-09-26

我正在实现一个类似于data-reactid的系统(从头开始)。像这样的东西:(与使用data-reactid的目的不完全相同):

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <div>
        <p></p>
        <p></p>
        <p></p>
    </div>
</body>
</html>

<!DOCTYPE html>
<html data-id="0">
    <head data-id="0.0">
        <title data-id="0.0.0"></title>
    </head>
    <body data-id="0.1">
        <div data-id="0.1.1">
            <p data-id="0.1.1.0"></p>
            <p data-id="0.1.1.1"></p>
            <p data-id="0.1.1.2"></p>
        </div>
    </body>
</html>

我能够创建解析的 HTML 的 JSON 对象,但无法以更简单的方式做我想做的事情,你能帮帮我吗,同样!

function mapDOM(element, json) {
    var treeObject = {};
    // If string convert to document Node
    if (typeof element === "string") {
        if (window.DOMParser) {
              parser = new DOMParser();
              docNode = parser.parseFromString(element,"text/xml");
        } else { // Microsoft strikes again
              docNode = new ActiveXObject("Microsoft.XMLDOM");
              docNode.async = false;
              docNode.loadXML(element); 
        } 
        element = docNode.firstChild;
    }
    //Recursively loop through DOM elements and assign properties to object
    var li=lj=lk=-1;
    function treeHTML(element, object) {
        ++li;
        object["type"] = element.nodeName;
        var nodeList = element.childNodes;
        if (nodeList != null) {
            if (nodeList.length) {
                object["content"] = [];
                for (var i = 0; i < nodeList.length; i++) {
                    ++lj;
                    if (nodeList[i].nodeType == 3) {
                        object["content"].push(nodeList[i].nodeValue);
                    } else {
                        object["content"].push({});
                        treeHTML(nodeList[i], object["content"][object["content"].length -1]);
                    }
                    document.getElementsByTagName(nodeList[i])[i].setAttribute("data-reactid","0."+i+"."+li+"."+lj);
                }
            }
        }
        if (element.attributes != null) {
            if (element.attributes.length) {
                object["attributes"] = {};
                for (var i = 0; i < element.attributes.length; i++) {
                    object["attributes"][element.attributes[i].nodeName] = element.attributes[i].nodeValue;
                }
            }
        }
    }
    treeHTML(element, treeObject);
    return (json) ? JSON.stringify(treeObject) : treeObject;
}

那样吗?

function processNode(node, id) {
    id = !id ? "0" : String(id);
    node.dataset.id = id;
    return {
        id: id,
        type: node.nodeName.toLowerCase(),
        content: processNodeList( node.childNodes, id + "." ),
        attributes: processAttributes( node.attributes )
    }
}
function processNodeList(nodes, prefix){
    prefix = !prefix ? "" : String(prefix);
    for(var out, i=0, j=0, len = (nodes && nodes.length)|0; i < len; ++i){
        var node = nodes[i], nt = node.nodeType;
        if(nt === 1){ //Element
            value = processNode(node, prefix + j++);
        }else if(nt === 3){ //Text-Node
            //especially &nbsp; should be kept, and not replaced on stringify
            var text = node.textContent.replace(/['u00A0<>&'u00AD]/g, toHtmlEntity);
            /*
            //TODO: move that into a filter, applied when the Array is built
            //remove all-whitespace-nodes between two block-nodes like p,div,section,h1-h6
            if((i === 0 || i === nodes.length-1) && /^['r'n't ]*$/.test(text)){
                //remove whitespace at the beginning or the end of the node
                continue;
            }
            */
            //compact multiple spaces into a single one
            value = text.replace(/(['r'n't ])+/g, "$1");
        }else{
            continue;
        }
        out || (out = []);
        out.push(value);
    }
    return out;
}
function processAttributes(attrs){
    for(var out, i = 0, len = (attrs && attrs.length)|0; i < len; ++i){
        var attr = attrs[i];
        if(attr.nodeName === "data-id") continue;
        out || (out = {});
        out[attr.nodeName] = attr.nodeValue;
    }
    return out;
}
function toHtmlEntity(c){
    switch(c.charCodeAt(0)){
        case 160: return "&nbsp;";
        case 38: return "&amp;";
        case 60: return "&lt;";
        case 62: return "&gt;";
        case 173: return "&shy;";
    }
    return c;
}
function mapDOM(element) {
    // If string convert to document Node
    if (typeof element === "string") {
        if (window.DOMParser) {
              parser = new DOMParser();
              docNode = parser.parseFromString(element,"text/xml");
        } else { // Microsoft strikes again
              docNode = new ActiveXObject("Microsoft.XMLDOM");
              docNode.async = false;
              docNode.loadXML(element); 
        }
        element = docNode.firstChild;
    }
    return processNode(element);
}

var tree = mapDOM(document.body);
console.log(JSON.stringify(tree, null, 4));