How to create many divs without actually creating them individually - javascript

I'm working on a project with html, css and js and I want to create many divs (let's say, 200) so, how can i create them without actually writing code for 200 different divs... I know I can do it with js but could I do it only with html and css..?

As I already said in my comment, you can't do it without JavaScript.
A JavaScript solution would be the following:
const container = document.getElementById("container");
for (let i = 0; i < 200; i++) {
const item = document.createElement("div");
item.classList.add("item", "item-" + i);
container.appendChild(item);
}
#container {
border: 1px solid red;
padding: .5rem;
}
.item {
border: 1px solid black;
height: 3rem;
margin-bottom: .3rem;
}
<div id="container">
</div>

One way with js:
you can create one HTML Span Element and with js you change the content of it. I bet with that knowledge you find something

how it's going? Html or css is not a programming language. So you can't do some kind of automation or repeating code or something like that. The only way to do that sort of things is using Javascript. Here is how:
<div class="container">
<!-- let's say we trying to add divs here. -->
</div>
And here's script:
function addMultiple (where, what, count, callBack) {
for (let i = 0; i < count; i++) {
// creating elements with document.createElement() method
let item = document.createElement(what)
// and then adding them into "where" element.
where.appendChild(item)
/*
and finally we'll have a function called Callback.
This is just gonna take our item as an argument and
do some stuff on it according to what we want.
(I'll show a simple usage down below)
*/
callBack(item)
}
}
// let's say we want to add 200 divs into "container" element
// and then we want to add class name to those divs.
const container = document.querySelector('.container')
addMultiple(container, 'div', 200, item => {
// this code will be repeated for all divs.
item.classList.add('what_ever_you_want')
})

Related

Change color in a number of different divs that all share the same class

