简体   繁体   English

Javascript-Div标签自动关闭

[英]Javascript - Div tag auto closing

I am changing my website to a modern web app of sorts, here is my HTML code.. 我正在将网站更改为现代的Web应用程序,这是我的HTML代码。

<joexn-profile>
<joexn-logo></joexn-logo>
<joexn-text></joexn-text>
</joexn-profile>

and this is the JavaScript I use for the <joexn-profile> tags. 这是我用于<joexn-profile>标记的JavaScript。

var joexnprofile = document.querySelector('joexn-profile');
joexnprofile.insertAdjacentHTML( 'afterBegin', '<center><div class="joexn-profile">');
joexnprofile.insertAdjacentHTML( 'afterEnd', '</div></center>');

The issue is, the <div class="joexn-profile"> tag automatically closes. 问题是<div class="joexn-profile">标记会自动关闭。

Take a look at the inspect element view: 看一下inspect元素视图:

在此处输入图片说明





JavaScript Only 仅JavaScript

As already explained by Quentin, you can't insert only half of a Node. 正如昆汀已经解释的那样,您不能仅插入节点的一半。

On the other hand, why do you want to do that at all? 另一方面,为什么要这么做呢?

1st: avoid tags like <center> or <font> or <b> , ... If you want to style sth. 第一个:避免使用<center><font><b>类的标签,...如果要设置样式。 do it with CSS. 用CSS来做。

and 2nd: what's the point in replacing <joexn-profile> with <div class="joexn-profile"> ? 第二:用<div class="joexn-profile">替换<joexn-profile>有什么意义?
Every style that you apply to the .joexn-profile CSS-Selector you can also apply to the joexn-profile CSS-Selector. 您应用于.joexn-profile CSS-Selector的每种样式也可以应用于joexn-profile CSS-Selector。

The only difference is, that you have to declare display:block for joexn-profile so that the browser knows how to render this Node; 唯一的区别是,您必须为joexn-profile声明display:block ,以便浏览器知道如何渲染此Node。 block or inline or whatever. blockinline或其他。


But if you insist in going your way, here a little utility to handle such compositions of html-markup (even partial) and DON-Nodes. 但是,如果您坚持自己的方式,这里有一个小工具可以处理html标记(甚至部分)和DON-Nodes的这种组合。

Disclaimer: Code not fully tested, it may still contain bugs. 免责声明:代码未经充分测试,可能仍然包含错误。 And fragment() doesn't handle cyclic references! fragment()不处理循环引用!

https://jsfiddle.net/mkapLz1k/1/ https://jsfiddle.net/mkapLz1k/1/

