Replace an element with a wrapped new one - javascript

I want to replace an old element with a wrapped new one.
I begin like this:
<div>Some text
<span id="old"></span>
</div>
And I want this:
<div>Some text
<span>
<a></a>
</span>
</div>
I manage to replace the old element with the new one like this:
var elementA = document.querySelector('#old')
var elementB = document.createElement("a")
elementA.before(elementB)
elementA.remove()
Result:
<div>Some text
<a></a>
</div>
But I cannot manage to wrap the new element in the meantime. I tried to override Element.outerHTML, and jQuery wrap(), without success. Any idea please?
EDIT: I noticed I oversimplified my use case... here is the more precise code:
var elementA = document.querySelector('#old')
var elementB = document.createElement("a")
// Here I do manipulations on elementB: add classes, set Id, set attributes, set innerHTML, etc.
elementA.before(elementB)
elementA.remove()
So elementB is really an "element" (or node?), not just HTML. Maybe I can turn this element into raw HTML and insert it in the wrapper with innerHTML as per suggestions below?
If you want to look at the actual code here it is.

var elementA = document.querySelector('#old')
var elementB = document.createElement("span")
elementB.innerHTML = '<span></span>';
elementA.before(elementB)
elementA.remove()
<div>Some text
<span id="old"></span>
</div>

You could try this:
You don't need to change the HTML for this...
var elementA = document.querySelector('#old');
var elementB = document.createElement("span");
elementB.innerHTML = '<span></span>';
elementA.before(elementB);
elementA.remove()

Related

Wrapping a DIV around a hyperlink created using appendChild

I have a bit of JS to add an email hyperlink to a page, after a DIV with an ID value of section_form_id:
// build email
var elmNewContentCustomer = document.createElement('a');
var elmFoo = document.getElementById('section_form_id');
elmNewContentCustomer.href = 'mailto:me#example.com?subject=Something';
elmNewContentCustomer.setAttribute("style", "color:blue;");
elmNewContentCustomer.setAttribute("id", "email_customer_id");
elmNewContentCustomer.appendChild(document.createTextNode('Email Customer'));
elmFoo.parentNode.insertBefore(elmNewContentCustomer, elmFoo.nextSibling);
This works fine. However, I'd like to put the hyperlink inside a DIV so I set the style attributes of the DIV.
I tried using this method, which was to create a DIV, and insert it before the email block using appendChild but it doesn't work:
var elmNewEmailDev = document.createElement('div');
var elmFoo2 = document.getElementById('email_customer_id');
elmNewEmailDev.setAttribute("style", "background:yellow;");
elmNewEmailDev.appendChild(elmFoo.parentNode.insertBefore(elmNewContentCustomer, elmFoo.nextSibling));
elmFoo2.parentNode.insertBefore(elmNewEmailDev, elmFoo.elmFoo2);
How can I wrap a DIV around the hyperlink so I can then use setAttribute to be able to control the style of that DIV?
Follow this method your get result as you want.
var myEmailLink = "<a href='mailto:a#b.com'>a#b.com</a>";
var myDiv = document.getElementById("section_form_id");
myDiv.insertAdjacentHTML('afterEnd', myEmailLink )
<div id="section_form_id">
My Div Here
</div>

text/template inside js-file?

I want to move this code from my html-file to a js-file, is there any smooth way to do this without having to put the HTML-code as a string?
<script type="text/template" id="template_test">
<h4>Test</h4>
<p>blablabla</p>
</script>
Thanks!
You can use the createElement function to create HTML elements however if you intend to move alot of code you should consider using a templeting engine.
// Create the <h4> element
var heading = document.createElement("h4");
// add the text
heading.textContent = "TEST";
// Create the text node <p>
var p = document.createTextNode("blablabla");
//get the element to which you want to append the h4 and p
var container = document.getElementById("myID");
// Append h4 and p
container.appendChild(heading);
container.appendChild(p);

Setting an id on an element created from a template element

