Javascript替换模板引擎的innerHTML部分

Javascript替换模板引擎的innerHTML部分,javascript,html,dom,Javascript,Html,Dom,我正在编写一个模板引擎。我试图按需更新innerHTML的某些部分,例如当模型更新时 据我所知,我可以通过两种方式更新部分: 用父元素包装html部分,获取该元素并重新生成其内容,然后重新插入。然而,包装可能会破坏css规则,并且会修改用户当前的html结构 在前后添加注释,找出要更新的部分,然后替换该部分。这很好,但当我这样做时: document.documentElement.innerHTML=innerHTML.substring(0,indexStart)+模板+innerHTML.

我正在编写一个模板引擎。我试图按需更新innerHTML的某些部分,例如当模型更新时

据我所知,我可以通过两种方式更新部分:

  • 用父元素包装html部分,获取该元素并重新生成其内容,然后重新插入。然而,包装可能会破坏css规则,并且会修改用户当前的html结构

  • 在前后添加注释,找出要更新的部分,然后替换该部分。这很好,但当我这样做时:

    document.documentElement.innerHTML=innerHTML.substring(0,indexStart)+模板+innerHTML.substring(indexEnd)

  • 整个dom将替换为一个新字符串,来自其他部分的所有事件绑定都将丢失

    那么,对于如何使用注释策略或类似策略仅替换html的一部分,有人有更好的想法吗

    示例

    <html>
      <head>
    
      </head>
    
      <body>
    
        <div>something</div>
    
        <!-- id:321312321 -->
          <div>Replace all within this comment space</div>
          <div>1</div>
          <div>2</div>
          <div>3</div>
        <!-- id:321312321 -->
    
      </body>
    </html>
    
    
    某物
    替换此注释空间中的所有内容
    1.
    2.
    3.
    
    可用于示例:

    <html>
      <head></head>
      <body>
        <div>something</div>
    
        <!-- id:321312321 -->
          <div>Replace all within this comment space</div>
          <div>1</div>
          <div>2</div>
          <div>3</div>
        <!-- id:321312321 -->
    
      </body>
    </html>
    
    commentReplaceBetween("<div>1</div>", " id:321312321 ");
    
    我的评论是这样称呼的

    commentReplaceBetween(commentContent)(template);
    
    因此,我的实际commentReplaceBetween函数被包装,如下所示:

    <html>
      <head></head>
      <body>
        <div>something</div>
    
        <!-- id:321312321 -->
        <div>1</div>
        <!-- id:321312321 -->
    
      </body>
    </html>
    
    function commentReplaceBetween(template, commentContent) {
            var div       = document.createElement("div");
            div.innerHTML = template;
    
            // Find our comment first
            var comment    = nodeCommentFind(document.documentElement, commentContent);
            var parentNode = comment.parentNode;
            var sibling    = comment.nextSibling;
    
            // Delete all contents in between
            while ( sibling ) {
                    if ( nodeCommentContentMatch(sibling, commentContent) ) {
                            break;
                    } else {
                            var tmp = sibling;
                            sibling = sibling.nextSibling;
                            parentNode.removeChild(tmp);
                    }
            }
    
            // Then append our elements afterw
            var child, children  = div.childNodes;
            for ( var i = 0; i < children.length; i++) {
                    child = children[i];
    
                    // See:
                    // http://www.javascriptkit.com/domref/nodetype.shtml
                    // and
                    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms764649(v=vs.85).aspx
                    if ( child.nodeType === 1 || child.nodeType === 7 || child.nodeType === 8 || child.nodeType === 11 ) {
                            // Sibling here should be the last comment, otherwise the entire page have been incorrectly deleted.
                            parentNode.insertBefore(child, sibling);
                    }
            }
    }
    
    var cacheComment = {};
    function nodeCommentFind(node, commentContent) {
            var child = cacheComment[commentContent];
            if ( child ) {
                    return child;
            }
            else {
                    return nodeCommentFindRecurse(node, commentContent);
            }
    }
    
    function nodeCommentFindRecurse(node, commentContent) {
            var children = node.childNodes;
    
            var child, returns;
            for(var i = 0; i < children.length; i++) {
                    child = children[i];
    
                    if( nodeCommentContentMatch(child, commentContent) ) {
                            cacheComment[commentContent] = child;
                            return child;
                    }
                    else if ( child.hasChildNodes && child.childNodes ) {
                            returns = nodeCommentFindRecurse(child, commentContent);
                            if ( returns ) return returns;
                    }
            }
    }
    
    function nodeCommentIs(node) {
            return node.nodeType === 8;
    }
    function nodeCommentContentMatch(node, commentContent) {
            return nodeCommentIs(node) && node.nodeValue === commentContent;
    }
    
    function commentReplaceBetween(commentContent) {
            return function(template) {
                    var div       = document.createElement("div");
                    div.innerHTML = template;
    
                    // Find our comment first
                    var comment    = nodeCommentFind(document.documentElement, commentContent);
                    var parentNode = comment.parentNode;
                    var sibling    = comment.nextSibling;
    
                    // Delete all contents in between
                    while ( sibling ) {
                            if ( nodeCommentContentMatch(sibling, commentContent) ) {
                                    break;
                            } else {
                                    var tmp = sibling;
                                    sibling = sibling.nextSibling;
                                    parentNode.removeChild(tmp);
                            }
                    }
    
                    // Then append our elements afterw
                    var child, children  = div.childNodes;
                    for ( var i = 0; i < children.length; i++) {
                            child = children[i];
    
                            // See:
                            // http://www.javascriptkit.com/domref/nodetype.shtml
                            // and
                            // http://msdn.microsoft.com/en-us/library/windows/desktop/ms764649(v=vs.85).aspx
                            if ( child.nodeType === 1 || child.nodeType === 7 || child.nodeType === 8 || child.nodeType === 11 ) {
                                    // Sibling here should be the last comment, otherwise the entire page have been incorrectly deleted.
                                    parentNode.insertBefore(child, sibling);
                            }
                    }
            };
    }
    
    函数commentreplacetween(commentContent){
    返回函数(模板){
    var div=document.createElement(“div”);
    div.innerHTML=模板;
    //先找到我们的评论
    var comment=nodeCommentFind(document.documentElement,commentContent);
    var parentNode=comment.parentNode;
    var sibling=comment.nextSibling;
    //删除中间的所有内容
    while(兄弟姐妹){
    if(nodeCommentContentMatch(同级,注释内容)){
    打破
    }否则{
    var tmp=兄弟姐妹;
    sibling=sibling.nextSibling;
    parentNode.removeChild(tmp);
    }
    }
    //然后将我们的元素附加到
    var child,children=div.childNodes;
    对于(变量i=0;i
    这完全无关。。。让我们说,当我发布它时,你会知道的…不是真的。你可以在github上查看10个模板引擎中的一些,看看它们是如何做到的,或者干脆不用麻烦,使用一个真正的、经过测试的引擎。它们都很糟糕,这就是为什么。。。请如果您愿意,您可以返回并使用prototype或css2。。。世界在前进,坚持这个问题,好吗?通常,人们会对愚蠢的评论投反对票,认为我确实不能做得比目前已有的更好,或者人们甚至不应该尝试做得更好,我真可怜那些傻瓜。@MoJS:看来你的引擎必须捕获事件绑定,然后在替换内容后重新绑定,不是吗?如果销毁具有事件的DOM元素,那么获取这些事件的唯一方法就是捕获并将它们重新添加到新元素中。您必须创建一种机制(或重用一种机制,如jQuery)来维护当前和未来元素上的事件。也就是说,你的引擎会做一些他们做不到的事情吗?
    function commentReplaceBetween(commentContent) {
            return function(template) {
                    var div       = document.createElement("div");
                    div.innerHTML = template;
    
                    // Find our comment first
                    var comment    = nodeCommentFind(document.documentElement, commentContent);
                    var parentNode = comment.parentNode;
                    var sibling    = comment.nextSibling;
    
                    // Delete all contents in between
                    while ( sibling ) {
                            if ( nodeCommentContentMatch(sibling, commentContent) ) {
                                    break;
                            } else {
                                    var tmp = sibling;
                                    sibling = sibling.nextSibling;
                                    parentNode.removeChild(tmp);
                            }
                    }
    
                    // Then append our elements afterw
                    var child, children  = div.childNodes;
                    for ( var i = 0; i < children.length; i++) {
                            child = children[i];
    
                            // See:
                            // http://www.javascriptkit.com/domref/nodetype.shtml
                            // and
                            // http://msdn.microsoft.com/en-us/library/windows/desktop/ms764649(v=vs.85).aspx
                            if ( child.nodeType === 1 || child.nodeType === 7 || child.nodeType === 8 || child.nodeType === 11 ) {
                                    // Sibling here should be the last comment, otherwise the entire page have been incorrectly deleted.
                                    parentNode.insertBefore(child, sibling);
                            }
                    }
            };
    }