Appending new paragraphs - javascript

Been stuck on this for a while now, trying to add multiple new p elements to a div but it is just adding the content to the first one instead of creating a new one.
var p = document.createElement("p");
var output = document.getElementById('output');
function on button press
p.appendChild(document.createTextNode("hello"+"\n"));
output.appendChild(p);
Thanks for any help in advance, I need a solution where i'm allowed an infinite amount of new paragraphs until a condition is met.

The problem is that you create only one paragraph but append multiple text nodes in it. Despite on how it looks, output.appendChild(p) doesn't append initial p more then once. In fact, if the element is already in DOM (like in your case afther the first click), appendChild simply moves element to a new location. But in your case new location is the same as the original. So as the result, you only create new text node with every click.
You need to create new HTMLParagraphElement on every click:
document.querySelector('button').onclick = function() {
var p = document.createElement("p");
var output = document.getElementById('output');
p.appendChild(document.createTextNode("hello"+"\n"));
output.appendChild(p);
};
<button>Click</button>
<div id="output"></div>

Related

Document.createElement() vs Document.createTextNode() - Javascript

I'm trying to figure out what is the differences between this two:
// first one
var h1 = document.createElement('h1');
var t = document.createTextNode('hey');
h1.appendChild(t);
document.body.appendChild(h1);
// second one
document.body.appendChild(document.createElement('h1').appendChild(document.createTextNode('hey')));
The first (Document.createElement()) works perfectly, but the second (Document.createTextNode()) does not.
The return value of appendChild is the appended child.
So if we add variables to:
document.body.appendChild(document.createElement('h1').appendChild(document.createTextNode('hey')));
it gets broken down into:
var text = document.createTextNode('hey');
var h1 = document.createElement('h1');
h1.appendChild(text);
document.body.appendChild(text);
Appending the text to the body removes the text from the h1.
The h1 is discarded because it is never appended anywhere.
I find a way to do it: (just add .parentNode at the end)
document.body.appendChild(document.createElement('h1').appendChild(document.createTextNode('hey')).parentNode);

Document Create Full Element

I'm making a little app, which has to append 3 elements to another element, by using this code:
var MyElem1= document.createElement("div");
ParentElem.appendChild(MyElem1);
This works just fine, but i was wondering if there is a way to create a full element, like this for example:
var MyElem1= document.createElement('<div style="some-styling: here;">Some InnerHtml Here</div>');
ParentElem.appendChild(MyElem1);
I know i can add those properties to the element after i create it, but i'm hopping there's a way to do it inline like that (Something that works cross-browser).
I saw on W3Schools (yes i know i should stop using it) the createElement function requires only the element type (div, span, button, etc...).
You could create a dummy container and create all elements you want inside it by replacing its innerHTML property, and then getting the .firstChild.
Here is a reusable function for it
var elementFactory = (function (){
var dummy = document.createElement('div');
return function(outerHtml){
var node;
dummy.innerHTML = outerHtml;
node = dummy.firstChild;
dummy.removeChild(node);
return node;
}
})();
and use it like this
var MyElem1 = elementFactory('<div style="some-styling: here;">Some InnerHtml Here</div>'),
MyElem2 = elementFactory('<div style="some-other-styling: here;">Some Other InnerHtml Here</div>');
Demo at http://jsfiddle.net/5De3p/1/

Adding larger content to div dynamically

I am using a div that is shown when I hover over an image. I want to use this div to display image info. How can I add a few lines of content to the div? The only sollution I found is innerHTML property of the div, but this means I have to use this for aech value I want to put on a div. Is there a way I can put more content on a div with a single command. I want to achieve this using javascript or dojo.
every time you use innerHTML the screen has to reflow/repaint. better pattern is to create a document fragment and update it "offline" before make the info "live":
var p, t, frag;
divInf = document.createElement('div');
frag = document.createDocumentFragment();
p = document.createElement('p');
t = document.createTextNode('first line');
p.appendChild(t);
frag.appendChild(p);
p = document.createElement('p');
t = document.createTextNode('second line');
p.appendChild(t);
frag.appendChild(p);
divInf.appendChild(frag);

Change some look for html on basis of selection of text

