Reverse the order of elements added to DOM with JavaScript - javascript

I am making a game in JavaScript, and need an event log. If i attack, it tells me if i hit or i miss. Here is my code:
function eventlogshow (text){
var para = document.createElement("p");
var node = document.createTextNode(text);
para.appendChild(node);
var element = document.getElementById("eventlog");
element.appendChild(para);
}
It lists the most recent event on the bottom, with the oldest on top. How do i reverse that?
I would like it to show the most recent event on the top.

Prepend the child element instead. Since there is no prependChild() function, you need to "insert it before the first child":
function eventlogshow (text){
var para = document.createElement("p");
var node = document.createTextNode(text);
para.appendChild(node);
var element = document.getElementById("eventlog");
element.insertBefore(para, element.firstChild);
}
A similar question has been asked here: How to set DOM element as first child?.
Read more about Node.firstChild and Node.insertBefore()

appendChild adds a node as a last child. You want to insert before the first node:
element.insertBefore(para, element.childNodes[0]);

Related

Javascript: Add same <li> to mulitple <ul> [duplicate]

I just notice I couldn't do
var d1 = document.createElement('div');
var d2 = document.createElement('div');
var p = document.createElement('p');
d1.appendChild(p); // d1 has p now
d2.appendChild(p); // d2 has p now
// but where is p in d1 ?
Some would say it's logic, but well, when I first noticed that I thought how uncool it was.
Why isn't that possible ?
The DOM is a tree structure.
When you append an element, you change its parent.
A node, in the browser, is much more than just the text inside your P (that string could be shared, in fact). It also has a position, dimensions, a visibility, receives events that could have been fired in child elements, propagate events to its parent, and so on. Everything here depends on the position in the tree. Just like would many CSS selectors. It doesn't make a lot of sense to imagine it's the same element at two places, it's better to think about it as two nodes, with maybe some identical content.
If you want to have the same content at two places, you have to clone it.
jQuery's appendTo() method inserts "every element in the set of matched elements to the end of the target". Try this:
p.appendTo(".div-class1, .div-class2")
for AppendChild same element multiple times , we can use this way :
//main function
function appendChildMultiple(parent) {
//check function argument is an element
if (parent.nodeType !== undefined) {
const pTag = document.createElement("p");
pTag.innerText = "This is the appended element";
//finally append child to parent
parent.appendChild(pTag);
}
}
and :
// target the wrapper and create test elements
const wrapper = document.querySelector(".wrapper");
const d1 = document.createElement("div");
const d2 = document.createElement("div");
//append test elements to wrapper
wrapper.appendChild(d1);
wrapper.appendChild(d2);
//use appendChildMultiple function
appendChildMultiple(d1);
appendChildMultiple(d2);
//we appended "pTag" multiple times
if we use Functions , we can AppendChild same element multiple times whitout cloneNode
https://codepen.io/kiumad/pen/eYMNKYa

Cannot replace nodes after using TreeWalker

I would like to replace the current text nodes with span nodes.
I have made this JS code but it does not work:
var EditorElement_Content;
var ContentElement_TreeWalker;
//
ContentElement_TreeWalker = document.createTreeWalker(EditorElement_Content, NodeFilter.SHOW_TEXT);
while (ContentElement_TreeWalker.nextNode()) {
var ReplacementNode = document.createElement("span");
ReplacementNode.appendChild(ContentElement_TreeWalker.currentNode);
ContentElement_TreeWalker.currentNode.parentNode.replaceChild(ReplacementNode, ContentElement_TreeWalker.currentNode);
}
Also, the Web explorer console returns this: HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy
What am I doing wrong and why?
Thanks in advance.

Why am I returned undefined?

I am wanting to get an attribute of the parent element that my cursor is inside of.
I have been totally unsuccessful for about two hours now, so I'm posting to see if anybody has any suggestions. This is the function I have but don't know why parentID only returns undefined:
function getAttrOfParent() {
var newRange = rangy.getSelection().getRangeAt(0);
var parentElement = newRange.commonAncestorContainer;
var parentID = $(parentElement).attr('id');
alert(parentID);
}
This works fine to get the text of the parent element...
function getTextOfParent() {
var newRange = rangy.getSelection().getRangeAt(0);
var parentElement = newRange.commonAncestorContainer;
var parentText = $(parentElement).text();
alert(parentText);
}
...and this works fine to get the title of a specified element.
function getAttrOfElement() {
var parentID = $('#1').attr('id');
alert(parentID);
}
Here's my jsFiddle, you have to click inside of the text area for the first two functions to work.
parentElement = newRange.commonAncestorContainer isn't giving you the parent element, it is giving you the parent node.
This is fairly obvious if you console.log(parentElement) to see what is being selected.
If you select text entirely inside one of your spans (which have ids) then you get the text node (which doesn't have an id).
If you select more text, you get the paragraph element node (which doesn't have an id).
You might want to try something like var parentElement = $(newRange.commonAncestorContainer).parents('span');

Style a substring in javascript

Hi i am trying to style a substring with javascript. Here's my code:
function runtest(){
document.getElementById("test1").innerHTML.substring(0,2).style.fontStyle="italic";
}
The substring function works but when I add the style the error console gives me an error of "undefined." How can I style this substring with javascript?
Two options:
An innerHTML solution. Warning: This will remove any event handlers on any elements within the element you're doing it on. I mention it here mostly so I can point that out:
var elm = document.getElementById("test1");
var html = elm.innerHTML;
elm.innerHTML = '<span style="font-style: italic">' + html.substring(0, 2) + '</span>' + html.substring(2);
Using splitText. Here I'm assuming the text you want to wrap in a span is the first text node within the element. This won't mess up event handlers on the elements:
var elm = document.getElementById("test1");
var node = elm.firstChild;
var span = document.createElement('span');
node.splitText(2);
span.style.fontStyle = "italic";
elm.insertBefore(span, node);
span.appendChild(node);
splitText creates two adjacent text nodes where there used to be one, with the split point being at the offset you specify. Then we take the first one and wrap it in a span.
Live Example | Live Source

"touch" a DOM element

Is there a handy way to "touch" a DOM element? I'd like to remove the element and insert it again at the same position. Something like this:
element.parentNode.removeChild(element).appendChild(element);
except that appendChild inserts the element as the last sibling.
Use insertBefore instead of appendChild.
var other = element.nextSibling;
if ( other ) {
other.parentNode.removeChild(element);
other.parentNode.insertBefore(element,other);
} else {
other = element.parentNode;
other.removeChild(element);
other.appendChild(element);
}
This creates a dummy text node to be used as a marker and replaces it with the node. Later when the node is to be re-inserted, replace it with the dummy node so the position is preserved.
Node.replaceChild
var dummy = document.createTextNode('');
var parent = element.parentNode;
parent.replaceChild(dummy, element); // replace with empty text node
parent.replaceChild(element, dummy); // swap out empty text node for original
Yes but it would be better to use the DOM cloneNode(true) as it would retain all of the child nodes and properties:
// Copy the node.
var theOldChild = document.getElementById("theParent").childNodes[blah]
var theNewChild = theOldChild.cloneNode(true);
// Find the next Sibling
var nextSib = theOldChild.nextSibling();
// Remove the old Node
theOldChild.parentNode.removeChild(theOldChild)
// Append where it was.
nextSib.parentNode.inserertBefore(theNewChild, nextSib);
That is the way that I would do it as you can hold onto the variable "theNewChild" 100% as it was and insert it back into the document at any time.

Categories