How to use getElementsByTagName Effeciently - javascript

I'm currently using this bookmarklet to hide several random rows of a webpage:
(function () {
document.getElementsByTagName("tr")[1].style.display = "none";
document.getElementsByTagName("tr")[3].style.display = "none";
document.getElementsByTagName("tr")[6].style.display = "none";
})();
Is it necessary to repeat
document.getElementsByTagName("tr")[].style.display = "none"
again and again or is there any way to simplify it ?
I mean to merge all these into a simple command like
document.getElementsByTagName("tr")[1,3,6].style.display = "none".
Is it possible?
Kindly provide me an example coding for above bookmarklet?

Sure, you can store the trs in a variable:
var trs = document.getElementsByTagName("tr");
Then you can loop through the trs 1 through 3.
for(var i = 1; i <= 3; i++) {
trs[i].style.display = "none";
}
Alternately, you can use Array.prototype.slice to select a range of trs.
Array.prototype.slice.call(trs, 1, 4).forEach(function(tr) {
tr.style.display = "none";
});

Try this one
var rows= document.getElementsByTagName("tr")
Array.from(rows).forEach(v => v.style.display = 'none');

Use a for loop or foreach loop.
var temp = document.getElementsByTagName("tr");
for(var i = 0; i < temp.length; i++){
temp[i].style.display = "none";
}
or
var temp = document.getElementsByTagName("tr");
temp.forEach(element => element.style.display = "none");
Can be put into
document.getElementsByTagName("tr").forEach(element => element.style.display = "none");

Related

Div not showing when onClick Function runs