//just to be clear: this ain't a replacement for jQuery, nor does it interfere with it's purposes.
//it's a set of utilities to enable working with compositions of HTML-Markup and plain DOM-Nodes
var nodeUtils = (function(){
    var container = document.createElement("div"), 
        placeholder = document.createElement("div"),
        forEach = Array.prototype.forEach;

    function _replacePlaceholder(node){
        var parent = node.parentNode;
        parent.insertBefore(this[node.id], node);
        parent.removeChild(node);
    }

    function _randomId(){
        return ("id"+Math.random()+Math.random()+Math.random()).replace(/0\./g, "-")
    }

    function _fragment(src){
        var markup = [], 
            nodesById = {}, 
            id = "", 
            ids = [];

        function _addNode(node){
            if(!id){
                nodesById[id=_randomId()] = fragment();
                ids.push("#"+id);
                //add placeholder into the html-markup.
                //These placeholder get eventually replaced.
                markup.push('<div id="'+id+'"></div>');
            }
            nodesById[id].appendChild( node );
        }

        function _parse(node){
            if(node == null || node === "" || typeof node === "function") return;

            if(typeof node === "object"){
                if("nodeType" in node){
                    //processes DOM Nodes, of all shapes and sizes ;)
                    //including Comment-Nodes, TextNodes and DocumentFragments, ...
                    _addNode( node );
                }else if(this.NodeList && node instanceof NodeList){
                    //nodeLists change
                    //so I have to process them differently than regular lists
                    while(node.length) _addNode( node[0] );
                }else{
                    //processes anything ArrayLike
                    for(var i = 0, len = ("length" in node && node.length)|0; i<len; ++i)
                        i in node && _parse( node[i] );
                }
            }else{
                //processes primitives as html-markup
                id = "";
                markup.push( node );
            }
        }

        _parse( src );

        if(ids.length === markup.length){ //=> 0 or 1
            //src contained only Nodes, no strings or primitives
            return id? nodesById[id]: void 0;
        }

        //src contained html-markup that needs to be parsed
        container.innerHTML = markup.join("");
        if(ids.length){
            //injecting the DOM-Nodes
            forEach.call( container.querySelectorAll( ids.join(",") ), _replacePlaceholder, nodesById );
        }

        for(var frag = fragment(), fc; fc = container.firstChild; )
            frag.appendChild( fc );
        return frag;
    }


    //`fragment()` is shorthand for `document.createDocumentFragment()`
    //`fragment(composition)` returns a DocumentFragment, that can be used with `node.appendChild()`.

    //takes an arbitrary composition of nested Arrays (or ArrayLike-structures, like jQuery-Objects, NodeLists, ...), containing DOM-Nodes or strings/primitives and builds a DocumentFragment out of that
    function fragment(composition){
        return composition != null && _fragment(composition) || document.createDocumentFragment();
    }


    //all the following functions can take anything that `fragment()` can handle as input:
    //only `node` has to be a real DOM-Node!

    //almost like setting a Nodes innerHTML, but it takes more than just HTML-Markup
    function content(node, composition){
        for(var frag = fragment(composition), fc; fc=node.firstChild;) node.removeChild(fc);
        node.appendChild(frag);
        return node;
    }

    //replace a Node with the provided 
    function replace(node, composition){
        var parent = node.parentNode;

        parent.insertBefore(placeholder, node);
        parent.insertBefore(fragment(composition), placeholder);
        parent.removeChild(placeholder);

        //how parent could have changed? maybe you referenced node somewhere in composition.
        if(parent === node.parentNode) parent.removeChild(node);

        return node;
    }

    //wraps a Node in the provided markup.
    //beforeBegin and afterEnd CAN contain associated markup. Like opening and closing Tag of the same Node.
    //e.g.: wrapNode(node, "<div>", "</div>");
    function wrapNode(node, beforeBegin, afterEnd){
        return replace(node, [beforeBegin, node, afterEnd]);
    }

    //wraps the content of the node in the provided Markup.
    //afterBegin and beforeEnd CAN contain associated markup. Like opening and closing Tag of the same Node.
    function wrapContent(node, afterBegin, beforeEnd){
        node.appendChild(fragment([afterBegin, node.childNodes, beforeEnd]));
        return node;
    }

    return {
        fragment: fragment,
        replace: replace,
        wrapNode: wrapNode,
        wrapContent: wrapContent,
        content: content,
    }   
})();

and your Markup: 和您的标记:

var joexnprofile = document.querySelector('joexn-profile');

//telling by your code, it's not entirely clear 
//wich of these you actually want to do:

nodeUtils.wrapNode(
    joexnprofile,
    '<center><div class="joexn-profile">',
    '</div></center>'   
);

//or
nodeUtils.wrapContent(
    joexnprofile,
    '<center><div class="joexn-profile">',
    '</div></center>'   
);

//or maybe
nodeUtils.replace(
    //replace this:
    joexnprofile, 

    //with this:
    [
        '<center><div class="joexn-profile">',
        joexnprofile.childNodes,
        '</div></center>'
    ]
);

Take a look at the code-examples and you get a first impression of what fragment() is able to handle 看一下代码示例,您对fragment()能够处理的内容有第一印象

var frag = nodeUtils.fragment([ 
    //you can build this Array inline, no need to do that beforehand
    condition? 
        window.title: 
        //simply inject `null` or `undefined` or `""` and this entry will be ignored
        null,

    //nest Arrays, they get parsed recursively
    [
        //mix (partial) HTML with other types
        '<div class="columns">',
            //real Nodes in the middle of some Markup: check
            document.getElementById('leftColumn'),

            //even more nesting, no problem
            [
                '<div class="middle">', 

                //handles anything Arraylike that contains Nodes or Markup
                jQuery('.someClass'),

                "</div>"
            ]
        '</div>'
    ],

    //NodeLists, no Problem
    document.querySelectorAll("#footer > div")
])

Now it's up to you how you use this. 现在由您决定如何使用此功能。

Despite the abstraction offered by insertAdjacentHTML , you are still working on a DOM. 尽管insertAdjacentHTML提供了抽象, insertAdjacentHTML您仍在处理DOM。 It has elements in a strict hierarchy, it doesn't have start and end tags. 它具有严格层次结构中的元素,没有开始和结束标签。

The HTML will be converted to DOM nodes and inserted. HTML将转换为DOM节点并插入。 You aren't editing the raw source code. 您不是在编辑原始源代码。

Use createElement instead. 请改用createElement Get the element you want inside the new element using querySelector and then use appendChild to move it inside the new element. 使用querySelector在新元素内获取所需的元素,然后使用appendChild将其移动到新元素内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM