Unable to attach event to an element in contextual fragment - javascript

I tried to attach an event to an element in a contextual fragment and then appended this element to body. But the event doesn't get attached.
var range = document.createRange();
var listE1 = "<div>Hello World</div>"
range.selectNode(document.getElementsByTagName("div").item(0));
var element = range.createContextualFragment(listEl);
element.querySelector("div").addEventListener("click", function () {
alert("hello");
}, true);
document.body.appendChild(element);
After appending this element to body, the div doesn't have any event at all

I stumbled upon here after looking for the same answer and I know this is a very old question hope this helps or points to a better direction.
The range.createContextualFragment(listEl); returns a DocumentFragment. In a nutshell a DocumentFragment is minimalized DOM object. It doesn't have an attachEventListener.
If you want you can either use DOMParser or use document.createElement
Here's an example of how you can use DOMParser
let listE1 = "<div>Hello World</div>"
let element = new DOMParser().parseFromString(listE1 , 'text/html').documentElement;
element.addEventListener("click", function () {
alert("hello");
}, true);
document.body.appendChild(element);
Hope this helps.

only a lot of little mistake, the code should run right easy:
we should add the fragment to document, then add the event listener
var range = document.createRange();
var listE1 = "<div id='hello'>Hello World</div>"
range.selectNode(document.getElementsByTagName("div").item(0));
var element = range.createContextualFragment(listE1); // listel -> liste1
document.body.appendChild(element); // should add to document first
document.querySelector("div#hello").addEventListener("click", function() { // element->document
alert("hello");
}, true);

Related

What are the equivalent of after and before jQuery's function in native javascript?

I always used jQuery before, but I want to switch the following to native javascript for better performance of the website.
var first = $('ul li:first');
var first = $('ul li:last');
$(last).before(first);
$(first).after(last);
From: http://clubmate.fi/append-and-prepend-elements-with-pure-javascript/
Before (prepend):
var el = document.getElementById('thingy'),
elChild = document.createElement('div');
elChild.innerHTML = 'Content';
// Prepend it
el.insertBefore(elChild, el.firstChild);
After (append):
// Grab an element
var el = document.getElementById('thingy'),
// Make a new div
elChild = document.createElement('div');
// Give the new div some content
elChild.innerHTML = 'Content';
// Jug it into the parent element
el.appendChild(elChild);
To get the first and last li:
var lis = document.getElementById("id-of-ul").getElementsByTagName("li"),
first = lis[0],
last = lis[lis.length -1];
if your ul doesn't have an id, you can always use getElementsByTagName("ul") and figure out its index but I would advise adding an id
I guess you are looking for:
Element.insertAdjacentHTML(position, text);
Where position is:
'beforebegin'.
Before the element itself.
'afterbegin'.
Just inside the element, before its first child.
'beforeend'.
Just inside the element, after its last child.
'afterend'.
After the element itself.
And text is a HTML string.
Doc # MDN
You can use insertBefore():
var node = document.getElementById('id');
node.parentNode.insertBefore('something', node);
Documentation: insertBefore()
There is no insertAfter method. It can be emulated by combining the insertBefore method with nextSibling():
node.parentNode.insertBefore('something', node.nextSibling);

How to add a function on an element that was made after DOM creation?

I have a function that creates an html element with an unique ID.
And after that I want that when I click this element I could call a new function.
Quick example:
1) I click a button "Create element";
2) An element is created with id of "New_Element";
3) I click the "New_Element";
4) I get a function that was already preset to this element.
My current code for creating an element.
var pageRows = document.getElementsByClassName('pageRows');
var pageRowID = "section";
var el = document.createElement('section');
el.setAttribute('id', pageRowID + pageRows.length);
var row = document.getElementById('allNewRows');
row.parentNode.appendChild(el);
el.innerText = "New " + pageRows.length + " ROW!";
Now that the Element of id "pageRowId0" is created I want to have a function that works when I click this element.
Best wishes.
Thanks for helping.
You can do element.onclick= function(){}
var pageRows = document.getElementsByClassName('pageRows');
var pageRowID = "section";
var el = document.createElement('section');
el.setAttribute('id', pageRowID + pageRows.length);
el.onclick = function(){
/*write your fn here*/
};
var row = document.getElementById('allNewRows');
row.parentNode.appendChild(el);
el.innerText = "New " + pageRows.length + " ROW!";
You can use event delegation:
var row = document.getElementById('allNewRows');
row.parentNode.onclick = function(e) {
if (e.target.nodeName.toLowerCase() == 'select') {
//click on target select element
}
};
The snippet below has two parts. The first piece of code allows you to add a bunch of elements with different texts to the document.
The second parts shows the text of the element you clicked.
You will notice that the click event handler is just assigned to the parent element in which the new elements are added. No explicit click event handlers are bound to the new element.
I like to use addEventListener, because I think it's better to add a listener for a specific goal than to override any other event listeners by bluntly setting 'onclick', but that's a matter of opinion.
// Only run this code when the DOM is loaded, so we can be sure the proper elements exist.
window.addEventListener('DOMContentLoaded', function(){
// The code to add an element when the add button was clicked.
document.getElementById('add').addEventListener('click', function() {
var element = document.createElement('div');
element.innerText = document.getElementById('text').value;
element.className = 'clickableElement';
document.getElementById('elements').appendChild(element);
});
// Click event handler for the 'elements' div and everything in it.
document.getElementById('elements').addEventListener('click', function(event) {
var target = event.target; // The element that was clicked
// Check if the clicked element is indeed the right one.
if (target.classList.contains('clickableElement')) {
alert(target.innerText);
}
});
})
<input id="text" value="test"><button id="add">add</button>
<div id="elements"></div>

jquery after method not returning generated element

In the following code:
var genContent = "<tr><td>please wait!!!</td></tr>";
var outputElement = $("#projectsTable tr:first").after(genContent);
myForm = $(this).find("form");
submitForm(myForm, outputElement);
I expect outputElement to be the element generated by the after method from jquery, but for some reason outputElement is refering to the table headers.
What do I need to do to get the newly generated element?
You need to use .insertAfter() if you want outputElement to refer to the tr element
var = "<tr><td>please wait!!!</td></tr>";
var outputElement = $(genContent).insertAfter("#projectsTable tr:first");
myForm = $(this).find("form");
submitForm(myForm, outputElement);
The after method inserts element(s) after the current selection, and returns that same current selection. So it does not change the selection. If you need the elements that you want to insert, maybe create a jQuery object of it, and insert that.
var genContent = "<tr><td>please wait!!!</td></tr>";
var outputElement = $(genContent);
$("#projectsTable tr:first").after(outputElement);

Appending an element inside the child of another element

I am trying to append a link ("a" tag) to a child of the "topBar" element.
Here is what i've got so far:
document.getElementById('topBar').innerHTML += 'Cookie Clicker Classic';
This puts the link inside the "topBar" element as a new child, but I want it inside the existing child of the "topBar" element. How do I do this? The child is just within a div tag, it has no id... I have done some reasearch on .appendChild but I haven't found any related help, thus why I am asking here...
I would be very appreciative for any ideas or even a solution to be posted.
Thanks,
Daniel
EDIT: topBar has only one child, it is nameless
also, am I doing something wrong with this?
setTimeout(doSomething, 1000);
function doSomething() {
var element = document.getElementById('particles');
if (typeof(element) != 'undefined' && element != null)
{
var newLink = document.createElement('a');
newLink.setAttribute('href', 'http://orteil.dashnet.org/experiments/cookie/');
newLink.target = 'blank';
document.getElementById('topBar').appendChild(newLink);
var del = document.getElementById('links')
del.parentNode.removeChild(del);
return;
} else {
setTimeout(doSomething, 1000);
}
}
EDIT: I have finished! Thanks to everyone for their help, especially Elias Van Ootegem. This is what I used:
var link=document.createElement('a');
link.setAttribute('href', 'http://orteil.dashnet.org/experiments/cookie/');
link.target = 'blank';
link.appendChild(
document.createTextNode('Cookie Clicker Classic')
);
var add = document.getElementsByTagName('div')[1]; //this picked the second div tag in the whole document
if(add.lastChild) add.insertBefore(link,add.lastChild); //appending it to the end of the child
else add.prependChild(link);
First, create the node:
var newLink = document.createElement('a');
//set attributes
newLink.setAttribute('href', 'http://orteil.dashnet.org/experiments/cookie/');
newLink.target = 'blank';//preferred way is using setAttribute, though
//add inner text to link:
newLink.appendChild(
document.createTextNode('Cookie Clicker Classic')//standard way, not innerHTML
);
Then, append the child, using appendChild:
document.getElementById('topBar').appendChild(newLink);
Or, given your update (your deleting some other element), use replaceChild:
document.getElementById('topBar').replaceChild(
newLink,//new
document.getElementById('links')//old, will be removed
);
And you're there!