I have a site with a lot of different div. The thing they have in common is all share (besides their unique classes) a shared class. Lets just call it .changeClass.
What I am looking for is code with a button (or radio buttons) and by clicking the button, the background instance of all these divs will get the same one (which the .changeClass has). So the .changeClass will just be active when the button is toggled/clicked.
I am looking for a way to do this with pure javascript and no Jquery.
Sorry for being a noob :-)
In the solution below, clicking the <button> element will add/remove the class style .changeClass to all elements that have the class style .apply applied.
let button = document.getElementById('change');
let containers = document.getElementsByClassName('apply');
function changeButtonText() {
if(button.innerHTML === "Add")
button.innerHTML = "Remove";
else
button.innerHTML = "Add";
}
button.addEventListener('click', function() {
for(let index = 0 ; index < containers.length ; ++index)
containers[index].classList.toggle('changeClass');
changeButtonText();
});
div {
margin-top: 25px;
}
.apply {
border: 3px solid black;
}
.changeClass {
background-color: black;
color: white;
border: 3px solid red;
margin-top: 25px;
}
<button id="change">Add</button>
<div class="apply">1</div>
<div class="apply">2</div>
<div class="apply">3</div>
<div class="apply">4</div>
<div class="apply">5</div>
First lets get all divs that are on the DOM
const divs = document.getElementsByTagName("div");
You will have array of all the divs that are on the DOM. Then add your class to all of it. In order to do that, lets loop it.
divs.forEach(div => div.className += div.className + " changeClass");
Could this be what you are looking for?
In html:
<button onclick="changeColor('blue');">blue</button>
In JS
function changeColor(newColor) {
var elem = document.getElementsByClassName("changeClass");
elem.style.color = newColor;
}
The HTML color can be any color you would like it to be, just change they name from blue to any color or input a hex code.
We have multiple divs with the same class value
We have given a function to the button that we want the event to happen when it is clicked, using the onclick method. Now when we click the button, the function called myFunction will run.
HTML:
<div class="changeClass">Im Example Div</div>
<div class="changeClass">Me Too</div>
<button type="submit" onclick="myFunction()">Click To Change Div BgColors !
</button>
We must define myFunction as Javascript and change the background color.
We have defined a function called myFunction.
With the getElementsByClassName selector in our function, we got all the data with the class value changeClass in object format.
To add a background (or any css property) to all of these objects; We put the object in a for loop and now we split our elements.
We can now define a background color for our elements with the style.backgroundColor parameter.
JavaScript:
function myFunction(){
var divs = document.getElementsByClassName('changeClass');
for(var i=0; i< divs.length; i++){
divs[i].style.backgroundColor = 'red';
}
}
For more detailed information, you can refer to the resources: https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp
Don't be sorry for being new at something and wanting to learn more!
So what you are saying is that the divs you want to change all have a common class of "changeClass". If this is the case then you want a function is passed an argument value of the color you want to be changed. Since all of your divs are static and you probably don't plan on changing, declare a variable outside of this function that has the following code
const divs = document.getElementsByClassName("changeClass")
Then, inside of the function, loop through all of the divs collected inside the variable "divs", or whatever you want to call it. Since "getElementsByClassName" returns a collection, it does not have the built in "foreach" and "map" methods. So you have to use a for loop preferably the following.
const divs = document.getElementsByClassName("changeClass");
function changeColor(color) {
for (let element of divs) {
element.style.backgroundColor = color;
}
}
I may have interpreted this wrong but I hope it helps
You may find using a CSS variable helpful.
For example:
function bg(color) {
document.body.style.setProperty('--bg', color);
}
body {
--bg: cyan;
}
.container {
display: flex;
gap: 1vw;
}
.container div {
width: 100px;
height: 100px;
background-color: black;
}
.container div.changeClass {
background-color: var(--bg);
}
<body>
<button onclick="bg( 'red');">Red</button>
<button onclick="bg( 'green');">Green</button>
<button onclick="bg( 'blue');">Blue</button>
<button onclick="bg( 'black');">Black</button>
<div class="container">
<div class="changeClass"></div>
<div class="changeClass"></div>
<div class="changeClass"></div>
<div></div>
<div class="changeClass"></div>
</div>
</body>
Then when one of the radio buttons is clicked it sets the variable --bg.
Here's a simple snippet:
First of all - thank you for all your replies. And yes I should have included code. I tried so many things that i just gave up at som point - got confused what was right code and what was just rubbish. So I appreciate so much that you all took time to answer me. This was my first post so now I know for the future. The answers I got all was possible ways to solve my problem - so thank you all. I will do better next time. You are awesome...
BTW - All solutions seems to work - but can only checkmark one of them as you know.
You can add or remove a class to change the colours of different div:
document.queryselector('.className').classList.add('classNamethatyouwanttoadd');
document.queryselector('.className').classList.remove('classNamethatyouwanttoadd');

toggle / display image through an event listener