I have a template element that I use to create <li>-Elements on my page. I can set the textContent attributes of the inner elements of that template. However I can not set the id for the parent element inside the template.
<template id="list-item">
<li class="list-group-item">
<div class="media-body">
<strong class="list-item-text"></strong>
<p class="list-item-text"></p>
</div>
</li>
</template>
<div id="output"></div>
And this is the required js to demonstrate the issue.
var template = document.querySelector('#list-item');
var listItem = document.importNode(template.content, true);
var lines = listItem.querySelectorAll('.list-item-text');
lines[0].textContent = 'title';
lines[1].textContent = 'description';
listItem.id = 5;
document.querySelector('#output').appendChild(listItem);
Text contents will be set correctly, however the id won't be set at all (the js attribute gets created but it does not appear in the DOM.
I also created a jsfiddle for this.
How can I set the id of the newly appended element? My current approach is to avoid templates in general and use strings in order to construct the element, which makes me feel dirty.
The problem is that you are trying to handle a document-fragment (listItem) as an DOM element. Instead, you should first get/query the element from the document-fragment as follows:
var docFragment = document.importNode(template.content, true);
var listItem = docFragment.querySelector('li');
See working JSFiddle
Also, see documentation about DocumentFragment here.
You need to use listItem.querySelector() on the document-fragment and change the id then:
listItem.querySelector("li").id = 5;
var template = document.querySelector('#list-item');
var listItem = document.importNode(template.content, true);
var lines = listItem.querySelectorAll('.list-item-text');
lines[0].textContent = 'title';
lines[1].textContent = 'description';
listItem.querySelector("li").id = 5;
document.querySelector('#output').appendChild(listItem);

How to append content to querySelectorAll element with innerHTML/innerText?

I currently have my class element:
var frame_2 = document.querySelectorAll(".name");
Currently this div is empty. I now want to "append/add" some content to that div - I had a go with innerHTML + innerText but for some reason nothing seems to be added.
Example:
frame_2.innerHTML = '<img src="image.gif" />';
and
frame_2.innerText = 'some text';
Any suggestions? Im not sure if there are ways of doing the same - or performance'wise something better?
this gives you a list of elements that contain the class name
var name=document.querySelectorAll(".name");
you want the first element?
name[0].textContent='some text';
This gives you one single element, the first one.
var name=document.querySelector(".name");
name.textContent='some text';
To append stuff
name.appendChild(document.createTextNode('pizza'));
name.appendChild(document.createElement('div')).textContent='spaghetti';
name.appendChild(document.createElement('img')).src='cookie.jpg';
EDIT
To get the elements by classname, then retrieve the id :
var names=document.querySelectorAll(".name"),l;
while(l--){
console.log(names[l].id);
}
or if i didn't understand correctly
html
<div class="spaghetti" id="pizza"></div>
js
document.querySelector(".spaghetti#pizza")
EDIT2
html
<div id="container1"><div class="my-class"></div></div>
js
document.querySelector("#container1>.my-class")
Easier solution, any use case. Query your selector:
let find = document.querySelector('.selector');
create some html as a string
let html = `put your html here`;
create element from string
let div = document.createElement('div');
div.innerHTML = html;
Append new html you created to selector
find.appendChild(div);

navigating the dom javascript specific tag

Here it is DOM structure:
<div id="some">
NOTHIS
NOTHIS
<h3 class="myclass">HELLO</h3>
</div>
How can I get the value of HELLO in javascript?
EDIT: Forgot, I have other anchor tags inside 'some', so I want strictly the anchor tag inside the h3's
EDIT2: Got it:
var n = document.getElementById('some').getElementsByTagName('h3')[0].getElementsByTagName('a')[0].innerHTML;
Thanks all!
var linkText = document.getElementById('some').getElementsByTagName('a')[0].innerHTML;
or if you have jQuery
var linkText = $('#some').find('a').html();
var anchor = document.getElementById('some').getElementsByTagName('a')[0],
yourText = anchor.innerText || anchor.textContent;
It's cross-browser, too. http://www.quirksmode.org/dom/w3c_html.html
Propagate down the DOM from your ID.
var s = document.getElementById('some').getElementsByTagName('h3')[0].getElementsByTagName('a')[0].innerHTML;
I would put an ID on the a myself.
var shouldEqualHello = document.getElementById('some').getElementsByTagName('h3')[0].getElementsByTagName('a')[0].innerHTML;
edit: fixed
to get to a single dom element with javascript, you need a way to uniquely identify it. the ideal approach is to give your element a unique id.
<a id="myAnchor" href="#" style="color:red;">HELLO</a>
then you can directly obtain a reference in script.
var myAnchor = document.getElementById('myAnchor');
or if you are guaranteed that your element is the only anchor element within the "some" id you can do
var someDiv = document.getElementById('some');
var anchors = someDiv.getElementsByTagName('a'); // returns a list of anchor elements
var myAnchor = anchors[0]; // get the first element in the list
but since that's not the case you'll have to pick your way down through the dom some more.
var someDiv = document.getElementById('some');
var headers = someDiv.getElementsByTagName('h3');
var myH3 = headers[0];
var anchors = myH3 .getElementsByTagName('a'); // returns a list of anchor elements
var myAnchor = anchors[0]; // get the first element in the list
from there you can see the stuff between the tags with
alert(myAnchor.innerHTML);
or
alert(myAnchor.firstChild.nodeValue);
or some other method already mentioned here.
You could simply use query selector,
let result = document.querySelector('#some h3 a').innerText;
console.log(result);

Categories

Resources