In my app there is an html file showed in a webview. I have a note functionality where when user selects text, it is highlighted and an image is added as suffix. This note is then saved as an html file.
So for this functionality, I have written a java script function.
function highlightsText()
{
var range = window.getSelection().getRangeAt(0);
var selectionContents = range.extractContents();
var newDate = new Date;
var randomnumber= newDate.getTime();
var div;
var imageTag = document.createElement("img");
imageTag.id=randomnumber;
imageTag.setAttribute("src","notes.png");
var linkTxt = document.createElement("a");
linkTxt.id=randomnumber;
linkTxt.setAttribute("href","highlight:"+randomnumber);
linkTxt.appendChild(selectionContents)
div = document.createElement("span");
div.style.backgroundColor = "yellow";
div.id=randomnumber;
linkTxt.appendChild(imageTag);
div.appendChild(linkTxt);
range.insertNode(div);
return document.body.innerHTML+"<noteseparator>"+randomnumber+"<noteseparator>"+range.toString();
}
Here I am making a span and this span holds my highlighted text with image.
Now problem is,
When I am selecting a paragraph, it only adds an image and does not highlight the text.
If I use div or p tag in place of span then it gives an entire line for a single word which looks rather odd.
Edit: div tags will get a linebreak before and after (usually, most browsers do this, considering it is a "division"/block level element), you're better off using a span.
And secondly you should append the selection contents to the span
ispain.appendChild(selectionContents) !! and do not forget the semicolon ;)
on a side note, you do know that:
1- you can't have html element ids starting with digits.
2- having more than one elements with the same id is gonna get unpredictable when you're selecting em.

JS: innerHTML and DOM aren't cooperating

I've noticed a funny behavior and was wondering if anybody could shed some light on the reason.
It breaks down like this:
I've added a div and a button using Javascript's `appendChild'.
I add an onclick handler to the button, works fine
I add-assign the innerHTML of the div to add some more content
Button onclick stops working altogether
Here's a sample script:
var D = document.createElement("DIV"), B = document.createElement("BUTTON");
B.innerHTML = "Is it true?";
document.body.appendChild(D);
D.appendChild(B);
B.onclick = function() { alert("Elvis Lives!"); }
At this point, it works fine. Then, add this line:...
D.innerHTML += "What about Tupac?";
...and the button breaks. So, I'm just using appendChild for all elements now.
But -
Why is this happening ("seems like it should work :) ")
Is there a fix (besides appending all my extra elements)?
(this is a lot of educated guessing) I think when you modify D's innerHTML, the dom within D is destroyed and created from the new value. So when the new contents are constructed, you are getting a brand new button, which is not the same node as B. since you set the onclick handler via js and not by an attribute on the original element, the new button does not have that function reference. however B still works as can be demonstrated by calling
B.click();
after you append to innerHTML.
to prevent the thrashing of the dom within D, you can do this instead of using innerHTML:
D.appendChild(document.createTextNode("What about Tupac?"));
innerHTML is a shortcut for creating DOM elements. When you append something to the outer div using innerHTML, this is what happens:
D.innerHTML += "What about Tupac?";
which is the same as,
D.innerHTML = D.innerHTML + "What about Tupac?";
which is the same as,
D.innerHTML = "<button>Is it true?</button>" + "What about Tupac?";
which finally becomes this,
D.innerHTML = "<button>Is it true?</button>What about Tupac?";
Now in the last step, we completely replaced the existing contents of the div, with a new string which contains HTML. As far as the DOM is concerned, it doesn't care whether a user typed the HTML by hand, or it came from calling innerHTML on a DOM node. All it cares about is, is that it has a string of HTML, which must be converted to a DOM. A new button element is created at this time, which is why the onclick stops working - it's not the same element anymore.
Not an answer, just a test page - looks very strange - I can confirm your findings
<script>
window.onload=function() {
var D = document.createElement("DIV"), B = document.createElement("BUTTON");
D.id = "div1"
B.innerHTML = "Is it true?";
B.onclick = function() { alert("Elvis Lives!"); }
D.appendChild(B);
document.body.appendChild(D);
}
</script>
Click<br>
Test
update: Lessons learned - be consistent.
This works as expected
<script>
window.onload=function() {
var D = document.createElement("DIV");
D.id = "div1"
D.innerHTML = '<button onclick="alert(\'Elvis Lives!\')">Elvis</button>'
document.body.appendChild(D);
}
</script>
Click<br>

Categories

Resources