I have a list of featured products which I get through an API call, with the title and the icon displayed in the list. All the products also have images (which I also get through the same API call)
I want the image to not display when the icon is not active, but to display when the icon is active. Not sure how I get to display that specific image when the icon to that product is active.
(kinda new into coding, so sorry if this is a weird question)
export function featuredProducts(products)
const featuredProductsContainer = document.querySelector(".featured-products_list");
featuredProductsContainer.innerHTML = "";
for (let i = 0; i < products.length; i++) {
console.log(products[i]);
if (products[i].featured) {
featuredProductsContainer.innerHTML +=
`<li class="featured-products">
<p>${products[i].title}<i class="far fa-flag" data-name="${products[i].title}"></i></p></li>
<img src="http://localhost:1337${products[i].image.url}" class="${products[i].title}"
height="300" width="300" style="display: none;">`;
}
}
const flag = document.querySelectorAll(".featured-products i");
flag.forEach(function(icon) {
icon.addEventListener("click", clicked);
});
function clicked(event) {
event.target.classList.toggle("fas"); //active
event.target.classList.toggle("far"); //unactive
}
}
TL;DR You'll want to add css to hide/show the images (As #barmar answered above).
I will propose a slightly different approach, which is toggling the classes on the images directly, to avoid a more complex rearrangement of the markup and gigantic css selectors.
But first, to make it easier, you should place the img tags inside their li, not beside them.
So, first, let's move the closing li tag to the end, after the img. Note I'm also removing the inline style of style="display: none;".
for (let i = 0; i < products.length; i++) {
console.log(products[i]);
if (products[i].featured) {
featuredProductsContainer.innerHTML +=
`<li class="featured-products">
<p>${products[i].title}<i class="far fa-flag" data-name="${products[i].title}"></i></p>
<img src="http://localhost:1337${products[i].image.url}" class="${products[i].title}"
height="300" width="300"></li>`;
}
}
Then, in your click handler, let's do something different:
function clicked(event) {
// remove all active classes
const $imgs = document.querySelectorAll('.fas')
$imgs.forEach(i => i.classList.toggle('fas'))
// add active class to targeting img
const $img = event.target.closest('li.featured-products').querySelector('img')
$img.classList.toggle("fas")
$img.classList.toggle("far");
}
Lastly, modified from from #barmar
.featured-products img.fas {
display: block;
}
.featured-products img.far {
display: none;
}
You can do this with CSS. Since your event listener toggles the far and fas classes, use CSS selectors that match an img inside those containers.
.featured-products.fas img {
display: block;
}
.featured-products.far img {
display: none;
}
There are many ways to go about this, a lot depends on what triggers the active state of the icon.
if it's any kind of input and you can keep the data in the same container then all you need to do Is add an "active" css class to the parent. This is the most performant way as you keep reads, writes and any reflows to a minimum.
Just add a general rule in in your css for the active class:
.active img { visibility: visible; }
If the images are in a separate element, you can add a dataset custom property to the icon in your html. With a value you can use in Javascript.
I. e.
<img id="icon" dataset-foo="imgContainer">
and in JS
var imgContainer = document.getElementById(icon.dataset.foo)
imgContainer.classList.add("active")
You can wrap it in a function and maybe save any references in an object. This way it's easy to keep track of any data and have very readable code.

How to display/hide a div in another html page

I have two html pages (produse.html and item.html) and a menu in one of them. When I click a link from the menu I need to go to the other page and in the same time display a specific div and hide the original one from item.html.
I tried it with javascript using onclick method, but it doesn't work. I think the problem is that the javascript code can't get the class name of a div that is in another page.
Can there be something done?
This is the code that I tried.
produse.html
<div class="sideMenu">
prod 1
prod 2
prod 3
prod 4
</div>
item.html
<div class="displayBox yes">
1
</div>
<div class="displayBox">
2
</div>
<div class="displayBox">
3
</div>
<div class="displayBox">
4
</div>
javascript
var prevN = 0;
function displayTheBox(n){
var products = document.getElementsByClassName("displayBox");
products[prevN].className = products[prevN].className.replace(" yes", "");
products[n].className += " yes";
prevN = n;
}
css
.displayBox{
float: left;
height: 200px;
overflow: auto;
position: relative;
box-shadow: 1px 1px 4px 2px #9b9b9b;
background-color: #bbe5f8;
border-radius: 6px;
width: 995px;
margin: 0 0 0 235px;
display: none;
}
.yes{
display: block;
}
JS is a client-side script and it's variables are reset on page load. You can either pass the values by passing as GET parameters or by saving and retriving persistent data using localStorage or cookies.
Here is a simple js function to get GET variables and process function.
function findGetParameter(parameterName) { // Gets the GET variables
var result = null,
tmp = [];
var items = location.search.substr(1).split("&");
for (var index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
}
return result;
}
if(findGetParameter("item")) { // Check if parameter matches
displayTheBox(findGetParameter("item"));
}
var prevN = 0;
function displayTheBox(n) {
var products = document.getElementsByClassName("displayBox");
products[prevN].className = products[prevN].className.replace(" yes", "");
products[n].className += " yes";
prevN = n;
}
Change your hyperlinks to
<div class="sideMenu">
prod 1
prod 2
prod 3
<a href="item.html?item=3">prod 4<a>
</div>
For more info on storage methods, check this SO question What is the difference between localStorage, sessionStorage, session and cookies?
For a good example on js session storage, check this answer to a SO question here https://stackoverflow.com/a/49805713/6060602
Actually, when you're making a function call in a page, it can't be reflected in another one. You've to use backend for that job. But as per your problem is concerned, you may use a language like PHP for doing this job.
Otherwise, you can make a function call at the beginning when the new page is opened.
like,
window.onload()
or jQuery may also be helpful in this case,
$(document).ready(function() { /* code here */ });
That is impossible through normal click events like that.
Two pages will need to interact and since requests are stateless, everything that belongs to one page only really lives in there and nowhere else.
So to perform that, you will need to pass the communication through the request object.
Options:
First - Either create a form line this:
<form action="targetPage" method="get">
<input type="hidden" value="hideSomething" />
<button></button>
</div>
Then inside your TargetPage, retrience the query string from the URL, FInd out more about this here
Second - Either you're not sure if that is the right approach you want to take. Look closer into what you're trying to achieve and see if it's really necessary. I am not sure why you're trying to put those buttons( sideMenu ) on their own page seperate from where the boxes you're trying to control are.

