please I need solution for my design program, with clonenode/copy
from one big div where user can choose what he would have on concretly id/content, so he could switch it with arrows or choose from dropdown menu,
but I have now solution only with appenchild from div
and, if user add some next content, next id, it will have same big div / it will duplicated so the file will bigger ....
so I need have only one big div from where it will clone or copy to concretly div and this div will not duplicate
many thanks for yours answers
const
dGet = document.getElementById('get')
, dBack = document.getElementById('back')
, slides = document.querySelectorAll('.mySlides')
, slideSelect = document.querySelector('#slide-Selector')
, current =
{ slide : null
, index : 0
, len : slides.length
};
slideSelect.onchange =()=>
{
current.index = slideSelect.selectedIndex;
plusDivs(0);
}
// init
plusDivs(0);
function plusDivs(n)
{
// more easy with a modulo...
current.index = (current.index +n +current.len) % current.len;
if (current.slide)
dBack.appendChild( current.slide );
current.slide = dGet.appendChild( slides[current.index] );
slideSelect.selectedIndex = current.index; // added
}
#get {
height : 300px;
width : 500px;
border : 1px solid red;
left : 100px;
position : absolute;
}
#back {
display : none;
}
<button onclick="plusDivs(-1)"><</button>
<button onclick="plusDivs(1)">></button>
<select id="slide-Selector">
<option>slideshow1</option>
<option>slideshow2</option>
<option>slideshow3</option>
</select>
<div id="back">
<div id="one" class="mySlides">
<span class="Tx1">slideshow1</span>
</div>
<div id="two" class="mySlides">
<span class="Tx1">slideshow2</span>
</div>
<div id="three" class="mySlides">
<span class="Tx1">slideshow3</span>
</div>
</div>
<div id="get"></div>
I used removeChild and cloneNode:
const
dGet = document.getElementById('get')
, dBack = document.getElementById('back')
, slides = document.querySelectorAll('.mySlides')
, slideSelect = document.querySelector('#slide-Selector')
, current =
{ slide : null
, index : 0
, len : slides.length
}
;
slideSelect.onchange =()=>
{
current.index = slideSelect.selectedIndex;
plusDivs(0);
}
// init
plusDivs(0);
function plusDivs(n)
{
// more easy with a modulo...
current.index = (current.index +n +current.len) % current.len;
if (current.slide)
dGet.removeChild( current.slide );
var clon = slides[current.index].cloneNode(true);
current.slide = dGet.appendChild(clon);
slideSelect.selectedIndex = current.index; // added
}
#get {
height : 300px;
width : 500px;
border : 1px solid red;
left : 100px;
position : absolute;
}
#back {
display : none;
}
<button onclick="plusDivs(-1)"><</button>
<button onclick="plusDivs(1)">></button>
<select id="slide-Selector">
<option>slideshow1</option>
<option>slideshow2</option>
<option>slideshow3</option>
</select>
<div id="back">
<div id="one" class="mySlides">
<span class="Tx1">slideshow1</span>
</div>
<div id="two" class="mySlides">
<span class="Tx1">slideshow2</span>
</div>
<div id="three" class="mySlides">
<span class="Tx1">slideshow3</span>
</div>
</div>
<div id="get"></div>
Related
I'm stumped on how to make the hex code displayed at the top one of the choices on the "board." This is what I've tried so far.
var colorCode = '#' + Math.random().toString(16).slice(2, 8);
hexCode.innerHTML = colorCode;
var divs = document.getElementsByTagName('div')
for (var i = 0; i < divs.length; i++) {
divs[i].style.backgroundColor = '#' + Math.random().toString(16).slice(2, 8);
}
.panel {
height: 100px;
width: 100px;
border: 2px solid yellow;
border-radius: 25%;
}
<header>
<h1>Guess the Color</h1>
</header>
<main>
<span id="hexCode"></span>
<div id="one" class="panel"></div>
<div id="two" class="panel"></div>
<div id="three" class="panel"></div>
<div id="four" class="panel"></div>
</main>
https://jsfiddle.net/magoo/6vdfcmnL/6/
Is not clear if you want to show the text above every panel or just make one of the panel below the title the correct one; By the way i edited the code to do both.
Try to edit the code like this to check if result as intended.
HTML part:
<header>
<h1>Guess the Color</h1>
</header>
<main>
<!-- question -->
<p id="hexCodeToGuess"></p>
<br>
<!-- one -->
<span id="oneHexCode" class="label"></span>
<div id="one" class="panel"></div>
<!-- two -->
<span id="twoHexCode" class="label"></span>
<div id="two" class="panel"></div>
<!-- three -->
<span id="threeHexCode" class="label"></span>
<div id="three" class="panel"></div>
<!-- four -->
<span id="fourHexCode" class="label"></span>
<div id="four" class="panel"></div>
</main>
Javscript part:
var colorCodeToGuess = '#' + Math.random().toString(16).slice(2, 8);
// set the first label with the question (the color code to guess)
hexCodeToGuess.innerHTML = colorCodeToGuess;
// list of panels
var panels = document.getElementsByClassName('panel');
// list of labels
var labels = document.getElementsByClassName('label');
// generate the position of the right answer panel (random to make it unpredictable)
var correctPanelIndex = getRandomInt(panels.length);
// cycle trough the divs
for (var i = 0; i < panels.length; i++) {
// set by default a random new color
var currentColorCode = '#' + Math.random().toString(16).slice(2, 8);
// the div is in the right answer position => override the current color with the colorCodeToGuess generate at the start (the problem of the previous code)
if(i == correctPanelIndex){
currentColorCode = colorCodeToGuess;
}
// set the color to the panel
panels[i].style.backgroundColor = currentColorCode;
// set the text on a label above the panel
labels[i].innerHTML = currentColorCode;
}
// an useful function to get a random integer passing it the numer of values possible
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
You will notice that one of the panels have the same code of the question of the first code written below the title.
I've also commented the code so you can remove the unwanted logic consciously.
Your question is a little vague but if i got it right you want to display the background color of one of your divs in hex format. The following code will do that. I have added comments on the code to explain what im doing.
//get your panels (using selector is better that using div)
var divs = document.querySelectorAll(".panel");
for (var i = 0; i < divs.length; i++) {
divs[i].style.backgroundColor = '#' + Math.random().toString(16).slice(2, 8);
}
//get the current backgrounds of all panels and add them to an array in hex format
curruntColorsArr = [];
x = document.querySelectorAll(".panel");
for (i = 0; i < x.length; i++) {
//get background color
backgroundColors = x[i].style.backgroundColor
//convert to hex
function rgbToHex(rgb) {
return '#' + rgb.match(/[0-9|.]+/g).map((x, i) => i === 3 ? parseInt(255 * parseFloat(x)).toString(16) : parseInt(x).toString(16)).join('')
}
//push to array
curruntColorsArr.push(rgbToHex(backgroundColors));
}
//get random color from the array and set it to innerHTML
function random_item(items) {
return items[Math.floor(Math.random() * items.length)];
}
const hexCode = document.getElementById("hexCode")
hexCode.innerHTML = random_item(curruntColorsArr)
.panel {
height: 100px;
width: 100px;
border: 2px solid yellow;
border-radius: 25%;
}
<header>
<h1>Guess the Color</h1>
</header>
<main>
<span id="hexCode"></span>
<div id="one" class="panel"></div>
<div id="two" class="panel"></div>
<div id="three" class="panel"></div>
<div id="four" class="panel"></div>
</main>
Context: I'm trying to change the color of a text according to a if statement (Green if returnOfInvestment >= 0 red if this isn't true) however, it doesn't seem to be working. I've searched on SO already, but can't figure out why it isn't working as expected.
var returnOfInvestment = (netProfit / initialInvestment.value) * 100;
var valEl = document.querySelector(".number dashtext-2");
var portfolioEl = document.querySelector(".number dashtext-3");
if (returnOfInvestment >= 0) {
valEl.style.color = "green";
portfolioEl.style.color = "green";
} else {
valEl.style.color = "red";
portfolioEl.style.color = "red";
}
.dashtext-2 {
color: #27b83f !important;
}
.dashtext-3 {
color: #27b83f !important;
}
<div class="col-md">
<div class="statistic-block block">
<div class="progress-details d-flex align-items-end justify-content-between">
<div class="title">
<div class="icon"><i class="icon-bars"></i></div>
<strong><div class="valdeval"></div></strong>
</div>
<div class="number dashtext-2">
<div class="valorization"></div>
</div>
</div>
</div>
</div>
<div class="col-md">
<div class="statistic-block block">
<div class="progress-details d-flex align-items-end justify-content-between">
<div class="title">
<div class="icon"><i class="icon-pie-chart"></i></div><strong> Portfolio</strong>
</div>
<div class="number dashtext-3">
<div class="totalportfolio"></div>
</div>
</div>
</div>
</div>
Give the elements you want to style a class and use CSS to apply a green text-color.
Create a class within CSS for a red text-color like: .color-red { color: red; }
Change the script slightly as below. Use classList.remove('.color-red'); to remove the class that changes the text-color to red or the same function with .add instead of .remove to apply the class for the red tex-color.
function changeStyle() {
var returnOfInvestment = document.getElementById('input-number').value;
var valEl = document.querySelector('.random-element'),
portfolioEl = document.querySelector('.portfolio-element');
if (returnOfInvestment >= 0) {
valEl.classList.remove('color-red');
portfolioEl.classList.remove('color-red');
} else {
valEl.classList.add('color-red');
portfolioEl.classList.add('color-red');
}
}
.random-element,
.portfolio-element {
color: green;
}
.color-red {
color: red;
}
<input type="number" id="input-number" name="input-number" onchange="changeStyle()">
<h1 class="random-element">Random element</h1>
<h1 class="portfolio-element">Portfolio element</h1>
Alternativly you could add a specific class to all elements you want to change color for. Then you can use this instead:
var allEL = document.querySelectorAll('.class-name');
if (returnOfInvestment >= 0) {
allEL.forEach(el => el.classList.remove('color-red'));
} else {
allEL.forEach(el => el.classList.add('color-red'));
}
}
That will apply/remove the class of all elements with a specific class. Really helpfull if you need to apply changes to multiple elements.
So I have a setup like this
<div class=“container”>
<div class=“segment segment1”></div>
<div class=“segment segment2”></div>
<div class=“segment segment3”></div>
.
.
.
<div class=“segmentN”></div>
</div>
Where N is an number defined by user so list is dynamical. For container I have applied styles to display it as grid, so EVERY time list has 3 items displayed, list is scrollable. My problem is, how can I via VanillaJS find element which is in the middle of container ? If there are 3 elements in the page, it should select 2nd one, when scrolling down it should select element which is in the middle of container every time to apply some styles to it in addition to grab it’s id. If there are 2 elements, it should select 2nd item as well. I was thinking about checking height of container, divide it by half and checking position of element if it’s in range. So far I was able to write this code in js
function findMiddleSegment() {
//selecting container
const segmentListContainer = document.querySelector(`.container`);
const rect = segmentListContainer.getBoundingClientRect();
//selecting all divs
const segments = document.querySelectorAll(`.segment`);
segments.forEach( (segment) => {
const location = segment.getBoundingClientRect();
if( (location.top >= rect.height / 2) ){
segment.classList.add(`midsegment`);
} else {
segment.classList.remove(`midsegment`);
}
});
}
But it doesn’t work. It finds element in the middle as should, but also applies style for every other element beneath middle segment. I’ve read some answers on stackoverflow, but couldn’t find any idea how to solve my problem.
EDIT
In addition to my problem I add additional function to show how I invoke it.
function handleDOMChange() {
findMiddleSegment(); //for "first run" when doc is loaded
const segmentListContainer = document.querySelector(`.container`);
segmentListContainer.addEventListener('scroll', findMiddleSegment);
}
A very easy way to do it is using the Intersection Observer:
const list = document.querySelector('ul'),
idDisplay = document.querySelector('p b');
const observer = new IntersectionObserver(
highlightMid,
{
root: list,
rootMargin: "-33.33% 0%",
threshold: .5
}
);
function makeList() {
list.innerHTML = '';
observer.disconnect();
const N = document.querySelector('input').value;
for (let i = 0; i < N;) {
const item = document.createElement('li');
item.id = `i_${++i}`;
item.textContent = `Item #${i}`;
list.append(item);
observer.observe(item);
}
};
function highlightMid(entries) {
entries.forEach(entry => {
entry.target.classList
.toggle('active', entry.isIntersecting);
})
const active = list.querySelector('.active');
if (active) idDisplay.textContent = '#' + active.id;
}
ul {
width: 50vw;
height: 50vh;
margin: auto;
padding: 0;
overflow-y: auto;
border: solid 1px;
}
li {
box-sizing: border-box;
height: 33.33%;
padding: .3em 1em;
list-style: none;
transition: .3s;
}
.active {
background: #6af;
}
<i>Make a list of:</i>
<input type="number" min="2" placeholder="number of items">
<button onclick="makeList()">make</button>
<p>Active id is <b>yet to set</b></p>
<ul></ul>
If container has only a list of segments inside, it's easer to count the element's children and find the mid element.
const segmentListContainer = document.querySelector(`.segmentListContainer`);
const midSegmentIndex = Math.floor(segmentListContainer.children.length / 2) - 1;
let midSegment = segmentListContaner.children[midSegmentIndex];
midSegment.classList.add('midsegment');
P.S.
The reason why your code adds 'mdsegment' to each element's class name after the real midsegment element is because of this conditional statement line you wrote.
if(location.top >= rect.height / 2){
segment.classList.add(`midsegment`);
}
Something like this. You can use Math.round, Math.ceil or Math.floor like I did. This works because querySelectorAll returns an array and you can use array.length to count the total number of items in the array then use a for loop to loop over all the segments and place the class based on the Math.(round, floor or ceil) based on your needs.
const container = document.querySelector(".container");
const segments = container.querySelectorAll(".segment");
const middleSegment = Math.floor(segments.length / 2);
for (let index = 0; index < segments.length; index++) {
segments[middleSegment].classList.add("middle-segment");
}
.middle-segment{
background-color: red;
}
<div class="container">
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
</div>
You don't need javascript for this. CSS will do
.container {
width: 350px;
}
.container .segment {
width: 100px;
height: 100px;
float: left;
background-color: #EEE;
border: 1px dotted gray;
margin: 3px;
text-align: center;
color: silver;
}
.segment:nth-child(3n-1) {
background-color: aquamarine;
color: black;
}
<div class="container">
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
</div>
This question already has answers here:
How to change div background color on button click?
(2 answers)
Closed 3 years ago.
I'm very new to coding and have learned my very limited knowledge from forums and tutorials online. I seem to be up against a problem that I cannot for the life of me figure out.
My goal is to press one of three buttons (Leadership, Program, Team) at the top of a grid (the grid lists our services) and have the appropriate grid box change colors. For example, pressing the Leadership button would turn a grid box blue, Program would turn a grid box yellow, and Team would turn a grid box green. This means that a grid box might be linked to more than one of the buttons, as our services overlap. So depending on what button is pressed, a single grid box might change to blue, yellow, or green.
I figured out how to do toggle buttons which show the body onclick. BUT that means A LOT of redundancy. (I would have to do a grid with the appropriately colored boxes for Leadership, another one for Program, and another one for Team). So, I think I'm on the wrong path there.
I've searched toggles, buttons, anchors, event listeners, targets, you name it. It seems like it all relates to the button itself, not how the button relates to an element on the page.
I am very grateful to anyone who can point me in the right direction! Thank you!
function goToAnchor(anchor) {
var loc = document.location.toString().split('#')[0];
document.location = loc + '#' + anchor;
return false;
}
var divs = ["Div1", "Div2", "Div3", "Div4"];
var visibleDivId = null;
function divVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
.square-grey {
display: table-cell;
height: 100px;
width: 600px;
text-align: center;
vertical-align: middle;
border-radius: 5%;
/*make it pretty*/
background: #F5F5F5;
color: #999999;
padding: 10px 15px 10px 15px;
font: 20px "helvetica";
font-weight: 350;
box-shadow: 2px 3px 3px #999999;
}
div.highlit {
padding: 25px;
}
<div class="row">
<div class="buttons">
<div style="text-align:center">
<div class="col-sm-4">
Enterprise
</div>
<div class="col-sm-4">
Program
</div>
<div class="col-sm-4">
Team
</div>
</div>
</div>
</div>
<div class="inner_div">
<div id="Div1">
<div class="row">
<div style="text-align:center">
<div class="col-sm-3">
<div class="top-buffer">
<div class="square-grey">
Strategic Alignment
</div>
</div>
</div>
<div class="col-sm-3">
<div class="top-buffer">
<div class="square-grey">
Adaptive Leadership
</div>
</div>
</div>
<div class="col-sm-3">
<div class="top-buffer">
<div class="square-grey">
Portfolio Management
</div>
</div>
</div>
<div class="col-sm-3">
<div class="top-buffer">
<div class="square-grey">
Cultural Shift
</div>
</div>
</div>
</div>
</div>
</div>
<div id="Div2" style="display: none;">I'm Div Two</div>
<div id="Div3" style="display: none;">I'm Div Three</div>
</div>
</div>
Edited answer, you can add IDs to the boxes and pass them to function.
const changeColor = (elements, color) => {
elements.forEach(el => {
const element = document.querySelector(el);
element.style.backgroundColor = color;
})
}
.colorbox {
width: 100px;
height: 100px;
background-color: aquamarine;
margin-bottom: 10px;
}
<div class="colorbox" id="colorbox1"></div>
<div class="colorbox" id="colorbox2"></div>
<div class="colorbox" id="colorbox3"></div>
<button onclick="changeColor(['#colorbox1', '#colorbox3'], 'tomato')">Change 1 & 3 to tomato</button>
<button onclick="changeColor(['#colorbox1', '#colorbox2'], 'aliceblue')">Change 1 & 2 to aliceblue</button>
<button onclick="changeColor(['#colorbox2', '#colorbox3'], '#ff0000')">Change 2 & 3 to reddest</button>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am new to Javascript and only have very basic knowledge of it at this stage.
I am trying to create a filter bar that, when clicked, would set the opacity of the non-matched items to 0.2 and the matched item would remain at full opacity.
I have uploaded the html/css to show an example on jsfiddle: https://jsfiddle.net/rebeccasmith1301/zw2aozff/
<div id="filter-bar">
<button onclick="findShoes()">Shoes</button>
<button onclick="findTops()">Tops</button>
<button onclick="findSkirts()">Skirts</button>
</div>
<div class="product-item">
<p>Shoes</p>
</div>
<div class="product-item">
<p>Tops</p>
</div>
Skirts
I have been experimenting with javascript written on a previous post that I found very helpful but due to my basic knowledge I have been unable to solve how to achieve the results I am aiming for.
I basically would like the user to be able to click on the button shoes (for example) and all of the divs that contain the word shoes to remain with full opacity and all other divs to have the class un-selected which lowers the opacity to 0.2. The divs that contain the products can be a class only, not an id as well.
Would anyone be able to help? This would be using mainly vanilla javascript.
Many thanks,
Becky
Fiddle with multiple words: https://jsfiddle.net/qucwvqfr/1/
Fiddle with white space removal: https://jsfiddle.net/d15v3x0w/1/
Don't make a function for each possible variation of content, just make one function and give that a parameter. This javascript would check the textContent of the items, strip the whitespace from them, and change classes accordingly. The hasClass, addClass, and removeClass are helpers, focus on the highlightItems function.
function hasClass(ele,cls) {
return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}
function addClass(ele,cls) {
if (!hasClass(ele,cls)) ele.className += " "+cls;
}
function removeClass(ele,cls) {
if (hasClass(ele,cls)) {
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
ele.className=ele.className.replace(reg,' ');
}
}
var highlightItems = function(itemName) {
var p = document.getElementsByClassName("product-item");
for (var i = 0; i < p.length; i++) {
itemText = p[i].textContent.replace(/^\s+|\s+$/g,''); // you don't need the .replace() part if you don't add extra white space in the HTML
if ( !(itemText == itemName) ) {
addClass(p[i], "un-selected");
} else {
removeClass(p[i], "un-selected");
}
}
}
And you would use it like this:
<div id="filter-bar">
<button onclick="highlightItems('Shoes')">Shoes</button>
<button onclick="highlightItems('Tops')">Tops</button>
<button onclick="highlightItems('Skirts')">Skirts</button>
</div>
Note:
If you want to have multiple words inside the box, don't add any unnecessary white space inside the div tags. (You probably shouldn't do it anyway.) So the HTML usage would be like this:
<div class="product-item">Shoes and socks</div>
<div class="product-item">Tops</div>
<div class="product-item">Skirts</div>
Credits for the class-changing functions go to http://jaketrent.com/post/addremove-classes-raw-javascript/
There needs to be a reliable way to select the specified items. I propose that you add a class shoes, tops and skirts to their respective elements:
<div class="product-item shoes">
Shoes
</div>
<div class="product-item tops">
Tops
</div>
<div class="product-item skirts">
Skirts
</div>
Now, to select all elements that got shoes it's really easy:
var shoes = document.getElementsByClassName('shoes');
Selecting elements that don't have a class shoes is another story. Let say we start by collecting out all product-item elements, like so:
var products = document.getElementsByClassName('product-item');
From here on, you need to iterate all the elements inside the returned nodeList and check if they got a shoes class. A helper function that can help you with that:
function not(nodeList, cls){
var reg = new RegExp('\\b' + cls + '\\b');
return Array.prototype.reduce.call(nodeList, function(acc, el){
console.log(el, el.className.search(reg))
if(el.className.match(reg) === null){
acc.push(el);
}
return acc;
}, []);
}
So now, to get products that aren't shoes:
var notShoes = not(products, 'shoes');
To change the opacity of all the elements inside a nodeList we could use another helper function:
function changeOpacity(nodeList, opacity){
Array.prototype.forEach.call(nodeList, function(el){
el.style.opacity = opacity;
});
}
And to use it:
changeOpacity(shoes, 1.0);
changeOpacity(notShoes, 0.2);
All together in this snippet:
function find(cls) {
var clsList = document.getElementsByClassName(cls);
var products = document.getElementsByClassName('product-item');
var notCls = not(products, cls);
changeOpacity(clsList, 1.0);
changeOpacity(notCls, 0.2);
}
function not(nodeList, cls){
var reg = new RegExp('\\b' + cls + '\\b');
return Array.prototype.reduce.call(nodeList, function(acc, el){
console.log(el, el.className.search(reg))
if(el.className.match(reg) === null){
acc.push(el);
}
return acc;
}, []);
}
function changeOpacity(nodeList, opacity){
Array.prototype.forEach.call(nodeList, function(el){
el.style.opacity = opacity;
});
}
/* Styling for filter bar*/
#filter-bar{
width: 100%
}
#filter-bar button{
width: 30%
float: left;
margin: 0.5%;
}
/* Styling for products*/
.product-item{
width: 24%;
float: left;
margin: 0.5%;
background-color: red;
height: 80px;
box-sizing: border-box;
padding: 10px;
}
/* Different options for products with button click*/
.un-selected{
opacity: 0.2;
}
<div id="filter-bar">
<button onclick="find('shoes')">Shoes</button>
<button onclick="find('tops')">Tops</button>
<button onclick="find('skirts')">Skirts</button>
</div>
<div class="product-item shoes">
Shoes
</div>
<div class="product-item tops">
Tops
</div>
<div class="product-item skirts">
Skirts
</div>
<div class="product-item skirts">
Skirts
</div>
<div class="product-item shoes">
Shoes
</div>
<div class="product-item tops">
Tops
</div>
<div class="product-item skirts">
Skirts
</div>
<div class="product-item skirts">
Skirts
</div>
I have a solution with jquery:
HTML
<button class="active btn" id="all">Show All</button>
<button class="btn" id="a">Tops</button>
<button class="btn" id="b">Skirts</button>
<button class="btn" id="c">Shoes</button>
<!-- An element with an id is needed for the jQuery -->
<div id="parent">
<!-- The base class is the box. Categories are then given as accessory classes. Any div can be in more than one category -->
<div class="box product-item a b">Shoes & Tops</div>
<div class="box product-item a">Tops</div>
<div class="box product-item b">Skirts</div>
<div class="box product-item c">Shoes</div>
</div>
CSS
/* Styling for filter bar*/
#filter-bar{
width: 100%
}
#filter-bar button{
width: 30%
float: left;
margin: 0.5%;
}
/* Styling for products*/
.product-item{
width: 24%;
float: left;
margin: 0.5%;
background-color: red;
height: 80px;
box-sizing: border-box;
padding: 10px;
}
/* Different options for products with button click*/
.un-selected{
opacity: 0.2;
}
jQuery
var $btns = $('.btn').click(function() {
if (this.id == 'all') {
$('#parent > div').fadeIn(450);
} else {
var $el = $('.' + this.id).fadeIn(450);
$('#parent > div').not($el).hide();
}
$btns.removeClass('active');
$(this).addClass('active');
})
jsfiddle
function filter(me) {
var items = document.getElementsByClassName("product-item");
console.log(me.textContent);
for (var i = 0; i < items.length; i++) {
var item = items[i];
item.style.display = "";
if (item.textContent.trim() !== me.textContent.trim() && me.textContent.trim() !== "All") {
item.style.display = "none";
}
}
}
/* Styling for filter bar*/
#filter-bar{
width: 100%
}
#filter-bar button{
width: 30%
float: left;
margin: 0.5%;
}
/* Styling for products*/
.product-item{
width: 24%;
float: left;
margin: 0.5%;
background-color: red;
height: 80px;
box-sizing: border-box;
padding: 10px;
}
/* Different options for products with button click*/
.un-selected{
opacity: 0.2;
}
<div id="filter-bar">
<button onclick="filter(this)">Shoes</button>
<button onclick="filter(this)">Tops</button>
<button onclick="filter(this)">Skirts</button>
<button onclick="filter(this)">All</button>
</div>
<div class="product-item">
Shoes
</div>
<div class="product-item">
Tops
</div>
<div class="product-item">
Skirts
</div>
<div class="product-item">
Skirts
</div>
<div class="product-item">
Shoes
</div>
<div class="product-item">
Tops
</div>
<div class="product-item">
Skirts
</div>
<div class="product-item">
Skirts
</div>