I wanted to make a specific form show and the other forms disappear when I click on one of four dropdown buttons. When I tested the code, no from is showing when I clicked on a button.
Here is my javascript code:
function showClass(className)
{
var allItems = document.getElementsByClassName('change-form');
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
It shows the form if I remove the top for loop.
Edit: Sorry guys I made a typo
Your code is going in and hiding all the items and then showing them right away. What you want to do is split the hide and show into different functions to trigger them at different times.
function showClass(className)
{
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
function hideClass(className){
var allItems = document.getElementsByClassName(className);
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
}
If you want to be able to swap them with one function you could use this:
function swapHide(className){
var firstItem = document.getElementsByClassName(className)[0];
var isDisplayed = firstItem.style.display == "block"
if(isDisplayed){
hideClass(className);
}else{
showClass(className)
}
}

More efficient way of writing this as part of a JavaScript function?

I am trying to write a JavaScript function that will hide multiple IDs at once. As I will be getting into 50 or so IDs that will need to be hidden for any given function, I don't want to have unnecessary code. I have something like below, but there must be a way to combine all these lines in to one, no?
document.getElementById("aMap").style.display = "none";
document.getElementById("aList").style.display = "none";
document.getElementById("bMap").style.display = "none";
document.getElementById("bList").style.display = "none";
document.getElementById("cMap").style.display = "none";
document.getElementById("cList").style.display = "none";
Ok, thanks everyone. Showing my updated code below. It's not working, as I am sure I am doing something wrong. The goal is to have a function that shows 2 elements that are identified by ID and hide all of the other IDs at the same time:
function zShowHideRest() {
var zOther = ["aMap", "aList", "bMap", "bList", "cMap", "cList"];
zOther.forEach.getElementById().style.display = "none";
document.getElementById("zMap").style.display = "block";
document.getElementById("zList").style.display = "block";
}
Am I in the ballpark or is what I did way off?
Just put all of the IDs in an array and iterate over them using a for of or forEach loop.
const arr = [your list of ids];
for(const a of arr) {
document.getElementById(a).style.display = "none";
}
const arr = [your list of ids];
arr.forEach((a) => {
document.getElementById(a).style.display = "none";
})
Using a loop helps reduce repeated code:
const ids = ["aMap","aList","bMap","bList","cMap","cList"];
ids.forEach(
function(id) {
const element = document.getElementById(id);
if (element) {
element.style.display = "none";
}
}
);
document.getElementById("aMap").style.display = "none";
document.getElementById("aList").style.display = "none";
document.getElementById("bMap").style.display = "none";
document.getElementById("bList").style.display = "none";
document.getElementById("cMap").style.display = "none";
document.getElementById("cList").style.display = "none";
// method of array of id REF Sebastian Simon
let arrID = ["aMap", "aList", "bMap", "bList", "cMap", "cList",]
// method 1 for loop
for (var i = 0; i < arrID.length; i++) {
document.getElementById(arrID[i]).style.display = "none";
};
// method 2 for loop
arrID.forEach((id) => {
document.getElementById(id).style.display = "none";
});
// arrow function not working any of IE
// my suggest
// give your elements same class example:"hide"
document.getElementsByClassName("hide").style.display = "none";
quickFix: you either use for loop but using class name makes without array of id but i have array of elements which is has classname hide
let elementsHasHide = document.getElementsByClassName("hide");
for (var i = 0; i < elementsHasHide.length; i++) {
elementsHasHide[i].style.display="hide"
}
You should use Class instead of ID.
var myClasses = document.querySelectorAll('.ids_list'),
i = 0,
l = myClasses.length;
for (i; i < l; i++) {
myClasses[i].style.display = 'none';
}
or
var list = document.getElementsByClassName('my-class')
for (var i = 0; i< list.length; i++){
list[i].style.display = "none";
}
html:
<div class="ids_list" id="aMap"></div>
<div class="ids_list" id="aList"></div>
<div class="ids_list" id="bMap"></div>
<div class="ids_list" id="bList"></div>
<div class="ids_list" id="cMap"></div>
<div class="ids_list" id="cList"></div>
Just update js

How to retrieve textContent and display on checkbox input

I am trying to build a small program which you enter data into using input fields to build a set of unordered lists containing list items.
I have a checkbox of which that when it is checked, i would like it to display the entire unordered list that contains that bit of text, in this case, atlanta. I would like the rest of the unordered lists which do not contain this text to be set to display: none;
The for loop is the issue, though I have been playing around all day and cannot behave as I would like.
This is the code in question I believe:
checkboxInput.addEventListener('change', (e) => {
const isChecked = e.target.checked;
let ulList = document.getElementsByTagName('ul');
let liList = document.getElementsByTagName('li');
let locationList = document.getElementsByClassName('location');
if (isChecked) {
for (let i = 0; i < ulList.length; i += 1) {
for (let j = 0; j < liList.length; j += 1) {
let ul = ulList[i];
let li = liList[i];
if (li.textContent == 'atlanta') {
ul.style.display = '';
} else {
ul.style.display = 'none';
}
}
}
}
});
Please see a jsFiddle link here.
Any help much appreciated.
A couple of the variables I declared were unnecessary in this piece of code.
The liList variable was replaced with ulList.children.
The second for loop wasn't necessary either.
Here is the eventListener changed to achieve the functionality I required.
checkboxInput.addEventListener('change', (e) => {
const isChecked = e.target.checked;
let ulList = document.getElementsByTagName('ul');
if (isChecked) {
for (let i = 0; i < ulList.length; i += 1) {
let ul = ulList[i];
let liList = ul.children;
let li = liList[1];
if (li.textContent == 'atlanta') {
ul.style.display = 'block';
} else {
ul.style.display = 'none';
}
}
}
});
Thanks to Kris from Treehouse for the answer to this problem.

Any better way to hide multiple elements at once?

This works perfectly fine, but for future reference I would like to know if there is a better way to do this.
document.getElementsByTagName('h1')[0].style.display = 'none';
document.getElementsByTagName("p")[0].style.display = 'none';
document.getElementsByTagName("p")[1].style.display = 'none';
document.getElementsByTagName("ul")[0].style.display = 'none';
document.getElementsByTagName("hr")[0].style.display = 'none';
I'm open to using jQuery if it would help.
While jQuery wasn't specifically requested, it would be the shortest implementation to meet the OP's sample code exactly as written:
$('h1:eq(0), ul:eq(0), hr:eq(0), p:lt(2)').hide();
Keep your nodes in an Array, then you can write some functions which will hide or show a whole Array (or NodeList) at once, e.g.
function display_none(nodelist) {
var i = nodelist.length;
while (i-- > 0)
nodelist[i].style.display = 'none';
}
function display_default(nodelist) {
var i = nodelist.length;
while (i-- > 0)
nodelist[i].style.display = '';
}
So you have
var elms = [
document.getElementsByTagName('h1')[0],
document.getElementsByTagName("p")[0],
document.getElementsByTagName("p")[1],
document.getElementsByTagName("ul")[0],
document.getElementsByTagName("hr")[0]
];
Now can simply do
display_none(elms); // hide them all
display_default(elms); // return to default
Here's a pure Javascript option that implements a jQuery-like extension for the :lt(n) pseudo selector so you can specify however many of each tag you want.
As the question asked, this operates on the first two "p" tags, then the first "h1", "ul" and "hr" tags:
function hideItems(selector) {
var r = /:lt\((\d+)\)/;
selector.split(',').forEach(function(item) {
var len, elems, i, m = item.match(r);
if (m) {
item = item.replace(r, "");
elems = document.querySelectorAll(item);
len = Math.min(+m[1], elems.length);
} else {
elems = document.querySelectorAll(item);
len = elems.length;
}
for (i = 0; i < len; i++) {
elems[i].style.display = 'none';
}
});
}
hideItems('p:lt(2),h1:lt(1),ul:lt(1),hr:lt(1)');
Working demo: http://jsfiddle.net/jfriend00/m9vspymz/
Using Pure JavaScript
//gets all DOM elements with a tag of p or li
var elems = document.querySelectorAll('p,li');
//loops over all elements
for(var i = 0;i < elems.length; i++)
{
//hides each element in the array
elems[i].style.display = 'none';
}
Code Specifically for you
var elems = document.querySelectorAll('p,h1,ul,hr');
for(var i = 0;i < elems.length; i++)
{
elems[i].style.display = 'none';
}
Here's the code (JavaScript):
var n = [ // 'tagname',which in order
'h1',0,
'p',0,
'p',1,
'ul',0,
'hr',0
];
for(var i = 0;i < elems.length)
{
document.getElementsByTagName(n[i*2])[(n[i*2]+1)].style.display = 'none';
i++;
i++;
}

expanding and collapsing folders

I need to get more than one element to toggle open and closed. Right now the function is just selecting the ID, but I'd like to know how to get it to select a class. I thought I could change the document.getElementById to document.getElementByClass but that didn't work.
I picked this bit of code during my search:
#ToggleTarget {display:hidden;}
<script type="text/javascript">
function Toggle() {
var el = document.getElementById("ToggleTarget");
if (el.style.display == "block") {
el.style.display = "none";
}
else {
el.style.display = "block";
}
}
</script>
var getElementsByClassName = function(node, classname) {
if (document.getElementsByClassName) {
return document.getElementsByClassName(classname);
}
var a = [];
var re = new RegExp('(^| )'+classname+'( |$)');
var els = node.getElementsByTagName("*");
for(var i=0,j=els.length; i<j; i++)
if(re.test(els[i].className))a.push(els[i]);
return a;
}
var Toggle = function(){
var tp = getElementsByClassName(document.documentElement,'toggle');
for(var i = 0; i < tp.length; i++){
if(tp[i].style.display=='none')
tp[i].style.display='block'
else
tp[i].style.display='none'
}
}
Use getElementsByClassName and then loop through them.
EDIT
Just make sure they have the class toggle as used in my code above.
UPDATE
Added function for IE support (adopted from https://stackoverflow.com/a/7410966/600101).

Categories