Javascript - Putting element in a var but can't change style - javascript

I have a function that is called when an element is clicked.
function showHide(elem){
var clickedText = elem.getElementsByTagName("p");
clickedText.style.color = "green";
}
When I run this code I get an Uncaught TypeError: Cannot set property 'color' of undefined. However, if I do console.log(clickedText) it logs the appropriate tag. Can't for the life of me figure out why this isn't working, have I missed something totally obvious?

The getElementsByTagName method returns a collection of elements (in a NodeList, which is like an array).
You will need to specify an index. For example:
clickedText[0].style.color = "green";
Currently, you're trying to access the style property of the NodeList itself, rather than an element contained within it.

getElementsByTagName returns a list of elements, so you need to loop through the results:
var clickedTexts = elem.getElementsByTagName("p");
for (var i = 0; i < clickedTexts.length; i++) {
clickedTexts[i].style.color = "green";
}

Related

Using querySelectorAll inside a for-in-loop

I'm feeling a little stupid to ask this because it should be so simple, but I'm getting pretty frustrated.
I have a few divs that I want to show only one at a time, so I want to hide the rest. My approach:
var elements = document.querySelectorAll("div");
for (i in elements) {
elements[i].style.setProperty("display", "none");
}
Firefox always says elements[i].style.setProperty(); is undefined.
I've made a workaround using a normal for-loop without using in, but I'd still like to know why this doesn't work.
Thanks in advance!
Replace
elements[i].style.setProperty("display", "none");
with
elements[i].style.display = "none";
As the HTMLElement.style property returns a CSSStyleDeclaration object that represents the element's inline styles as properties, i.e. style.property = 'value'
And use a regular for loop when iterating over array-like objects that has a length, like nodeLists
var elements = document.querySelectorAll("div");
for ( var i=0; i<elements.length; i++) {
elements[i].style.display = "none";
}

Why can't I make "onclick" event handler in my javascript code? [duplicate]

I am using getElementById when I need to clone the div element.
Code:
printHTML( document.getElementById("div_name").cloneNode(true));
Now I need to use getElementsByClassName
CloneNode is not working when using getElementsByClassName.
How can I put class name in here?
Thank's
EDIT:
When I try to use this:
printHTML( $('.dataTables_scroll').clone(true) );
You can see my function:
function printHTML(clonedDive){
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
iframe.contentWindow.onunload = function(){
$(".DTTT_container").show("fast");
$("#header_outer").show("fast");
$(".ColVis.TableTools").show("fast");
$("#footer").show("fast");
};
iframe.contentWindow.document.body.appendChild(clonedDive);
iframe.contentWindow.print();
document.body.removeChild(iframe);
}
I am getting an error in this line:
iframe.contentWindow.document.body.appendChild(clonedDive);
This is an error description:
Uncaught Error: NOT_FOUND_ERR: DOM Exception 8
getElementsByClassName gets a nodelist, or an array-like object containing elements if you will, as there can be more than one element with the same class.
getElementsByClassName does this even if only one element matches the class.
You can generally recognize methods like that be the s in getElements, which means it gets multiple elements, i.e. a nodeList.
getElementById only gets one element as ID's are unique.
To get the first element in the nodelist, use bracket notation, like so:
document.getElementsByClassName("div_name")[0].cloneNode(true);
or one could use querySelector, which gets the first matching element only
document.querySelector(".div_name").cloneNode(true);
The jQuery solution would be:
$('.div_name').clone(true);
and to iterate over elements with a certain classname you'd use a loop
var elems = document.getElementsByClassName("div_name");
for ( var i=0; i<elems.length; i++ ) {
printHTML( elems[i].cloneNode(true) );
}
Due to getElementsByClassName returns an object's array, so you have to use for loop to iterates among them, as follows:
for (i = 0; i < document.getElementsByClassName("div_name").length; i++){
printHTML( document.getElementsByClassName("div_name")[i].cloneNode(true));
}
otherwise, if you know the index of the element you have let we say 1
printHTML( document.getElementsByClassName("div_name")[1].cloneNode(true));
This does not work? :
printHTML( document.getElementsByClassName("class_name")[0].cloneNode(true));
You can loop through the elements and clone one by one...
var e = document.getElementsByClassName('div');
for (var i = 0; i < e.length; i += 1) {
// Clone e[i] here
console.log(e[i].cloneNode(true));
}

element.classlist not working in client side

