Changing content of class using Javascript - javascript

I started reading JavaScript in W3schools and testing out/changing few things in the examples they give so I can see what is doing what but didn't manage to identify the syntax, yet.
Below is the original code to change p tag content, the link to it.
<p id="demo">
JavaScript can change the content of an HTML element.
</p>
<script>
function myFunction()
{
x = document.getElementById("demo"); // Find the element
x.innerHTML = "Hello JavaScript!"; // Change the content
}
</script>
<button type="button" onclick="myFunction()">Click Me!</button>
I want to know how to change contents with the same class, but failed as you can see that the example below doesn't work. Fiddle of code below.
<p class="demo">
JavaScript can change the content of an HTML element.
</p>
<p class="demo">Yolo</p>
<script>
function myFunction()
{
x = document.getElementsByClassName("demo"); // Find the element
x.innerHTML = "Hello JavaScript!"; // Change the content
}
</script>
<button type="button" onclick="myFunction()">Click Me!</button>
If you could show me how ^^" and help me understand, is "getElementById" a variable that could be anything else or is it a command?

Your x - is array of elements. try to use loop:
<body>
<p class="demo">JavaScript can change the content of an HTML element.</p>
<p class="demo">Yolo</p>
<button type="button" onclick="myFunction()">Click Me!</button>
<script>
function myFunction()
{
x=document.getElementsByClassName("demo"); // Find the elements
for(var i = 0; i < x.length; i++){
x[i].innerText="Hello JavaScript!"; // Change the content
}
}
</script>
</body>
See FIDDLE

Notice how when you use:
x=document.getElementsByClassName("demo");
It is Elements instead of Element. This is because it returns an array a HTMLCollection of all the elements with one particular class name. In order to combat this, you can choose the first element in the array:
x=document.getElementsByClassName("demo")[0];

It is easier to use jQuery with Javascript
See this example:
http://jsfiddle.net/37jq9/3/
If you use jquery instead of calling
x=document.getElementsByClassName("demo");
you can use
x = $('.demo');
but you can just call the function like this:
$(document).ready(function(){
$('button').click(function(){
$('.demo').text('Hello Javascript');
})
})

Related

Why is the childNodes count is greater than expected?

I have a question about DOM. Consider the following javascript code, the output will be 5.
<body>
<p>Hello</p>
<script>
function countBody() {
var childs = document.getElementsByTagName("body")[0].childNodes;
alert(childs.length);
}
window.onload = countBody;
</script>
</body>
Since I have two element nodes and two text nodes, what is the 5th node?
You have three text nodes.
Between the body start tag and the paragraph.
Between the paragraph and the script.
Between the script and the body end tag
… you could loop over childNodes and console.log() each value to see.
Just check it for yourself:
<body>
<p>Hello</p>
<script>
function countBody() {
var childs = document.getElementsByTagName("body")[0].childNodes;
console.log([].map.call(childs, function (node) { return node.textContent; }));
}
window.onload = countBody;
</script>
</body>
You have missed one text node in your counting. Please be aware that output from snippet will be different from code you have provided.

Show/Hide onClick button not working

Hey guys I have searched for many answers and none of them seem to be working so I am going to put my code here and hopefully you can help me figure this out.
I am going to have two buttons. The first button (show_Chappie) is going to show the hidden contents and another button (hide_Chappie) and hides it self when clicked.
The second button (hide_chappie) is going to hide the contents and bring back the first button (show_chappie). The hide_chappie button itself would also be hidden.
The information div is already hidden from the start. I did this on the CSS using the display:none;
Here's my HTML code so far:
<button class ="show_chappie" onclick="showInfo()">Show More</button>
<div class="info">Info here.</div>
<button class ="hide_chappie" onclick="hideInfo()">Show Less</button>
Here's my JavaScript code so far:
function showInfo(){
document.getElementById('chappie_info').style.display = "inline-block";
document.getElementById('show_chappie').style.display = "none";
document.getElementById('hide_chappie').style.display = "inline-block";
}
I haven't written the code for the hide_chappie button because I wanted to see this working first.
So where have I gone wrong here? Thanks for the help in advance.
You are trying to get the elements by id while they have a class, you should change the elements class to id like this:
<button id="show_chappie" onclick="showInfo()">Show More</button>
<div id="info">Info here.</div>
<button id="hide_chappie" onclick="hideInfo()">Show Less</button>
you should change your code to:
<button id ="show_chappie" onclick="showInfo()" >Show More</button>
<div class="info">Info here.</div>
<button id= "hide_chappie" onclick="showInfo()">Show Less</button>
if you want to use class here,you should change your Javascript Code to
function showInfo(){
document.getElementByClass('chappie_info')[0].style.display = "inline-block";
document.getElementByClass('show_chappie')[0].style.display = "none";
document.getElementByClass('hide_chappie')[0].style.display = "inline-block";
}
because function getElementsByClass returns a collection,so you should add [] to find out the result you want!
It's kind of annoying to turn all id's into classes, you can use:
function showInfo(){
document.getElementsByClassName('chappie_info').style.display = "inline-block";
document.getElementsByClassName('show_chappie').style.display = "none";
document.getElementsByClassName('hide_chappie').style.display = "inline-block";
}
This is supported by practically every browser these days so I wouldn't worry about that. If that is still an issue an you need to support ancient browsers, use this:
document.getElementsByClassName = function (a) {
var b = document.getElementsByTagName('*'), i, c=[];
for (i = 0; i < b.length; i += 1) { b[i].getAttribute('class')===a&&c.push(b[i]); }
return c;
};

change HTML tag name using Pure JS

