Removing only the outer html element from a HTML code section - javascript

I want to remove outer HTML element from a code snippet to get the content inside including other html elements.
that is,
consider the below code
<p> My Paragraph
<ul>Mylist
<li>Item1</li>
<li>Item2</li>
</ul>
</p>
I want to get the output displayed as below
My Paragraph
<ul>Mylist
<li>Item1</li>
<li>Item2</li>
</ul>
Is this possible ??

You need to use .unwrap() along with .contents() to target all the contents in it:
$('p').contents().unwrap();
Demo

ul elements are not legally allowed inside `p' elements.
you can unwrap() function to do this Refrence

In your code ul inside p will not work as expected when using
$('p').contents().unwrap();
As suggest by A.B. Use div instead of p, than try
$('div').contents().unwrap();

Related

Why does removeChild function behave differently with list items and i tag?

I have noticed that removeChild does NOT behave as it does with other elements such as list item. I am using the i tag for some icons from frontAwesome and want these items removed individually when a button is clicked.
Unfortunately, I can only remove each i tag element only if I use removeChild() function twice. (Weird!)
What's going on?
HTML:
<div id="myFonts">
<i>1</i>
<i>2</i>
<i>3</i>
<i>4</i>
<i>5</i>
</div>
Javascript:
function FunctionTwo() {
var font = document.getElementById("myFonts");
font.removeChild(font.childNodes[0]);
}
https://codepen.io/anon/pen/EeaYvL
EDIT
Note: It makes a difference if you use LineBreaks or not!
<ul id="myList">
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
Here, there are 6 child nodes. Apparently, the LineBreaks are also considered as child nodes!
<ul id="myList"><li>Coffee</li><li>Tea</li><li>Milk</li></ul>
Here, there are 3 child nodes. WEIRD - is this a bug?
From MDN,
childNodes includes all child nodes, including non-element nodes like
text and comment nodes. To get a collection of only elements, use
ParentNode.children instead.
Hence, in both the cases, the elements are being removed weirdly. You should update
from
font.removeChild(font.childNodes[0]);
to
font.removeChild(font.children[0]);
For tweaking, https://codepen.io/anon/pen/aazoLK
Also.. if you notice both of your code closely on your link...
Code for <ul id="myList">
<ul id="myList"><li>Coffee</li><li>Tea</li><li>Milk</li></ul>
We see no spaces between tags.
Whereas, Code for <div id="myFonts">
<div id="myFonts">
<i>1</i>
<i>2</i>
<i>3</i>
<i>4</i>
<i>5</i>
</div>
You see the empty spaces before the <i>? Those got added as a text node in the childNodes object of your div
<div id="myFonts">
<i>1</i>
</div>
You could have used exactly the same code that you have currently, if you had chosen to rather Not add spaces before the <i> tags.
For Eg. like this:
<div id="myFonts"><i>1</i><i>2</i><i>3</i><i>4</i><i>5</i></div>
Check modified HTML for div here:
CodePen

How to append a ul tag inside a P or span tag?

Run the following piece of jQuery:
$('body').append('<p><span><ul><li>test</li></ul></span></p>');
I would expect this:
<p>
<span>
<ul>
<li>test</li>
</ul>
</span>
</p>
However, the result is this:
<p>
<span></span>
</p>
<ul>
<li>test</li>
</ul>
Why does the ul tag break out of span and p? This is valid HTML markup.
* UPDATE *
The p tag seems to be the problem. If you run the following:
$('body').append('<span><ul><li>test</li></ul></span>');
then
<span>
<ul>
<li>test</li>
</ul>
</span>
will generate properly.
How to append a <ul> tag inside a <p> or <span>?
You can't, it's invalid. So what you're seeing is the browser trying to rearrange it to make it valid.
The content model of span elements (e.g., what they're allowed to have in them) is "phrasing content" (things like em and such). (Same for p elements.) ul elements are only valid where "flow content" (like paragraphs and divs) is expected.
To fix it, don't try to put a ul inside a span or a p. You could remove the span and the p and use a div, for instance:
$('body').append('<div><ul><li>test</li></ul></div>');
...or just use the ul directly without a wrapper around it.
Re your update:
If you add the following markup to an html document
...
And then open the page in your favorite browser, it will open correctly. Try it!
Sure — because the browser rearranges it. For instance, this snippet:
<p>
<span>
<ul>
<li>test</li>
</ul>
</span>
</p>
Is turned into this DOM by Chrome:
Note how the ul is not inside the p or span — it's exactly the result you said you were getting.
That said, browsers do a lot to try to tolerate invalid markup and structures. But using valid markup and structures is generally the way to go.
You're putting a block-level element inside an inline element. Also, you wouldn't normally put a list in a paragraph.
$('body').append('<div><ul><li>test</li></ul></div>');
As already explained, your markup is invalid HTML and won't be parsed as you expected.
However, you can still do it using DOM manipulations.
document.body
.appendChild(document.createElement('p'))
.appendChild(document.createElement('span'))
.appendChild(document.createElement('ul'))
.appendChild(document.createElement('li'))
.appendChild(document.createTextNode('test'))
Not recommended because it's semantically wrong, but it's possible.

jQuery Prepend Open Tag Append Closing Tag

Firstly, I am familiar with .wrapAll() and that is not what I need. I have some markup that I am not able to change and I need to wrap everything in a <li>.
Here is what I am trying to do:
$('nav[role="breadcrumb"] ul a').wrap('<li></li>');
$('nav[role="breadcrumb"] ul li:last').after('<li>');
$('nav[role="breadcrumb"] ul').append('</li>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav role="breadcrumb">
<ul class="clearfix">
Home
Health Care Professionals Healthy Choices Cholesterol Kits
</ul>
</nav>
The problem is that jQuery closes each of these <li> tags. Here is the original markup:
<nav role="breadcrumb">
<ul class="clearfix">
Home
Health Care Professionals Healthy Choices Cholesterol Kits
</ul>
</nav>
As you can see, I have some loose text at the bottom of this <ul> and I am trying to get it wrapped in an <li>.
.contents() will get all the children, including the text nodes
$('nav[role="breadcrumb"] ul').contents().filter(function() {
return $.trim($(this).text())!=="";
}).wrap('<li/>');
EDIT: Added the filter method to get rid of the whitespace text nodes
Try creating your <li> first and then append your selector to it:
var $li = $('<li>').append('nav[role="breadcrumb"] ul a');
Then use $li to replace or append anywhere you like.
jQuery only works with complete elements, you can't append just a closing or opening tag.
If the ul doesn't have any other list items, you could simply use wrapInner
$('nav[role="breadcrumb"] ul').wrapInner("<li />");
If it does contain LI's, the easiest way would be to detach them, wrap inner, then append them.
var $lis = $('nav[role="breadcrumb"] ul > li').detach();
$('nav[role="breadcrumb"] ul').wrapInner("<li />").prepend($lis);

What is the difference between .empty().append() and .html()?

Using jQuery, what's the performance difference between using:
$('#somDiv').empty().append('text To Insert')
and
$('#somDiv').html('text To Insert')
?
$('#somDiv').html(value) is equivalent to $('#somDiv').empty().append(value).
Source: jQuery source.
.html will overwrite the contents of the DIV.
.append will add to the contents of the DIV.
difference between append() and html() in jQuery
.append() and .html() are the most useful methods in jQuery. But these are far different from one another, .append() add some value to the existing one. Where .html() do the same but it removes the old value first.
Here is an example:
<ul id="test">
<li>test</li>
</ul>
Now I will use .append() to add one <li>, For that I will write:
<script type="text/javascript>"
jQuery("#test").append("<li>test1</li>");
</script>
The output of this jQuery will be:
<ul id="test">
<li>test</li>
<li>test1</li>
</ul>
Now if I use .html() to add one <li>, For that I will write:
<script type="text/javascript>"
jQuery("#test").html("<li>test1</li>");
</script>
The output of this Script will be:
<ul id="test">
<li>test1</li>
</ul>
Here in this example .append() add one extra <li>, whether .html() removes the old one with new one. This is the main difference between .append() and .html() in jQuery.
In simple words:
$('#somDiv').append('blabla')
works like this:
<div id='somDiv'>some text</div>
becomes:
<div id='somDiv'>some textblabla</div>
And innerHTML replaces the contents, so it becomes this:
<div id='somDiv'>blabla</div>
The correct syntax is
$("#somDiv").html("<span>Hello world</span>");

How to aceess span directly using jQuery

I want to know how to get access of this [span class="myclass"] in below html structure..
<ul>
<li class="first">
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
<li >
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
</ul>
Here I need to write one function in [span class="myclass"], but i cant do it using $(".myclass") [I have few issues] I just want to directly access the span itself.How to do this..?
EDIT:the sln by phoenix is working fine..but lets say(just for my knowledge) the structure is
<li >
<span class="myclass"></span>
<div class="xx">
<li>
<span></span>
</li>
........
</div>
</ul>
so why the span inside 2 nd li(which is under div) is not getting the ref, is it bcoz they are not in the same level..if I need to access them do I need to do some thing like
enter code here
$("li").next(".xx").find(li span:first-child )..or something else is there?
Thanks.
$("li span.myclass")
EDIT: Okay then maybe with
$("li span:first") //EDIT: Don't do that. See below.
apparently :first stops after the first hit. So :first-child is the way to go.
which will select the first span in every li-element. But this can be tricky in case you have other li-elements with spans inside...
EDIT: If you can't use the class you already have, maybe assigning an additional class helps?
<span class="myclass newClass"></span>
...
var spans = $("li span.newClass");
EDIT:
As phoenix pointed out
$("li span:first-child")
returns a list with all span elements that are the first child of a li-element. I don't know if jQuery treats textnodes as child nodes. So if you have a space between <li> and <span>, this might be counted as the first-child. So check if you have any whitespace between your elements beside line breaks.
If span is the first child then you can use
first-child
selector
$("li span:first-child");

Categories

Resources