How do I add classes to an unspecified amount of elements

I feel like this should be simple enough but I tend to overthink things. I simply want to add new classes to only the container-1 elements. The classes need to be numbered to differentiate them. Bonus for multiple methods & explaining in detail as I'd like to learn how to do this properly.
Example:
<div class="scroller">
<div class="container-1 newClass1"></div>
<div class="container-1 newClass2"></div>
<div class="container-2"></div>
<div class="container-1 newClass3"></div>
<div class="container-2"></div>
</div>
As the title says, the amount can be random. So it needs to read & apply to all container-1 within the scroller.
Here is some js, which get all elements by class name "container-1". After that in for loop, it will add class "newClass" with counter mark to each of the element with this class.
var elements = document.getElementsByClassName("container-1");
for(var i = 0; i < elements.length; i++){
elements[i].classList.add("newClass" + (i+1));
}
Well, one method I can think of is:
let selectedContainers = Array.from(document.querySelectorAll('.container-1'));
selectedContainers.map((container, i)=>{
container.classList.add(`newClass${++i}`)
})
What's going on here is that you're selecting all the divs with the container-1 class and creating an array from the NodeList. Then you're mapping through the array to access each element. Using template strings, you add a class name with a dynamic variable being the index of the container. You could use other variables and just increment them after, but I think the index is the easiest solution. Also, the reason I used ++i is to avoid getting a class with a zero index e.g newClass0
You can create an array of all the elements having class name 'container-1 using document.getElementsByClassName and the spread operator(...). Spread operator is used here because getElementsByClassName returns a HTMLCollection. So to iterate over it easily using a forEach we need to convert it to an array. Once converted, we could iterate over it and add newClass class to every element. To get the number to be added to the end of each newClass we use the 2nd argument to forEach which is index of the current element.
const containerOneDivs = [...document.getElementsByClassName('container-1')];
containerOneDivs.forEach((div, i) => div.className += ` newClass${i+1}`);
You can use querySelector (just to teach people who still use jQuery) to query for DOM elements.
You can then use Array.forEach to iterate over the list, and use $node.classList.add to append a class name.
Just for the purpose of the example:
window.onload = function onload () {
document.getElementById('btn-add').addEventListener('click', add, true);
document.getElementById('btn-remove').addEventListener('click', remove, true);
}
function add(e) {
updateFocus(e.target);
const list = document.querySelectorAll('.container-1');
list.forEach((item, i) => item.classList.add(`newClass-${i}`));
}
function remove(e) {
updateFocus(e.target);
const list = document.querySelectorAll('.container-1');
list.forEach((item, i) => item.classList.remove(`newClass-${i}`));
}
function updateFocus(el){
document.querySelectorAll('.active').forEach((i) => i.classList.remove('active'));
el.classList.add('active');
}
.scroller {
height: 100%;
width: 100%;
}
div[class*="container"] {
display: inline-block;
border: 1px solid blue;
width: 20px;
height: 20px;
margin: 2px;
}
div[class*="newClass-"] {
border: 1px solid yellow;
}
.active {
border: 3px solid red;
font-weight: bold;
}
<div class="scroller">
<div class="container-1"></div>
<div class="container-1"></div>
<div class="container-2"></div>
<div class="container-1"></div>
<div class="container-2"></div>
</div>
<button id="btn-add">add newClass-* to container-1</button>
<button id="btn-remove">remove newClass-* to container-1</button>
Otherwise it is just one line of code
document.querySelectorAll('.container-1');
.forEach((item, i) => item.classList.add(`newClass-${i}`));

