Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use JavaScript or CSS to close a previous div?

I am working within the constraints of a content management system that sometimes forces me to do some odd things because I don't have full control of the HTML code.

In this instance, I have a situation where I want one DIV to not be nested inside another DIV. Because of the CMS settings, I can't just re-order the DIVs in the HTML code.

So, I have this:

<div class="blog">
   <div class="free-me">
      Hello world
   </div>
</div>

What I need is:

<div class="blog">
</div>
<div class="free-me">
   Hello world
</div>
<div class="blog">
</div>

This would be as simple as copying and pasting some lines if I could access the HTML. But, since I can't just change the HTML, what I want to know is if there's any way I can use CSS or JavaScript to close off the blog DIV so that free-me can be a sibling.

I tried this (even though I kind of knew it wouldn't work):

.free-me::before {
    content: '</div>';
}

As suspected, that just rendered text that said </div> into the page.

For JavaScript, I'm certainly no expert, but it seems like you can only insert complete elements, with opening and closing tags, with a command like document.createElement('div'); I can't see a clear way to take an existing DIV and close it off.

Is there a way, either with CSS or JavaScript, I can force a DIV to close or insert an ending </div> tag?

Note: Preferably a non-jQuery solution.

like image 983
Questioner Avatar asked Apr 11 '17 09:04

Questioner


People also ask

How do you close a div using JavaScript?

To hide a div using JavaScript, get reference to the div element, and assign value of "none" to the element. style. display property.

How do you close a div element?

Div tag has both open(<div>) and closing (</div>) tag and it is mandatory to close the tag.

Is self closing div valid?

It is unnecessary to add an explicit closing “ </div> “ tag to the string you pass to . html() , because jQuery will take care of that for you. Beware: although this XML-like syntax (“ <div/> “) is accepted by jQuery, it is not valid HTML, and shouldn't be used in HTML files.

Can you disable a whole div?

Nope! Divs can't be disabled. Only form and form elems. Actually in Quirks-mode IE can disable a div , but it only grays button texts, it doesn't prevent events firing.


2 Answers

If you just want to pop out one div out of the other after rendering I suggest you use jQuery insertAfter method. I also use a CMS and know exactly how you feel.

$(".free-me").insertAfter(".blog");
.blog {
  border: 1px solid red;
  width: 100px;
  height: 20px;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="blog">
  <div class="free-me">
    Hello world
  </div>
</div>
like image 169
Dan Philip Avatar answered Sep 30 '22 03:09

Dan Philip


You can achieve this with JavaScript by looping through all the elements with the classname .free-me and inserting into them DOM before their parent elements' next siblings, which will also remove them from their parent elements at the same time.

(function(){
    var children=document.querySelectorAll(".blog>.free-me"),
        x=children.length,
        child,parent;
    while(x--){
        child=children[x];
        parent=child.parentNode;
        // Uncomment below if you would prefer to
        // explicitly remove the child from the parent.
        //parent.removeChild(child);
        parent.parentNode.insertBefore(child,parent.nextSibling);
    }
})();
div{
    margin:5px;
    padding:10px;
}
.blog{
    background:#000;
}
.free-me{
    background:#090;
}
.ignore-me{
    background:#f00;
}
<div class="free-me"></div>
<div class="blog"></div>
<div class="blog">
    <div class="free-me"></div>
</div>
<div class="blog">
    <div class="free-me"></div>
    <div class="free-me"></div>
</div>
<div class="blog">
    <div class="free-me"></div>
    <div class="ignore-me"></div>
    <div class="free-me"></div>
    <div class="free-me"></div>
</div>

However, if your parent elements contain multiple children, some of which will have the .free-me class and some of which won't, and you wish to maintain the order of all child elements then the solution is a little more complex (Note: this Snippet was a little rushed so could probably be cleaned up a good bit.)

(function(){
    var blogs=document.querySelectorAll(".blog"),
        x=blogs.length,
        grandparent,parent,clone,children,child,y;
    while(x--){
        parent=blogs[x];
        // You can remove the following if statement
        // if you wish to have any pre-existing empty .blog
        // elements removed from the DOM.
        if(parent.querySelector(".free-me")){
            grandparent=parent.parentNode;
            children=parent.children;
            y=children.length;
            while(y--){
                child=children[y];
                if(child.classList.contains("free-me")){
                    if(clone){
                        grandparent.insertBefore(clone,parent.nextSibling)
                        clone=0;
                    }
                    grandparent.insertBefore(child,parent.nextSibling);
                }else{
                    if(!clone)
                        clone=parent.cloneNode(0);
                    clone.insertBefore(child,clone.firstChild);
                }
            }
            grandparent.removeChild(parent);
        }
    }
})();
div{
    margin:5px;
    padding:10px;
}
.blog{
    background:#000;
}
.free-me{
    background:#090;
}
.ignore-me{
    background:#f00;
}
<div class="free-me">1</div>
<div class="blog"></div>
<div class="blog">
    <div class="free-me">2</div>
</div>
<div class="blog">
    <div class="free-me">3</div>
    <div class="free-me">4</div>
</div>
<div class="blog">
    <div class="free-me">5</div>
    <div class="ignore-me">6</div>
    <div class="ignore-me">7</div>
    <div class="free-me">8</div>
</div>
<div class="blog">
    <div class="ignore-me">9</div>
    <div class="free-me">10</div>
    <div class="ignore-me">11</div>
    <div class="free-me">12</div>
</div>
<div class="blog">
    <div class="ignore-me">13</div>
</div>
like image 23
Shaggy Avatar answered Sep 30 '22 01:09

Shaggy