I am trying to create an array of a parent div's (id="lol") children and them fetch them to change display:none; except for the child with id="a". I've tried this but it doesn't work. How can I improve this to get it to work?
function myFunction() {
var x = document.getElementById('a');
var children = [].slice.call(document.getElementById('lol').getElementsByTagName('*'),0);
var arrayLength = children.length;
for (var i = 0; i < arrayLength; i++) {
var name = children[i].getAttribute('id');
var z = document.getElementById(name);
z.style.display = 'none';
}
x.style.display = 'block';
}
If every child has an id attribute than it will work. Otherwise, some children might not have id attribute, in that case variable z will be undefined and accessing style property over z which is undefined will give error. Simple fix would be just handling undefined variable:
if(z)
z.style.display = 'none';
Same goes with variable x, too.
function myFunction() {
var children = [].slice.call(document.getElementById('lol').getElementsByTagName('*'),0);
var arrayLength = children.length;
for (var i = 0; i < arrayLength; i++) {
children[i].style.display = 'none';
}
document.getElementById('a').style.display = 'block';
}
How about using jQuery?
$('#lol').children(':not(#a)').hide();
If jQuery is not an option you can do this:
var lol = document.getElementById('lol');
var children = lol.querySelectorAll(':not(#a)');
for(var i=0;i<children.length;i++) {
children[i].style.display = 'none';
}
Even more "low-level":
var lol = document.getElementById('lol');
var children = lol.childNodes;
for(var i=0;i<children.length;i++){
if(children[i].id != 'a') {
children[i].style.display = 'none';
}
}
Related
I have this code, repeating 20 times with only change of variables prefix. How can i possibly make a loop and iterate by it to avoid this huge block of code?
It is used in my website and I want to make the development process more clear.
var keepElements = document.getElementsByName("keep-type");
for(var i = 0; i < keepElements.length; i++){
keep = document.getElementById(keepElements[i].value);
if(keepElements[i].checked == true){
keep.style.display = "block";
}
else{keep.style.display = "none";}
}
var offworkshopElements = document.getElementsByName("offworkshop-type");
for(var i = 0; i < offworkshopElements.length; i++){
offworkshop = document.getElementById(offworkshopElements[i].value);
if(offworkshopElements[i].checked == true){
offworkshop.style.display = "block";
}
else{offworkshop.style.display = "none";}
}
var defworkshopElements = document.getElementsByName("defworkshop-type");
for(var i = 0; i < defworkshopElements.length; i++){
defworkshop = document.getElementById(defworkshopElements[i].value);
if(defworkshopElements[i].checked == true){
defworkshop.style.display = "block";
}
else{defworkshop.style.display = "none";}
}
Move the logic to a function:
function keepElements(name) {
var keepElements = document.getElementsByName(name);
for (var i = 0; i < keepElements.length; i++) {
keep = document.getElementById(keepElements[i].value);
if (keepElements[i].checked == true) {
keep.style.display = "block";
}
else { keep.style.display = "none"; }
}
}
keepElements("keep-type");
keepElements("offworkshop-type");
keepElements("defworkshop-type");
If I didn't miss any details, you're repeating the same block 3 times:
["keep-type", "offworkshop-type", "defworkshop-type"].forEach(name => {
var elements = document.getElementsByName(name);
for(var i = 0; i < elements.length; i++){
element = document.getElementById(elements[i].value);
if(elements[i].checked == true){
element.style.display = "block";
}
else{element.style.display = "none";}
}
});
I prefer the array / forEach syntax, because the block starts with the list of name. But you could use a for...of loop instead.
for (const name of ["keep-type", "offworkshop-type", "defworkshop-type"]) {
var elements = document.getElementsByName(name);
for(var i = 0; i < elements.length; i++){
element = document.getElementById(elements[i].value);
if(elements[i].checked == true){
element.style.display = "block";
}
else{element.style.display = "none";}
}
}
The answers saying you should put the common functionality into a single function are absolutely right.
I just wanted to add that there are also solutions on the query side of things:
you could have all the elements be collected in one javascript function, querySelectorAll()
const elements = document.querySelectorAll('[name="keep-type"], [name="offworkshop-type"], [name="defworkshop-type"]')
Alternatively you could give them all the same class and select by that class.
const elements = document.getElementsByClassName("requiredElements");
And this way you have all your elements in one array.
for(let i = 0; i < 8; i++) {
let childDiv = document.createElement('div');
divi.id = "addDay";
childDiv.className = "boxName";
divi.appendChild(childDiv);
childDiv.textContent = "0";
}
document.querySelector('#map');
map.appendChild(divi);
divi.firstChild.style.backgroundColor = "green";
change();
}
function change(){
n = document.getElementById('addDay');
n.firstChild.textContent = 'something';
}
I need to change content of first child of addDay on every click,but this function makes it only once. What do you think where is problem?
I'm trying to figure out how to count the number of p's so every time the button is pressed, it outputs to 0 to 1 until the maximum number of p's is counted.
var big_number = 999999;
var i;
var a = document.getElementsByTagName("p");
function function0() {
for (i=0; i < big_number; i++) {
document.getElementsByTagName("p")[i].innerHTML="text";
}
}
I want it to write to another p every time the button is pressed.
document.getElementsByTagName("p").length // number of p elements on the page
Is that what you were asking?
Make a generic tag adder function then call it:
function addTags(tagName,start, max, container) {
var i = start;
for (i; i < max; i++) {
var newp = document.createElement(tagName);
newp.innerHTML = "paragraph" + i;
container.appendChild(newp);
}
}
var tag = 'p';
var big_number = 30;
var i;
var a = document.getElementsByTagName(tag );
// **THIS is your specific question answer**:
var pCount = a.length;
var parent = document.getElementById('mydiv');
addTags(tag,pCount , big_number, parent);
// add 10 more
a = document.getElementsByTagName(tag );
pCount = a.length;
big_number = big_number+10;
addTags(tag,pCount , big_number, parent);
EDIT:
NOTE: THIS might be better, only hitting the DOM once, up to you to determine need:
function addTagGroup(tagName, start, max, container) {
var tempContainer = document.createDocumentFragment();
var i = start;
for (i; i < max; i++) {
var el = document.createElement(tagName);
el.textContent = "Paragraph" + i;
tempContainer.appendChild(el);
}
container.appendChild(tempContainer);
}
To find out how many <p> elements there are in the document you should use DOM's length property as below :-
var numP = document.getElementsByTagName("P").length;
or
var div = document.getElementById("myDIV");
var numP = div.getElementsByTagName("P").length;
To get number of element inside a tag.
var x = ["s1","s2","s3","s4","s5","s6","s7","s8","s9","s10","s11",......,"s100"];
for (var i = 0; i < x.length; i++) {
document.getElementById(x[i]); }
var c = document.getElementById(x);
var a = document.getElementById("s2");
var b = document.getElementById("hover");
c.addEventListener('mouseover', function() {
b.style.display = "block";
});
c.addEventListener("mouseout", function() {
b.style.display = "none";
});
I have gallery of 100pictures, that needs mouseover action, so I wanted to use array like Id selector,and as you see I am not quite sure how to do this :D, so if anyone could help me a would be very thankful.
Hello i want to remove "Have you served in the military ?" and "No" if Answer is "No" but when it will "Yes" than it should show.
Whatever i have tried but it's not working
<script type="text/javascript">
(function(){
for(i = 0; (a = document.getElementsByTagName("td")[i]); i++){
if(document.getElementsByTagName("span")[i].innerHTML.indexOf('Have you served in the military') > -1){
document.getElementsByTagName("td")[i].style.display = "none";
}
}
})();
</script>
You could use child of the element or just do a find replace or even hide and show.
You can get all td elements like you already did and than get the span elements inside them:
var tds = document.getElementsByTagName('TD');
for (var i = 0, l = tds.length; i != l; ++i) {
var spans = tds[i].getElementsByTagName('SPAN');
for (var j = 0, l2 = spans.length; j != l2; ++j) {
var span = spans[j];
if ((span.textContent = span.innerText).indexOf('Have you served in the military') != -1) {
span.style.display = 'none';
break;
}
}
}
EDIT: OP wants to only delete the span if there is a td with the content "No" (also delete the td element)
var tds = document.getElementsByTagName('TD');
var tdsLength = tds.length;
var answerNoFound = false;
for (var i = 0; i != tdsLength; ++i) {
var td = tds[i];
if ((td.textContent = td.innerText) == 'No') {
td.style.display = 'none';
answerNoFound = true;
break;
}
}
if (answerNoFound)
for (var i = 0; i != tdsLength; ++i) {
var spanFound = false;
var spans = tds[i].getElementsByTagName('SPAN');
for (var j = 0, l = spans.length; j != l; ++j) {
var span = spans[j];
if ((span.textContent = span.innerText).indexOf('Have you served in the military') != -1) {
span.style.display = 'none';
spanFound = true;
break;
}
}
if (spanFound)
break;
}
It looks like you have an application form and document probably has more spans, some outside the td elements, so you don't get correct selection of spans versus td.
So when you are comparing span content, it is most likely not the span that is inside your looped td.
<script type="text/javascript">
(function(){
for(i = 0; (a = document.getElementsByTagName("td")[i]); i++){
if(a.getElementsByTagName("span")[0].innerHTML.indexOf('Have you served in the military') > -1){
a.style.display = "none";
}
}
})();
</script>
I changed the if statement to select span inside your looped td, that should do it.