I am new to javascript. When i headed with the javascript events i have seen about element.classList.So i have tried out some code to understand how it works ..
The code i have done
var n = document.getElementsByClassName('name');
var c = n.classList.add('name');
console.log(c);
it gives me error like Uncaught TypeError: Cannot read property 'add' of undefined.
Can anyone point me where am going wrong ??
getElementsByClassName returns a NodeList (which is like an Array). Note that "Elements" is plural.
classList is a property of an Element (singular)
You need to loop over the Elements in the NodeList and access the classList property of each one in turn.
for (var i = 0; i < n.length; i++) {
console.log( n[i].classList.add('name') );
}

Can't set styles to elements with a specified class javascript

This is my javascript code:
document.getElementsByClassName('loader').style.opacity = "0";
this code will give an error in my console displayed below:
TypeError: 'undefined' is not an object (evaluating 'document.getElementsByClassName('loader').style.opacity = "0"')
I have already tried these, but these also do not work:
document.document.querySelectorAll('.loader').style.opacity = '0';
document.document.querySelector('.loader').style.opacity = '0';
My html code:
<div class="loader">Some Text</div>
The .getElementsByClassName() function returns a list of elements. You have to iterate over that list with your own code.
var loaders = document.getElementsByClassName('loader');
for (var i = 0; i < loaders.length; ++i)
loaders[i].style.opacity = '0';
If you just want to operate on particular members of the list, you can (if you're careful) treat it like an array. I mention being careful because .getElementsByClassName() returns a "live" NodeList. If you remove the class "loader" from one or more of the elements, the list will change. (That's not the case for the lists returned from .querySelectorAll().)
If you select elements by classes you most will most likely end up with an array of elements. You need to set the parameters for each one. Pure JS doesn't behave as jQuery regarding this.
First make your selection by
var elements = document.getElementsByClassName('loader');
then cycle through them
for(var i=0; i<elements.length; i++){
elements[i].style.opacity = "0";
}
See if this helps..

Javascript Getting specific element (of parent) by name

I'm using custom tags to define sections in an application, so I have something like this:
<mysection>
<form>
<input name="myfield">
</form>
</mysection>
I'm using the following and able to get the tag (printed to console, everything is groovy)
var parent = document.getElementsByTagName('mysection');
The issue I'm having is finding the child field by name:
var myfield = parent.getElementsByName("myfield");
...as I don't want to pick up on any other 'sections' that might have an input with the name 'myfield'.
EDIT:
var parent = document.getElementsByTagName('mysection')[0];
was suggested and returns to console the section contents, however, getElementsByName throws an error:
Uncaught TypeError: Object #<NodeList> has no method 'getElementsByName'
Using getElementsByTagName() and getElementsByName() will return a NodeList, you need to get the first element of the list like this:
var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.getElementsByName("myfield")[0];
Edit
You were correct, getElementsByName is not valid for an element. I am unsure how to localize the functionality of it as you are trying to do. It seems that it will only work for document. You may have to write your own implementation of getElementsByName if you want to use it in a localized scope.
Second Edit
To be nice, I made that implementation for you :D Here it is in all its "glory".
Element.prototype.getElementsByName = function (arg) {
var returnList = [];
(function BuildReturn(startPoint) {
for (var child in startPoint) {
if (startPoint[child].nodeType != 1) continue; //not an element
if (startPoint[child].getAttribute("name") == arg) returnList.push(startPoint[child]);
if (startPoint[child].childNodes.length > 0) {
BuildReturn(startPoint[child].childNodes);
}
}
})(this.childNodes);
return returnList;
};
var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.getElementsByName("myfield")[0];
Small fix
I was incorrectly passing the element and not its children into the recursion. The code above has been edited with the proper argument passed now. See working fiddle: http://jsfiddle.net/js6NP/5/
I actually found a much more simple way to handle this:
document.querySelectorAll('mysection [name="myfield"]');
Here you can see an example where it only modifies the field inside the section specified: http://jsfiddle.net/fluidbyte/kph6H/
qSA supports modern browsers and is compatible down to IE8, Here's a polyfill to support back to IE7: https://gist.github.com/2724353
getElementsByName won't work on a DOM element reference. Use querySelector or querySelectorAll instead. In example:
var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.querySelector("[name='myfield']");
Just use an ID instead:
<mysection>
<form>
<input name="myfield" id="fieldName">
</form>
</mysection>
var myfield = document.getElementById("fieldName");
ID's are supposed to be unique on a page. So you shouldn't have trouble accessing the right element.
If you really have to use name/tagname, getElementsByTagName and getElementsByName both always return a array (A empty one if no element was found). you can access the right element, just like you'd access elements in arrays:
document.getElementsByTagName('mysection')[0]; For the first element with tagname mysection.

Categories