How to convert HTML DOM structure - javascript

I have different requirement for my webpage. For that I need to change the DOM elements. I will have the html from server through AJAX. Html is come from server for different pages is different. Like,
<h1> Some text </h1>
Text out of tags
<div>
<p> Text in div </p>
<img src="some-image.jpg" />
</div>
<p> Some other text </p>
<p> Some other text </p>
<img src="some-image.png" />
Something like that.
When it appears in webpage, It would be like,
Some text Text out of tags
Text in div An Image
Some other text
Some other text
Another Image
So, what I need is, I want to convert the above HTML DOM structure as follows by using Javascript or jQuery.
<p> Some text Text out of tags Text in div</p>
<img src="some-image.jpg" />
<p> Some other text </p>
<p> Some other text </p>
<img src="some-image.png" />
I just want text through <p> tags and images through <img> tags. I don't require remaining all other stuff.
If it is possible, please help me.
Any help would be appreciated.

You can use
$("<selector>").contents().unwrap();
with all the element you want to remove.
For example:
$(document).ready(function() {
$('h1, div, a').contents().unwrap();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> <h1> Some text </h1> </p>
<div> <img src="some-image.jpg" /> </div>
<p> Some other text </p>
<p> Some other text </p>
<img src="some-image.png" />

Similar to this question remove parent element but keep the child element using jquery in HTML
use replaceWith() and return the element you want

You can manipulate/edit the DOM structure received from the server. To hide certain <div> or <p> elements, try following :
document.getElementById("divWithImage").style.display = "none";
^^^^^^
Of course this will hide everything inside, so you should get hold of the inside contents like <img> and inject them again in the DOM at desired location.

Related

Using jQuery to add paragraph tags and skip HTML elements

I have some HTML being fed in to me for blogs and want to be able to ensure it's parsed properly.
I am using this jQuery function (below) to ensure text is being wrapped in a paragraph tag however it seems to be filtering out the strong and a tags into their own paragraph tags.
Here is the original HTML:
<div id="demo">
<h2>This is a title</h2>
This is content that will need to be wrapped in a paragraph tag <strong>and this is bold</strong> and this is a link.<br />
More content here.
</div>
Now using this function to filter this:
$('#demo')
.contents()
.filter(function() {
return this.nodeType === 3 && $.trim(this.textContent).length;
})
.wrap('</p>');
Renders me this HTML:
<div id="demo">
<h2>This is a title</h2>
<p>This is content that will need to be wrapped in a paragraph tag </p>
<strong>and this is bold</strong>
<p> and this is a </p>
link.
<p>More content here.</p>
</div>
As you can see, I'm getting half of what I need but it's separating the HTML elements outside of the paragraph tag. Is there a way I can allow these HTML elements to remain inside the paragraph tag?
Thanks
You can store the h2 element, remove it from the structure, wrap what remains and add back in the h2.
let cloned = $("#demo > h2").clone(); // Clone the <h2>
$("#demo > h2").remove(); // Remove the <h2>
$("#demo").wrapInner("<p>"); // Wrap everyting left over
cloned.insertBefore("p"); // Put <h2> back
console.log($("#demo").html());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="demo">
<h2>This is a title</h2>
This is content that will need to be wrapped in a paragraph tag <strong>and this is bold</strong> and this is a link.
More content here.
</div>

.html() not working in second id but is in first id

When you press button it calls randomQuote() function using onClick method in html. It works fine , changes the background color and the text of quotes[rand] also works. But there is no change in by id element. Also, it is not a array problem because if i type the same by statement outside the randomQuote(), it works fine.
Here is the code:
function randomQuote(){
var rand =Math.floor(Math.random()*(quotes.length));
$("#qu").html(quotes[rand]);
$("#by").html(by[rand]);
$("body").animate({backgroundColor: colorr[rand]}, 1000);
};
(Go to https://codepen.io/TheCoder21/pen/XVVxvo) for full code
The issue in your markup:
<div class="quote">
<blockquote id="qu">
Here are some of my favourite quotes.Hope you enjoy them!
<p id="by">
random text
</p>
</blockquote>
</div>
container with id="by" overwrites by this jquery method $("#qu").html(quotes[rand]);
If you want to prevent this behaviour just wrap your text in new paragraph with id="qu":
<blockquote>
<p id="by">
Here are some of my favourite quotes.Hope you enjoy them!
</p>
<p id="by">
random text
</p>
</blockquote>
The problem is that your by element belongs inside blockguote i.e id=qu element when you did $("#qu").html(quotes[rand]);
It's html structure got changes. you no longer have a by element.
Therefore, when you try to $("#by").html(by[rand]); nothing happens. Because no by element was found.
Solution: move your by element outside the blockquote
Working code: https://codepen.io/anon/pen/MrLodd
You have to separate the id in two paragraphs inside the blockquote. You can't give the blockquote and id and then expect the paragraph tag to also pick up an id inside of it. The blockquote overrides it.
<blockquote>
<p id="qu">
Here are some of my favourite quotes.Hope you enjoy them!
<p>
<p id="by">
random text
</p>
</blockquote>

Javascript: select a textnode

<div>
some text
<img />
<br>
text I want to select
<br>
<img />
some text
</div>
The HTML is like above, I want to select the text between the two images, is there anyway to do this?
Some background: I am trying to format some poorly written HTML so it can be further stylized. There are too many pages of them to hardcode it one by one, they have some certain pattern though, so I am trying to write a javascript function to make the whole procedure easier. The text between <br> is actually the description of the first image, I want to wrap it with <div> so I can add class to it and stylize it. But first I need to select it, right?
Simplest solution using core jQuery functions:
$('img').nextUntil('img').doSomething();
Jonathan Snook pointed me to the jQuery 1.4 function that solves this:
nextUntil()
Check out it's sibling functions:
prevUntil
parentsUntil
Inspired by:
nextAll
prevAll
For other reference check this one :How to select all content between two tags in jQuery
<div>
some text
<img />
<br>
<span>text I want to select <span>
<br>
<img />
some text
</div>
add tag for this and get "div span" . If have more span in "div" . add id or class for them.

Change only text (Jquery)

I have a small problem that i cannot solve.I have this : <p>Text<span></span></p> and i want to change only the text of the <p>.Which means, when i click on an change-Button, the text based on an input field should replace the text.
What i have tried is something like this : $("p").text("newText") but this will also remove the <span>.
So how can i only change the text and not the inner html...
With your HTML above you can do
$('p').contents().first()[0].textContent='newText';
The idea is to take advantage of the fact that contents() includes text-nodes. Then, access by index [0] to get the native javascript DOM element and set the textContent
$('p').contents().first()[0].textContent = 'newText';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<p>Text<span>inside span</span>
</p>
Put another span inside of the p tag and only change its contents:
<p>
<span id="theText">Text</span>
<span></span>
</p>
And then:
$('#theText').text('newText');
$('#theText').text('newText')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<span id="theText"></span>
<span>some other span</span>
</p>

Why does delegate not work in "p" tag?

When delegate with p tag, it does not work http://jsfiddle.net/peswe/wbVMV/4/
HTML:
<p id='test'>
<div>box 1
<div>box in box1</div>
</div>
</p>
​
JavaScript:
$('p#test').delegate('div','click',function(){
alert('test');
})
Changing p#test to span#test or body, it works http://jsfiddle.net/peswe/wbVMV/3/
HTML:
<span id='test'>
<div>box 1
<div>box in box1</div>
</div>
</span>
​
JavaScript:
$('span#test').delegate('div','click',function(){
alert('test');
})
Please tell me something about it.Thank you very much!
This is how browser (HTML parser) works, since <div> is a Flow element and <p> is a Phrasing element, in most case an phrasing element cannot contain any flow element, this is called misnested tags, HTML parser would fix these issues magically with some certain steps:
When reading <p>, it generates a <p> element
When reading <div>, since <div> cannot reside in a <p> element, HTML parser closes the last <p> element, then open an <div> element
When reading </div>, closes the <div> element
When reading </p>, since previous <p> element is closed, parser recogonizes it as a <p> element missing a start tag, so parser automatically inserts an <p> start tag here to create a complete <p> element
Thus, the final DOM construct is:
<p id="test"></p> <!-- auto closed -->
<div>
box1
<div>
box in box1
</div>
</div>
<p></p> <!-- auto generated -->
It's obvious that the <div> and <p> is at the same level, not forming a containing relation, so delegate fails here.
The browser is correcting your invalid HTML and moving the div outside of the p. They become siblings, hence event delegation does not work. Just inspect the elements and see for yourself:
First case:
<body>
<p id="test"></p>
<div>box 1
<div>box in box1</div>
</div>
<p></p>
</body>
Second case:
<body>
<span id="test">
<div>box 1
<div>box in box1</div>
</div>
</span>
</body>
The p tag can only contain inline elements,
While the <span> tag (as being one that handles pretty well the crossbrowser identity of an inline-block element) accepts pretty well (visually cause in the code it get messed) the div tag, although either incorrect.
It won't validate either in strict 4.01 doctype nor in HTML5.
The appropriate way would be to wrap it in a block-level element : a div.

Categories

Resources