I have multiple div elements with same id='mydiv'.I want to calculate these divs and Iam using the code
document.getElementById('mydiv').length
But it is not working
What you should do is use class instead of ID's. ID is for one element only, class is for multiple.
http://jsfiddle.net/d7AHV/
It won't work as getElementById will always return an element with the specified ID and null if the specified ID doesn't exist
From ECMA
getElementById(elementId) This method returns a Element. The elementId
parameter is of type DOMString.
What you can do is to assign each div with class
<div class="mydiv"></div>
<div class="mydiv"></div>
<div class="mydiv"></div>
<div class="mydiv"></div>
<div class="mydiv"></div>
And iterate over:
var divs = document.getElementsByTagName('div');
var count = 0;
for(var i = 0; i < divs.length; i++) {
if(divs[i].className == 'mydiv') count++;
}
alert(count);
If your clients support document.getElementsByClassName(), it's even more concise:
alert(document.getElementsByClassName('mydiv').length)
You've been told about multiple elements with the same ID, but in rare cases it might be unavoidable (e.g. an XML document over which you have no control). The only adverse behaviour is that selecting by ID will usually only return the first one (but that's not guaranteed).
You can count elements with the same id by looping over all the elements in the document and counting the ones with a matching id, e.g.
function countSameIds(id) {
var allNodes = document.getElementsByTagName('*');
for (var i=allNodes.length, count=0; i; ) {
if (allNodes[--i].id == id) {
++count;
}
}
return count;
}
Related
I've got following HTML:
<span class="testClass1" >
wanted Text
<a class="ctx" href="#"></a>
</span>
Now I want to get the text "wanted Text".
How can I achieve this?
I tried with:
document.getElementsByClassName("testClass1");
I also tried with document.getElementsByTagName() but I don't know how to use them properly.
You can use querySelectorAll
hence:
document.querySelectorAll('.testclass1 a')
will return all the <a> items children of a .testclass1
Snippet example:
var elements = document.querySelectorAll('.testClass1 a')
console.log(elements) // open the console to see this
console.log(elements[0].text) // this gets the first <a> text `wanted Text`
<span class="testClass1" >
wanted Text
<a class="ctx" href="#"></a>
</span>
The getElementsByClassName() function returns an array of matching elements, so if you need to access them, you could do so using a loop :
// Get each of the elements that have the class "testClass1"
var elements = document.getElementsByClassName("testClass1");
// Iterate through each element that was found
for(var e = 0; e < elements.length; e++){
// Get the inner content via the innerHTML property
var content = elements[e].innerHTML;
}
If you need to actually access the <a> tags directly below some of the elements as your edit indicates, then you could potentially search for those wihtin each of your existing elements using the getElementsbyTagName() function :
// Get each of the elements that have the class "testClass1"
var elements = document.getElementsByClassName("testClass1");
// Iterate through each element that was found
for(var e = 0; e < elements.length; e++){
// Find the <a> elements below this element
var aElements = elements[e].getElementsByTagName('a');
// Iterate through them
for(var a = 0; a < aElements.length; a++){
// Access your element content through aElements[a].innerHTML here
}
}
You can also use an approach like squint's comment or Fred's which take advantage of the querySelectorAll() function as the getElementsByClassName() and getElementsByTagName() are better served when accessing multiple elements instead of one specifically.
Try this:
document.getElementsByClassName("testClass1")[0].getElementsByTagName('a')[0].innerText
var testClass1 = document.getElementsByClassName("testClass1");
console.log(testClass1[0].innerHTML);
I'm trying to only show certain divs. The way I have decided to do this is to first hide all elements that start with "page" and then only show the correct divs. Here's my (simplified) code:
<form>
<input type="text" onfocus="showfields(1);">
<input type="text" onfocus="showfields(2);">
</form>
<div class="page1 row">Some content</div>
<div class="page1 row">Some content</div>
<div class="page2 row">Some content</div>
<div class="page2 row">Some content</div>
<script>
function showfields(page){
//hide all items that have a class starting with page*
var patt1 = /^page/;
var items = document.getElementsByClassName(patt1);
console.log(items);
for(var i = 0; i < items.length; i++){
items[i].style.display = "none";
}
//now show all items that have class 'page'+page
var item = document.getElementsByClassName('page' + page);
item.style.display = '';
}
</script>
When I console.log(items); I get a blank array. I'm pretty sure the regexp is right (get all items starting with 'page').
The code I'm using is old school JS, but I'm not adverse to using jQuery. Also if there is a solution that doesn't use regexp, that's fine too as I'm new to using regexp's.
getElementsByClassName only matches on classes, not bits of classes. You can't pass a regular expression to it (well, you can, but it will be type converted to a string, which is unhelpful).
The best approach is to use multiple classes…
<div class="page page1">
i.e. This div is a page, it is also a page1.
Then you can simply document.getElementsByClassName('page').
Failing that, you can look to querySelector and a substring matching attribute selector:
document.querySelectorAll("[class^=page]")
… but that will only work if pageSomething is the first listed class name in the class attribute.
document.querySelectorAll("[class*=page]")
… but that will match class attributes which mention "page" and not just those with classes which start with "page" (i.e. it will match class="not-page".
That said, you could use the last approach and then loop over .classList to confirm if the element should match.
var potentials = document.querySelectorAll("[class*=page]");
console.log(potentials.length);
elementLoop:
for (var i = 0; i < potentials.length; i++) {
var potential = potentials[i];
console.log(potential);
classLoop:
for (var j = 0; j < potential.classList.length; j++) {
if (potential.classList[j].match(/^page/)) {
console.log("yes");
potential.style.background = "green";
continue elementLoop;
}
}
console.log("no");
potential.style.background = "red";
}
<div class="page">Yes</div>
<div class="notpage">No</div>
<div class="some page">Yes</div>
<div class="pageXXX">Yes</div>
<div class="page1">Yes</div>
<div class="some">Unmatched entirely</div>
Previous answers contain parts of the correct one, but none really gives it.
To do this, you need to combine two selectors in a single query, using the comma , separator.
The first part would be [class^="page"], which will find all the elements whose class attribute begins with page, this selector is thus not viable for elements with multiple classes, but this can be fixed by [class*=" page"] which will find all the elements whose class attribute have somewhere the string " page" (note the space at the beginning).
By combining both selectors, we have our classStartsWith selector:
document.querySelectorAll('[class^="page"],[class*=" page"]')
.forEach(el => el.style.backgroundColor = "green");
<div class="page">Yes</div>
<div class="notpage">No</div>
<div class="some page">Yes</div>
<div class="pageXXX">Yes</div>
<div class="page1">Yes</div>
<div class="some">Unmatched entirely</div>
You can use jQuery solution..
var $divs = $('div[class^="page"]');
This will get all the divs which start with classname page
$(document).ready(function () {
$("[class^=page]").show();
$("[class^=page]").hide();
});
Use this to show hide div's with specific css class it will show/hide all div's with css class mention.
This question already has answers here:
javascript variable corresponds to DOM element with the same ID [duplicate]
(3 answers)
Closed 9 years ago.
I have multiple spans
<span id ="myId">data1</span>
<span id ="myId">data2</span>
<span id ="myId">data3</span>
<span id ="myId">data4</span>
<span id ="myId">data5</span>
I want to delete text inside all span on single button click.
I tried this on button click in javascript
document.getElementById("myId").innerHTML = "";
but it is removing text from only 1st span
IDs are unique, Classes are repeatable
The purpose of an id in HTML is to identify a unique element on the page. If you want to apply similar styles or use similar scripts on multiple elements, use a class instead:
<span class="myClass">data1</span>
<span class="myClass">data2</span>
<span class="myClass">data3</span>
<span class="myClass">data4</span>
<span class="myClass">data5</span>
<input type="button" id="clearbutton" value="Clear Data">
Now let's remove the text
Now, you can select all of these elements and set their text to anything you want. This example uses jQuery, which I recommend because older versions of IE don't support getElementsByClassName:
$('#clearbutton').click(function() {
$('.myClass').text('');
});
Link to Working Demo | Link to jQuery
Or in Vanilla JS
If you're not worried about supporting IE, you can do this with vanilla JavaScript:
function clearSpans() {
var spans = document.getElementsByClassName("myClass");
for(var i=0; i < spans.length; i++) ele[i].innerHTML='';
}
Link to Working Demo
Note: You can add getElementsByClassName to IE
I wouldn't recommend doing this because it's simpler and more widely accepted to just use jQuery, but there have been attempts to support older IEs for this function:
onload=function(){
if (document.getElementsByClassName == undefined) {
document.getElementsByClassName = function(className)
{
var hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
var allElements = document.getElementsByTagName("*");
var results = [];
var element;
for (var i = 0; (element = allElements[i]) != null; i++) {
var elementClass = element.className;
if (elementClass && elementClass.indexOf(className) != -1 && hasClassName.test(elementClass))
results.push(element);
}
return results;
}
}
}
Link to source
Dont give same ID to more than one one tag, use class instead
<span class ="myId">data1</span>
<span class ="myId">data2</span>
<span class ="myId">data3</span>
<span class ="myId">data4</span>
<span class ="myId">data5</span>
call this function to clear
function clearAll()
{
var ele= document.getElementsByClassName("myId");
for(var i=0;i<ele.length;i++)
{
ele[i].innerHTML='';
}
}
You are using a DOM method that relies to the DOM of ID, that is, per DOM, there can only be one element with the same ID.
However, you do not use the id attribute that way in your HTML, so instead you are looking for the selector to query all elements with the id myId, you perhaps know it from CSS:
document.querySelectorAll("#myId").innerHTML = '';
This does not work out of the box, you also need to add the innerHTML setter to the NodeList prototype, but that is easy:
Object.defineProperty(NodeList.prototype, "innerHTML", {
set: function (html) {
for (var i = 0; i < this.length; ++i) {
this[i].innerHTML = html;
}
}
});
You find the online demo here: http://jsfiddle.net/Pj4HD/
var spans=document.getElementsByTagName("span");
for(var i=0;i<spans.length;i++){
if(spans[i].id=="myId"){
spans[i].innerHTML="";
}
}
Although I suggest you don't keep same IDs
http://jsfiddle.net/YysRp/
I need to hide all the elements that have the string "replies-36965584" anywhere in their IDs.
HTML:
<div id="replies-36965584_1">aaaa</div>
<div id="replies-36965584_2">aaaa</div>
<div id="replies-36965584_3">aaaa</div>
<div id="replies-36965584_4">aaaa</div>
<div id="replies-36222224_2">nnnn</div>
JavaScript:
document.getElementById("replies-36965584").style.display="none"
How can I modify this JS to select the first four elements?
You can do this with CSS and attribute selectors.
[att^=val]
Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.
Source: http://www.w3.org/TR/css3-selectors/#attribute-substrings
jsfiddle
CSS
[id^="replies-36965584_"] {
display: none;
}
Is using jQuery an option? If so, this is dead simple:
$(document).ready(function(){
$('div[id^="replies-36965584"]').hide();
});
If you're unfamiliar with jQuery, here's a link to get started: http://learn.jquery.com/javascript-101/getting-started/
EDIT: Fixed syntax error.
EDIT: Added jsFiddle: http://jsfiddle.net/xbVp9/
If you don't know certain literal values but you know the general pattern and only the number will change, then I will consider some matching with regular expresiion.
You can do it the painful way:
var o = document.getElementsByTagName("div");
for (var i=0;i<o.length;i++) {
if(o[i].id.indexOf('replies-36965584') == 0) {
o[i].style.display = 'none';
}
}
The only way to do this with vanilla javascript that I know of, is to fetch all the divs on the page, and test the id's for the ones you want.
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; ++i) {
var div = divs[i];
if (/replies-36965584/.test(div.id)) {
div.style.display = 'none';
}
}
Can you please tell me if there is any DOM API which search for an element with given attribute name and attribute value:
Something like:
doc.findElementByAttribute("myAttribute", "aValue");
Modern browsers support native querySelectorAll so you can do:
document.querySelectorAll('[data-foo="value"]');
https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll
Details about browser compatibility:
http://quirksmode.org/dom/core/#t14
http://caniuse.com/queryselector
You can use jQuery to support obsolete browsers (IE9 and older):
$('[data-foo="value"]');
Update: In the past few years the landscape has changed drastically. You can now reliably use querySelector and querySelectorAll, see Wojtek's answer for how to do this.
There's no need for a jQuery dependency now. If you're using jQuery, great...if you're not, you need not rely it on just for selecting elements by attributes anymore.
There's not a very short way to do this in vanilla javascript, but there are some solutions available.
You do something like this, looping through elements and checking the attribute
If a library like jQuery is an option, you can do it a bit easier, like this:
$("[myAttribute=value]")
If the value isn't a valid CSS identifier (it has spaces or punctuation in it, etc.), you need quotes around the value (they can be single or double):
$("[myAttribute='my value']")
You can also do start-with, ends-with, contains, etc...there are several options for the attribute selector.
We can use attribute selector in DOM by using document.querySelector() and document.querySelectorAll() methods.
for yours:
document.querySelector("[myAttribute='aValue']");
and by using querySelectorAll():
document.querySelectorAll("[myAttribute='aValue']");
In querySelector() and querySelectorAll() methods we can select objects as we select in "CSS".
More about "CSS" attribute selectors in https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
FindByAttributeValue("Attribute-Name", "Attribute-Value");
p.s. if you know exact element-type, you add 3rd parameter (i.e.div, a, p ...etc...):
FindByAttributeValue("Attribute-Name", "Attribute-Value", "div");
but at first, define this function:
function FindByAttributeValue(attribute, value, element_type) {
element_type = element_type || "*";
var All = document.getElementsByTagName(element_type);
for (var i = 0; i < All.length; i++) {
if (All[i].getAttribute(attribute) == value) { return All[i]; }
}
}
p.s. updated per comments recommendations.
Use query selectors, examples:
document.querySelectorAll(' input[name], [id|=view], [class~=button] ')
input[name] Inputs elements with name property.
[id|=view] Elements with id that start with view-.
[class~=button] Elements with the button class.
Here's how you can select using querySelector:
document.querySelector("tagName[attributeName='attributeValue']")
Here is an example , How to search images in a document by src attribute :
document.querySelectorAll("img[src='https://pbs.twimg.com/profile_images/........jpg']");
you could use getAttribute:
var p = document.getElementById("p");
var alignP = p.getAttribute("align");
https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute
Amendment for Daniel De León's Answer
It's possible to search with
^= - filters Elements where id (or any other attr) starts with view keyword
document.querySelectorAll("[id^='view']")
very simple, try this
<!DOCTYPE html>
<html>
<body>
<h1>The Document Object</h1>
<h2>The querySelector() Method</h2>
<h3>Add a background color to the first p element:</h3>
<p>This is a p element.</p>
<p data-vid="1">This is a p element.</p>
<p data-vid="2">This is a p element.</p>
<p data-vid="3">This is a p element.</p>
<script>
document.querySelector("p[data-vid='1']").style.backgroundColor = "red";
document.querySelector("p[data-vid='2']").style.backgroundColor = "pink";
document.querySelector("p[data-vid='3']").style.backgroundColor = "blue";
</script>
</body>
</html>
function optCount(tagId, tagName, attr, attrval) {
inputs = document.getElementById(tagId).getElementsByTagName(tagName);
if (inputs) {
var reqInputs = [];
inputsCount = inputs.length;
for (i = 0; i < inputsCount; i++) {
atts = inputs[i].attributes;
var attsCount = atts.length;
for (j = 0; j < attsCount; j++) {
if (atts[j].nodeName == attr && atts[j].nodeValue == attrval) {
reqInputs.push(atts[j].nodeName);
}
}
}
}
else {
alert("no such specified tags present");
}
return reqInputs.length;
}//optcount function closed
This is a function which is is used tu to select a particular tag with specific attribute value. The parameters to be passed are are the tag ID, then the tag name - inside that tag ID, and the attribute and fourth the attribute value.
This function will return the number of elements found with the specified attribute and its value.
You can modify it according to you.