how do i call a function to count the number of divs with an id of 'd1' after the page loads. right now i have it in my section but doesnt that execute the script before anything in the loads? because it works if i put the code below the div tags...
Firstly there should be at most one because IDs aren't meant to be repeated.
Second, in straight Javascript you can call getElementById() to verify it exists or getElementsByTagName() to loop through all the divs and count the number that match your criteria.
var elem = document.getElementById("d1");
if (elem) {
// it exists
}
or
var divs = document.getElementsByTagName("div");
var count = 0;
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
if (div.id == "d1") {
count++;
}
}
But I can't guarantee the correct behaviour of this because like I said, IDs are meant to be unique and when they're not behaviour is undefined.
Use jQuery's document.ready() or hook up to the onLoad event.
well an ID should be unique so the answer should be one.
you can use <body onload='myFunc()'> to call a script once the DOM is loaded.
You need to have the function tied to the onload event, like so:
window.onload = function() {
var divElements = document.getElementById("d1");
var divCount = divElements.length;
alert(divCount);
};
For the record, you should only have one div with that ID, as having more than one is invalid and may cause problems.
Related
I am looking for a way to be able to select an HTML element by its tag, like:
document.querySelector("<div id='myDiv'\>hello world</div\>")
//instead of: document.querySelector("#myDiv")
However, this code returns an error. The code should return the HTML element.
Does anybody know a way to achieve this? (vanilla JS preferred)
It seems a bit odd that you wouldn't want to select element via ID. But regardless one way of selecting the element in your example would be to look for its innerHTML.
e.g
var div = document.getElementsByTagName('div');
for (var i=0;i<div.length;i++){
console.log(div[i].innerHTML)
if(div [i].innerHTML == 'hello world'){
var element = div[i].parentElement
console.log(element)
break;
}
}
You could use outerHTML to search for it, however this only works if the element has a parent element.
var els = Array.from(document.querySelector('body *')); //this selects all elements in the body
var el;
for(var i = 0; i < els.length; i++) {
if(els.outerHTML === "<div id='myDiv'\>hello world</div\>") {
el = els[i];
}
}
//Use the el variable for your element
I am attempting to populate a list with href links via javascript.
Here is an example of the html I would like to create:
<li> Complete blood count</li>
Where "#modal-one" displays a pop up.
I have used the following and several other iterations to try and create this dynamically:
<script>
var listItem = [];
function createTestList() {
var tests = results.tests; //an array to tests to populate list
var i;
var j;
for (i = 0; i < tests.length ; i++ ){
listItem[i] = document.createElement("li");
var node = document.createTextNode(tests[i].name);
listItem[i].appendChild(node);
listItem[i].setAttribute("href", "#modal-one");
addOnClick(i);
//var element = document.getElementById("div1");
//element.appendChild(listItem[i]);
document.body.appendChild(listItem[i]);
console.log(listItem[i]);
};
};
function addOnClick(j) { //this is separate to handle the closure issue
listItem[j].onclick = function() {loadModal(j)};
};
</script>
However, this code (and several others) produce:
<li href='#modal-one'>Complete Blood Count</li> //note missing <a>...</a>
It appears there are several ways to achieve this, but nothing seems to work for me...
You are never actually adding in an anchor tag. You are creating a list-item (li), but you are adding an href to that list-item rather than adding an anchor node to it with that href. As such, the browser just thinks you have a list-item with an href attribute.
Consider using the following instead:
<script>
var listItem = [];
function createTestList() {
var tests = results.tests; //an array to tests to populate list
var i;
var j; // Never actually used in function. Consider omitting
for (i = 0; i < tests.length ; i++ ){
// create the list item
listItem[i] = document.createElement("li");
// Create the anchor with text
var anchor = document.createElement("a");
var node = document.createTextNode(tests[i].name);
anchor.appendChild(node);
anchor.setAttribute("href", "#modal-one");
// Set the onclick action
addOnClick(i, anchor);
// Add the anchor to the page
listItem[i].appendChild(anchor);
document.body.appendChild(listItem[i]);
console.log(listItem[i]);
};
};
// Modified "addOnClick" to include the anchor that needs the onclick
function addOnClick(j, anch) { //this is separate to handle the closure issue
anch.onclick = function() {loadModal(j)};
};
</script>
A couple things to note:
I have modified your addOnClick() function because it is the anchor element that needs the onclick, not the list item.
I have added in the creation of an anchor element rather than simply creating a list item and adding the href to that.
I do not see creating a element, change code to:
var aNode=document.createElement("a");
aNode.innerText=tests[i].name;
aNode.setAttribute("href", "#modal-one");
listItem[i].appendChild(aNode);
You can change also click method, to use it on a not on li
function addOnClick(j) {
listItem[j].querySelector("a").addEventListener("click",function(e) {
e.preventDefault();//this prevent for going to hash in href
loadModal(j);
});
};
Okay. I missed the anchor tag. My bad...
Spencer's answer came close, but I had to make few changes to get it work in my instance.
The final working code (and honestly I am not sure why it works) is:
<script>
var listItem = [];
function createTestList() {
var tests = results.tests;
var i;
//var j;
for (i = 0; i < tests.length ; i++ ){
// create the list item
listItem[i] = document.createElement("li");
// Create the anchor with text
var anchor = document.createElement("a");
anchor.setAttribute("href", "#modal-one");
var node = document.createTextNode(tests[i].name);
anchor.appendChild(node);
// Set the onclick action
addOnClick(i);
// Add the anchor to the page
listItem[i].appendChild(anchor);
document.getElementById("demo").appendChild(listItem[i]); //added the list to a separate <div> rather than body. It works fine like this.
console.log(listItem[i]);
};
};
function addOnClick(j) { //this is separate to handle the closure issue
//didn't need the additional code beyond this
listItem[j].onclick = function() {loadModal(j)};
};
</script>
Thanks to all and Spencer thanks for the thoroughly commented code. It helps!!!
Might be a strange setup, but I have a number of hyperlinks on the page with the same id (yeah, I know, but it was not my choice and I cannot change that at this time plus those hyperlinks are generated dynamically).
Example:
<div id="Links">
<div class="myItem">Some text</div>
<div class="myItem">More text</div>
<div class="myItem">Even more text</div>
</div>
Now I need to attach javascript to those links dynamically (the hyperlinks are also dynamically generated). The easiest way I see is by getting all hyperlinks on the page and then check the hyperlink id to ensure I only take care of those that have id of "myLink" (I have many other hyperlinks on the page).
I thought of using getElementById but that would only grab the first element with the specified id.
am attaching javascript to those links using the following:
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
if (anchor.id='myLink')
{
if (anchor.getAttribute("LinkID") != null)
{
anchor.onclick = function() {
MyFunction(this.getAttribute("LinkID"), false);
return false;
}
}
}
}
}
The above function works fine, but it creates another issue - affects the styling of other hyperlinks on the page. So I was wondering if there is a way to accomplish the same thing but without affecting other elements on the page?
This is more modern and corrects your equality test:
window.onload = function() {
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
if (anchor[i].id==='myLink' && anchor[i].getAttribute("LinkID") !== null)
{
anchor[i].addEventListener("click", function() {
MyFunction(this.getAttribute("LinkID"), false);
}
}
}
}
Even with your original code, I don't see anything that would interfere with styling in the code. Can you elaborate as what styling changes you were getting?
You can use an attribute selector and document.querySelector([id=<id>]) pretty reliably depending on your browser support situation: http://codepen.io/anon/pen/YwLdKj
Then, of course, loop through that result and make subsequent changes or event bindings.
If not, you could use jQuery (referenced in above code pen).
You might also use JavaScript event delegation and listen for all click events, check if the user is clicking a link with the correct id.
If a combination of tag == 'a', class == "myItem" and presence of a LinkID attribute is sufficient to identify nodes requiring a click handler they could be identified using multiple CSS selectors. If this is not possible however, a query selector not using id can create a list of nodes to be checked for id, as for example:
function callMyFunction()
{ MyFunction(this.getAttribute("LinkID"), false);
}
function addClickHandlers()
{ var list = document.querySelectorAll("a[LinkID]")
var i, node;
for( i = 0; i < list.length; ++i)
{ node = list[i];
if(node.id == "myLink")
{ node.onclick=callMyFunction;
}
}
}
See also running a selector query on descendant elements of given node if of interest.
I have an issue about getElementById.
Here is the part of the javascript code that causes a problem:
var elmt = document.getElementById("cardSlotsJoueur");
elmt.style.backgroundImage = "url('images/backcard.png')";
I wanted to modify this (Css) :
#cardSlotsJoueur div {
But it actually modifies #cardSlotsJoueur {
Could you help me to find a way to modify the first one with getElementById ?
Thanks !
If you only want to modify the first div within the element with id=cardSlotsJoueur, you can use this:
var elmt = document.getElementById("cardSlotsJoueur").getElementsByTagName("div")[0];
To target #cardSlotsJoueur div it's better to use querySelector method which would retrieve children div element of the #cardSlotsJoueur container:
var elmt = document.querySelector("#cardSlotsJoueur div");
If you expect multiple div elements under the #cardSlotsJoueur then you need to get them all first
var elmt = document.querySelectorAll("#cardSlotsJoueur div");
and then set backgroundImage to each in the for loop.
You need to find div elements within #cardSlotsJoueur:
var elmt = document.getElementById("cardSlotsJoueur");
var divs = elmt.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].style.backgroundImage = "url('images/backcard.png')";
}
Probably the best way to do what you want is to use a class with the required styling and add it to the element. But as an alternative, you can add a rule to the last style sheet, e.g.
function addBackground() {
var sheets = document.styleSheets;
// If there are no style sheets, add one
if (!sheets.length) {
document.head.appendChild(document.createElement('style'));
}
// The sheets collection is live, if a new sheet was needed, it's automatically a member
sheets[sheets.length - 1].insertRule('#cardSlotsJoueur div{background-image:url("images/backcard.png")');
}
You can make it generic:
function addRule(ruleText) {
var sheets = document.styleSheets;
if (!sheets.length) {
document.head.appendChild(document.createElement('style'));
}
sheets[sheets.length - 1].insertRule(ruleText);
}
and call it like:
addRule('#cardSlotsJoueur div{background-image:url("images/backcard.png")');
I have a legacy html document containing h1 elements which don't have ids.
What I would like to achieve is to be able, using JavaScript, to get all h1(s) and then add to each a unique ID.
I have searched but could not find a solution that works.
Try getting all of them with document.getElementsByTagName("h1"). Loop through them, check if they have an id, and work appropriately. Try:
var h1s = document.getElementsByTagName("h1");
for (var i = 0; i < h1s.length; i++) {
var h1 = h1s[i];
if (!h1.id) {
h1.id = "h1" + i + (new Date().getTime());
}
}
DEMO: http://jsfiddle.net/kTvA2/
After running the demo, if you inspect the DOM, you'll see 3 out of the 4 h1 elements have a new, unique id. The one with the id in the first place isn't changed.
Note that this code needs to run after all elements are ready/rendered, which can be achieved by putting the code inside of a window.onload handler. The demo provided is set up to implicitly run the code then.
UPDATE:
With jQuery, you could use:
$(document).ready(function () {
$("h1:not([id])").attr("id", function (i, attr) {
return "h1" + i + (new Date().getTime());
});
});
DEMO: http://jsfiddle.net/kTvA2/7/
Use querySelectorAll() to get all of your header elements, then iterate over the result and generate yor unique id for each element.
var headerElements = document.querySelectorAll('h1');
for(h in headerElements) {
if(headerElements[h] instanceof Element) {
headerElements[h].id=uniqueIDgenerator();
}
}