<div id="demo"></div>
document.getElementsById("demo").onclick = function() {
this.tagName = "p";
};
// and then the output should be:
<p id="demo"></p>
I want to use pure javascript to change the tag name, could anyone help please?
With some snazzy dom Manipulation you can do this easely.
You simply need to make a new element, move over all the elements so you keep onclick handlers and such, and then replace the original thing.
function addClickEventToSpan() {
document.getElementById('whoa').addEventListener("click",function(){alert('WHOA WORLD! HELLO!');});
}
function transform(id){
var that = document.getElementById(id);
var p = document.createElement('p');
p.setAttribute('id',that.getAttribute('id'));
// move all elements in the other container.
// remember to use firstchild so you take all the childrens with you and maintain order.
// unles you like reversed order things.
while(that.firstChild) {
p.appendChild(that.firstChild);
}
that.parentNode.replaceChild(p,that);
}
p { background-color:green;color:white; }
div { background-color:blue;color:white; }
<div id="demo">Hello fantastical<span id="whoa" style="color:red">WORLD</span>
<UL>
<LI>something</LI>
</UL>
</div>
<input type="button" onclick="addClickEventToSpan('demo')" value="bind event handler(click WORLD)">
<input type="button" onclick="transform('demo')" value="transform">

Working with getElementById( x ).onclick = someFunction

I thought for long how to define the question but i couldn't, i need to explain the code.
I want to make a simple organizer in JavaScript. You enter the task and click on the button "add to the list" and a script makes a checkbox with paragraph that contains the task's text. The second part is the disabling the checkbox, and striking through that tasks text when you click on it. I tried to do that by giving every checkbox i create a function (destroyIt() that gets element by id and than disables it, but it works only for the last checkbox added to the page. I am looking at this code for long time and i can't see what is wrong. Please help. Here is my code:
<html>
<head>
<style id="stil">
.over{
text-decoration:line-through;
}
</style>
<script type="text/javascript">
var numberOfTasks=1;
function insertNew(){
tekst = document.getElementById("zadatak").value;
if(tekst.length>0){
var idEl= "check"+numberOfTasks;
document.getElementById("ispis").innerHTML+="<input type='checkbox' id='check"+numberOfTasks+"'> "+"<span class='"+idEl+"'>"+tekst+"</span> <br/>";
document.getElementById(idEl).onclick= function(){ destroyIt(idEl); };
numberOfTasks++;
}
}
function destroyIt(idEl){
document.getElementById(idEl).disabled=true;
document.getElementById("stil").innerHTML+= "."+idEl+"{text-decoration:line-through;}";
alert(idEl+"{text-decoration:line-through;}");
}
</script>
</head>
<body>
Tasks for: <span id="date"> </span>
<script>
var date= new Date();
document.getElementById("date").innerHTML= ""+ date.getDay() +"." +date.getMonth() +"." +date.getFullYear();
</script>
<br/> <br/>
New task: <input type="text" id="zadatak"> <button onclick="insertNew()"> add to the list </button>
<button onclick="provera()">Provera</button>
<p id="ispis"> </p>
</body>
The problem is that when you do .innerHTML += "...", it destroys the existing nodes and their event handlers, and replaces them with new, clean nodes. For this and other reasons, you should almost never use += after .innerHTML.
A better way to insert new content from HTML markup is to use .insertAdjacentHTML() instead. The first argument describes the position relative to the element on which it was invoked, and the second argument is the new content.
So your code with .insertAdjacentHTML() would look like this:
function insertNew(){
tekst = document.getElementById("zadatak").value;
if(tekst.length>0){
var idEl= "check"+numberOfTasks;
document.getElementById("ispis")
.insertAdjacentHTML("beforeEnd", "<input type='checkbox' id='check"+numberOfTasks+"'> "+"<span class='"+idEl+"'>"+tekst+"</span> <br/>");
document.getElementById(idEl).onclick= function(){ destroyIt(idEl); };
numberOfTasks++;
}
}
Furthermore, you can modify the destroyIt function to operate on its this value, which will give you the input element that has the handler. You can then use its .id to get the class of the span, or you can just traverse to the next element.
Also, you shouldn't modify the style sheet to hide the element. Just add a class or a direct style property.
So in the above function, this:
document.getElementById(idEl).onclick= function(){ destroyIt(idEl); };
becomes this:
document.getElementById(idEl).onclick= destroyIt;
And then the destroyIt function becomes this:
function destroyIt(){
var span = this.nextElementSibling;
this.disabled=true;
span.style.textDecoration = "line-through";
}
The .nextElementSibling will need to be patched in IE8, but this is just for simple demonstration.

JS get value of generated textnode

I have this Javascript in a for loop:
renderAElements[i] = document.createElement ("a");
renderAElements[i].setAttribute("href", "#");
renderAElements[i].setAttribute("class", "expander");
renderAElements[i].appendChild(expand);
alert (renderAElements[i].nodeValue);
where expand is created as:
var expand = document.createTextNode("+");
The alert, which is meant to return the link text of each created element returns null. Why is this?
Because you are trying to get the nodeValue of the Element node and not the Text node.
alert (renderAElements[i].firstChild.nodeValue);
It's because the a element contains another element and not a value. If you want to get the text out of the node you'll need to do either
renderAElements.childNodes[0].nodeValue
or
renderAElements.innerText
Check this out
<head>
<script type="text/javascript">
function GetTextNode () {
var textContainer = document.getElementById ("textContainer");
var textNode = textContainer.firstChild;
alert (textNode.data);
}
</script>
</head>
<body>
<div id="textContainer">This is a simple text in the container.</div>
<button onclick="GetTextNode ()">Get the contents of the container</button>
</body>
try this alert (renderAElements[i].firstChild.nodeValue);

Categories