How to get the HTML for a DOM element in javascript

Imagine I have the following HTML:
<div><span><b>This is in bold</b></span></div>
I want to get the HTML for the div, including the div itself. Element.innerHTML only returns:
<span>...</span>
Any ideas? Thanks
Use outerHTML:
var el = document.getElementById( 'foo' );
alert( el.outerHTML );
Expanding on jldupont's answer, you could create a wrapping element on the fly:
var target = document.getElementById('myElement');
var wrap = document.createElement('div');
wrap.appendChild(target.cloneNode(true));
alert(wrap.innerHTML);
I am cloning the element to avoid having to remove and reinsert the element in the actual document. This might be expensive if the element you wish to print has a very large tree below it, though.
First, put on element that wraps the div in question, put an id attribute on the element and then use getElementById on it: once you've got the lement, just do 'e.innerHTML` to retrieve the HTML.
<div><span><b>This is in bold</b></span></div>
=>
<div id="wrap"><div><span><b>This is in bold</b></span></div></div>
and then:
var e=document.getElementById("wrap");
var content=e.innerHTML;
Note that outerHTML is not cross-browser compatible.
old question but for newcomers that come around :
document.querySelector('div').outerHTML
You'll want something like this for it to be cross browser.
function OuterHTML(element) {
var container = document.createElement("div");
container.appendChild(element.cloneNode(true));
return container.innerHTML;
}
If you want a lighter footprint, but a longer script, get the elements innerHTML and only create and clone the empty parent-
function getHTML(who,lines){
if(!who || !who.tagName) return '';
var txt, ax, str, el= document.createElement('div');
el.appendChild(who.cloneNode(false));
txt= el.innerHTML;
ax= txt.indexOf('>')+1;
str= txt.substring(0, ax)+who.innerHTML+ txt.substring(ax);
el= null;
return lines? str.replace(/> *</g,'>\n<'): str;
//easier to read if elements are separated
}
var x = $('#container').get(0).outerHTML;
as outerHTML is IE only, use this function:
function getOuterHtml(node) {
var parent = node.parentNode;
var element = document.createElement(parent.tagName);
element.appendChild(node);
var html = element.innerHTML;
parent.appendChild(node);
return html;
}
creates a bogus empty element of the type parent and uses innerHTML on it and then reattaches the element back into the normal dom
define function outerHTML based on support for element.outerHTML:
var temp_container = document.createElement("div"); // empty div not added to DOM
if (temp_container.outerHTML){
var outerHTML = function(el){return el.outerHTML||el.nodeValue} // e.g. textnodes do not have outerHTML
} else { // when .outerHTML is not supported
var outerHTML = function(el){
var clone = el.cloneNode(true);
temp_container.appendChild(clone);
outerhtml = temp_container.innerHTML;
temp_container.removeChild(clone);
return outerhtml;
};
};
var el = document.getElementById('foo');
el.parentNode.innerHTML;

Categories