How to create a search that filters by class name

I currently have a website that has multiple items. They are all individual div items. They all have one class name in common with several other class names as tags to help separate them (some tags are common among multiple div items)
I already have buttons set up that use data-filter=".exampleclass" and data-filter=".exampleclass2" etc. which work perfectly for sorting based on the class names. I am now trying to make a search bar where a user could type in the class name so I don't have to make buttons for them all.
document.getElementById("boxsearch").oninput = function() {
var matcher = new RegExp(document.getElementById("boxsearch").value, "gi");
for (var i = 0; i < document.getElementsByClassName("portfolio-item").length; i++) {
if (matcher.test(document.getElementsByClassName("category")[i])) {
document.getElementsByClassName("portfolio-item")[i].style.display = "inline-block";
} else {
document.getElementsByClassName("portfolio-item")[i].style.display = "none";
}
}
}
http://jsfiddle.net/kc2ot8ua/
I dont have the jquery file included so the buttons dont work (they work on my end) I just dont know how to use the search bar to search the class names.
This is the closest I could find to what I am trying to achieve: http://jsfiddle.net/mttgj1tt/5/
Filtering elements based on regular expression matches with one of their class names is an inefficient way to filter elements. Typically you'd build an index and use that with a more optimised search algorithm.
You might use one class to select the target set of elements, then loop over them and get their classList, then loop over those looking for matches, there's an example below. But this will also test other class names that have nothing to do with filtering or sorting (e.g. in the example below, "box" is used for display only, but elements are filtered by it anyway).
A better idea might be to add the filter and sorting values as a data- attribute, then they can be isolated from other side effects. I'd also suggest building an index of subject elements so you can find the ones you want first, then hide them.
Multiple getElementByClassName calls are expensive and unnecessary (particularly in a for loop). The example does one call per keyup.
function filterOnClass(baseClass, s) {
let re = new RegExp(s.trim(), 'i');
document.querySelectorAll('.' + baseClass).forEach(node => {
let cNames = Array.from(node.classList);
// Show all if search string is blank
if (s.trim() == '') {
node.classList.remove('hide');
// Otherwise, filter
} else if (cNames.some(cName => re.test(cName))) {
node.classList.add('hide');
} else {
node.classList.remove('hide');
}
});
}
.box {
height: 50px;
width: 100px;
border: 1px solid blue;
}
.hide {
display: none;
}
<input id="searchInput" onkeyup="filterOnClass('box', this.value)"><br>
<div class="box foo">foo</div>
<div class="box foo bar">foo bar</div>
<div class="box fum bar">fum bar</div>
<div class="box fum">fum</div>

Categories

Resources