I'm making my own slide plugin using jQuery for practice. The problem is, I don't know why but some reason ternary operator doesn't work. The slider only responses when user clicks prev button which registered as a condition from the code.
I expected it should move to right side when user presses next button, but next button is totally broken.
I could just make 2 different trigger buttons and use multiple if statements for solving this problem, but I want to merge it on single line by using ternary operator and minifise my code as much as I can.
How would I solve this problem?
Code block:
(function($) {
$.fn.sliderModule = function(options) {
const defaults = {
myGallery: $(this)
};
var settings = $.extend({
myItems: null,
trigger: null,
current: null
}, defaults, options);
$(settings.trigger).on('click', function() {
if (!(defaults.myGallery.is(':animated'))) {
var movement = settings.trigger.hasClass('prev') ? -1 : 1
defaults.myGallery.animate({left: "+=" + (100 / settings.current) * movement + '%'}); // It doesn't respond the `next` button.
};
});
};
})(jQuery);
$(function() {
$('#slide-list').sliderModule({
myItems: '#img-slider',
trigger: $('#buttons').find('#button'),
current: 4
});
})
li {
list-style-type: none;
}
#slide-container {
position: relative !important;
width: 1170px;
margin: 0 auto;
overflow: hidden;
height: auto;
}
#slide-list {
margin: 0 auto;
position: relative;
display: flex;
width: 1170px;
}
#buttons {
width: 1170px;
margin: 0 auto;
display: flex;
justify-content: center;
}
#buttons li {
margin: 0 20px;
}
.slide-l-quarter {
flex-shrink: 0;
position: relative;
white-space: nowrap;
width: calc(100% / 4);
}
.slide-l-quarter img {
width: 100%;
height: auto;
}
<div id="slide-container">
<ul id="slide-list">
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/PVsHlX9.jpg" alt="">
</li>
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/WfWhNnU.jpg" alt="">
</li>
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/eqHdnNs.jpg" alt="">
</li>
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/0jziABY.jpg" alt="">
</li>
</ul>
</div>
<ul id="buttons">
<li id="button" class="prev">Prev</li>
<li id="button" class="next">Next</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
There is no problem with using ternary operators. But you made some mistakes along the way.
IDs must be unique
You cannot have this in your HTML:
<li id="button" class="prev">Prev</li>
<li id="button" class="next">Next</li>
If you need multiple elements to have the same selector, use a class instead:
<li class="button prev">Prev</li>
<li class="button next">Next</li>
settings.trigger selects both buttons
When you do this:
settings.trigger.hasClass('prev')
You're refering to both buttons. You only want the one clicked by the user:
$(this).hasClass('prev')
Fixed version
(function($) {
$.fn.sliderModule = function(options) {
const defaults = {
myGallery: $(this)
};
var settings = $.extend({
myItems: null,
trigger: null,
current: null
}, defaults, options);
$(settings.trigger).on('click', function() {
if (!(defaults.myGallery.is(':animated'))) {
var movement = $(this).hasClass('prev') ? -1 : 1;
defaults.myGallery.animate({left: "+=" + (100 / settings.current) * movement + '%'});
};
});
};
})(jQuery);
$(function() {
$('#slide-list').sliderModule({
myItems: '#img-slider',
trigger: $('#buttons').find('.button'),
current: 4
});
})
li {
list-style-type: none;
}
#slide-container {
position: relative !important;
width: 1170px;
margin: 0 auto;
overflow: hidden;
height: auto;
}
#slide-list {
margin: 0 auto;
position: relative;
display: flex;
width: 1170px;
}
#buttons {
width: 1170px;
margin: 0 auto;
display: flex;
justify-content: center;
}
#buttons li {
margin: 0 20px;
}
.slide-l-quarter {
flex-shrink: 0;
position: relative;
white-space: nowrap;
width: calc(100% / 4);
}
.slide-l-quarter img {
width: 100%;
height: auto;
}
<div id="slide-container">
<ul id="slide-list">
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/PVsHlX9.jpg" alt="">
</li>
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/WfWhNnU.jpg" alt="">
</li>
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/eqHdnNs.jpg" alt="">
</li>
<li class="slide-l-quarter" id="image-slider">
<img src="https://i.imgur.com/0jziABY.jpg" alt="">
</li>
</ul>
</div>
<ul id="buttons">
<li class="button prev">Prev</li>
<li class="button next">Next</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
Tried a few different JavaScript options and I am hoping it is something really simple that I am missing.
Several attempts and Google searches as to how exactly I do this seems to lead me on a road to nowhere for every different solution so far.
Any suggestions as to how to fix this would be apppreciated.
window.onscroll = function() {
scrollFunction()
};
function scrollFunction() {
if (document.body.scrollTop > 80 || document.documentElement.scrollTop > 80) {
document.getElementsByClassName(".navbar").style.backgroundColor = "transparent";
} else {
document.getElementsByClassName(".navbar").style.backgroundColor = "black";
}
}
ul {
padding: 0;
margin: 0;
}
ul li {
list-style-type: none;
}
.hero-img {
filter: brightness(30%);
background-size: cover;
}
.hero-image-overlay {
width: 50%;
margin: 0 auto;
padding: 1rem 0;
}
.navbar {
padding: 0;
background-color: transparent;
position: fixed;
top: 0;
width: 100%;
}
.navbar ul {
display: flex;
position: relative;
}
.navbar ul li {
padding: .5rem 0;
color: white;
padding: 1rem;
width: 100%;
}
ul a {
display: inline-block;
}
.nav-img {
width: 175px;
}
.header-li:hover,
.header-li:focus {
color: orangered;
transition: all .3s;
}
.header-li {
display: none;
}
.news-posts {
max-width: 1250px;
columns: 500px 2;
margin: 0 auto;
}
<html>
<body>
<!-- start of Header area -->
<header>
<div class="hero-image">
<img class="hero-img" src="img/lower-height-team-photo.jpg" alt="team-photo">
</div>
<nav class="navbar">
<ul class="header-ul">
<a href="#">
<li class="img-li"><img src="img/imageedit_3_3953793469.png" alt="" class="nav-img"></li>
</a>
<a href="#">
<li class="header-li">About Us</li>
</a>
<a href="#">
<li class="header-li">Team</li>
</a>
<a href="#">
<li class="header-li">Fixtures/Results</li>
</a>
<a href="#">
<li class="header-li">News</li>
</a>
<a href="#">
<li class="header-li">Contact</li>
</a>
</ul>
<i class="fa fa-bars fa-2x"></i></>
</nav>
</header>
</body>
</html>
Many thanks to any solutions you can offer.
Firstly, remove . sign when getting element by class name, it should be
document.getElementsByClassName("navbar")
and not
document.getElementsByClassName(".navbar")
Also, take a note that getElementsByClassName returns an array so, in order to set a background color to work, it should be something like this:
document.getElementsByClassName(".navbar")[0].style.backgroundColor = "black";
This is complete javascript code
function scrollFunction() {
if (document.body.scrollTop > 80 || document.documentElement.scrollTop > 80) {
document.getElementsByClassName("navbar")[0].style.backgroundColor = "transparent";
} else {
document.getElementsByClassName("navbar")[0].style.backgroundColor = "black";
}
}
// Do not forget to call the function
scrollFunction();
Also remove display: none in header-li class
I want to create a sidebar with a submenu that extends to the right instead of down. A rough picture below:
I'm fairly new with flexbox and that is all I could come up with:
HTML:
<div class="d-flex align-items-stretch">
<nav class="side-navigation">
<ul class="sidebar-nav d-flex flex-column">
<li class="sidebar-nav-expand d-flex toggle">
<a class="nav-link sidebar-nav-expand-toggle py-3" href="#">
<span class="icon icon-ic_compute"></span>
<span class="nav-item-text">Menu1</span>
<span class="float-right"><i class="fas fa-mortar-pestle"></i></span>
</a>
<div class="sidebar-nav-expand-items">
<ul class="sidebar-nav">
<li class="sidebar-nav-item py-3">
<a class="nav-link py-1" href="#some-url1">
<span class="nav-item-text">Menu1 subitem1</span>
</a>
</li>
<li class="sidebar-nav-item py-3">
<a class="nav-link py-1" href="#some-url2">
<span class="nav-item-text">Menu1 subitem2</span>
</a>
</li>
<li class="sidebar-nav-item py-3">
<a class="nav-link py-1" href="#some-url3">
<span class="nav-item-text">Menu1 subitem3</span>
</a>
</li>
</ul>
</div>
</li>
<li class="sidebar-nav-expand d-flex">
<a class="nav-link sidebar-nav-expand-toggle py-3" href="#">
<span class="icon icon-ic_management"></span>
<span class="nav-item-text">Menu2</span>
<span class="float-right"><i class="fas fa-mortar-pestle"></i></span>
</a>
<div class="sidebar-nav-expand-items">
<ul class="sidebar-nav">
<li class="sidebar-nav-item py-3">
<a class="nav-link py-1" href="#some-url21">
<span class="nav-item-text">Menu2 subitem1</span>
</a>
</li>
<li class="sidebar-nav-item py-3">
<a class="nav-link py-1" href="#some-url22">
<span class="nav-item-text">Menu2 subitem2</span>
</a>
</li>
<li class="sidebar-nav-item py-3">
<a class="nav-link py-1" href="#some-url23">
<span class="nav-item-text">Menu2 subitem3</span>
</a>
</li>
</ul>
</div>
</li>
<li class="sidebar-nav-expand">
<a class="nav-link py-3" href="#some-url">
<span class="icon icon-ic_administration"></span>
<span class="nav-item-text">Direct link</span>
<span class="float-right"><i class="fas fa-mortar-pestle"></i></span>
</a>
</li>
</ul>
</nav>
<div class="main">
Content
</div>
</div>
SCSS:
$white: #fff;
$whitesmoke: #ECEFF1;
$aliceblue: #f1f6ff;
$light-gray: #D6DADC;
$blue: #2971FB;
$light-blue: #BFD5FE;
$black: #263238;
$light-black: #364046;
$orange: #FF8F00;
.side-navigation {
max-width: 540px;
transition: all 0.3s;
}
.sidebar-nav {
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding-left: 0;
margin-bottom: 0;
list-style: none;
.nav-link {
display: block;
padding: .75rem 1rem;
color: $white;
text-decoration: none;
background: 0 0;
&:hover {
color: $orange;
}
}
.sidebar-nav-item {
width: 100%;
}
.sidebar-nav-expand {
width: 100%;
background-color: $black;
&.toggle {
.sidebar-nav-expand-toggle {
color: $orange;
}
.sidebar-nav-expand-items {
margin-left: 0;
}
}
.sidebar-nav-expand-toggle {
width: 270px;
z-index: 2;
}
.sidebar-nav-expand-items {
width: 270px;
height: 100%;
background-color: $light-gray;
transition: margin-left .25s ease-in-out;
margin-left: -270px;
color: $black;
.nav-link {
color: $black;
&:hover {
color: $orange;
}
&:not(.active) {
margin-left: 8px;
}
&.active {
border-left: solid 8px $orange;
}
}
}
}
}
.main {
width: 100%;
min-height: 100vh;
padding-left: 10px;
}
JS:
$('.sidebar-nav-expand-toggle').on('click', function() {
let self = $(this);
self.parent('.sidebar-nav-expand').toggleClass('toggle');
$('.main').toggleClass('toggle');
});
https://jsfiddle.net/cj4375er/
As you can see the child is not properly hidden under the parent and submenus are stacked, if a menu is opened I want all other menus to close. Also, there is too much space between menu items.
I would just need some points in the right direction. If there is an example of a similar case I would be happy.
I see that you tried to cover the submenu bar using z-index: 2 at that sidebar-nav-expand-toggle. However, your items are not properly hidden because your sidebar-nav-expand-toggle has no background (i.e. it's transparent). The background is actually from sidebar-nav-expand (#263238) that bleeds through the sidebar-nav-expand-toggle because sidebar-nav-expand-toggle is transparent. Therefore, the solution is to instruct the sidebar-nav-expand-toggle to inherit the same background as its parent, resulting in this code below:
.sidebar-nav-expand-toggle {
width: 270px;
z-index: 2;
background: inherit;
}
Your menus are stacked because you did not handle the closing of the other submenus that may be open (you merely toggled the one that is clicked, but you didn't close the ones that may be open that are not clicked). A simple addition to your JS code fixes this:
$('.sidebar-nav-expand-toggle').on('click', function() {
let self = $(this);
let toggled = self.parent('.sidebar-nav-expand').hasClass('toggle')
hideAllSubmenu()
if (toggled)
self.parent('.sidebar-nav-expand').removeClass('toggle')
else
self.parent('.sidebar-nav-expand').addClass('toggle')
$('.main').toggleClass('toggle');
});
function hideAllSubmenu() {
let submenus = $('.sidebar-nav-expand-toggle')
submenus.parent('.sidebar-nav-expand').removeClass('toggle')
}
There is too much space between menu items. My suggestion would be to make a flexbox that has only the three menu items with padding. And then, for each of those menus (can be a or div), create a div inside it that has position: absolute based on those menus. You can then slide it out when clicked by using transform: translate. That way, the height is not dependent on a wrapping container's height.
Also, I see that you are using SCSS. I really suggest reading about BEM selectors here to better utilize SCSS to create a more easily readable code.
EDIT:
I've added a little working example of what I meant by using position: absolute and still being able to push the main content to the right when the submenu expands. Take a look below (please adjust this minimal working example to what you need):
function resetSubmenuStyles() {
let submenus = document.querySelectorAll('.submenu div')
for (let submenu of submenus) {
submenu.style.width = ''
submenu.style.visibility = ''
}
}
document.querySelector('#menuOne').addEventListener('click', e => {
let submenu = document.querySelector('.submenu')
let submenuOne = document.querySelector('#submenuOne')
let submenuStyle = window.getComputedStyle(submenuOne)
let submenuWidth = parseInt(submenuStyle.getPropertyValue('width')) - parseInt(submenuStyle.getPropertyValue('padding-left')) - parseInt(submenuStyle.getPropertyValue('padding-right'))
resetSubmenuStyles()
if (submenuWidth == 0) {
submenu.style.width = '20%'
submenuOne.style.width = '100%'
submenuOne.style.visibility = 'visible'
}
else {
submenu.style.width = ''
submenuOne.style.width = ''
submenuOne.style.visibility = ''
}
})
document.querySelector('#menuTwo').addEventListener('click', e => {
let submenu = document.querySelector('.submenu')
let submenuTwo = document.querySelector('#submenuTwo')
let submenuStyle = window.getComputedStyle(submenuTwo)
let submenuWidth = parseInt(submenuStyle.getPropertyValue('width')) - parseInt(submenuStyle.getPropertyValue('padding-left')) - parseInt(submenuStyle.getPropertyValue('padding-right'))
resetSubmenuStyles()
if (submenuWidth == 0) {
submenu.style.width = '20%'
submenuTwo.style.width = '100%'
submenuTwo.style.visibility = 'visible'
}
else {
submenu.style.width = ''
submenuTwo.style.width = ''
submenuTwo.style.visibility = ''
}
})
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Helvetica, sans-serif;
}
html, body {
width: 100vw;
height: 100%;
}
body {
display: flex;
}
.menu {
width: 20%;
height: 100%;
background: #000;
color: #FFF;
}
.menu h1 {
padding: 20px;
cursor: pointer;
}
.submenu {
position: relative;
width: 0%;
height: 100%;
background: #333;
color: #FFF;
}
.submenu div {
visibility: hidden;
position: absolute;
width: 0;
top: 0;
left: 0;
padding: 20px;
}
<div class = "menu">
<h1 id = "menuOne">Test</h1>
<h1 id = "menuTwo">Test</h1>
</div>
<div class = "submenu">
<div id = "submenuOne">
Submenu Test One
</div>
<div id = "submenuTwo">
Submenu Test Two
</div>
</div>
<div id = "main">Some Content</div>
i am try to make just simple slider of images
images in img tag not a background image
all images have display:none only first li have active class active class is display:block
click on button add active class to only next one li and remove active from pre li
i try but it active class add with all next li tag on click on button
var btn_next = document.getElementById('next-btn');
btn_next.onclick = function() {
if ($('#main_chagen li').hasClass('acitve') === true) {
$('#main_chagen li.acitve').removeClass('acitve')
$('#main_chagen li').next().addClass('acitve');
} else {
}
}
.main_chagen {
width: 100%;
float: left;
position: relative;
}
#main_chagen img {
width: 100%;
height: 26rem;
object-fit: cover;
}
#next-btn,
#pre-btn {
position: absolute;
top: 15rem;
padding: 5px 20px;
}
#next-btn {
right: 0;
}
#pre-btn {
left: 0;
}
#main_chagen li {
display: none;
}
.img_acitve {
display: block !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<ul id="main_chagen">
<li class="acitve">
<img src="1.jpg">
</li>
<li>
<img src="2.jpg">
</li>
<li>
<img src="3.jpg">
</li>
<li>
<img src="4.jpg">
</li>
<li>
<img src="5.jpg">
</li>
</ul>
<button id="next-btn">next</button>
<button id="pre-btn">pre</button>
</div>
Here is a working example.
You will need to study it a bit
$(function() {
$('button').on("click", function() {
var $cur = $('#main_chagen li.active'); // possibly active
var max = $('#main_chagen li').length; // max number of LIs
var dir = this.id.indexOf("next") === 0 ? 1:-1; // which button
var idx = $cur.length === 0 ? 0 : $cur.index()+dir; // find the index of what we want to show
if (idx >= max) idx = 0; // are we at end or beginning
if (idx < 0) idx = max-1;
$('#main_chagen li').removeClass("active").eq(idx).addClass("active");
})
$("#next-btn").click(); // show the first
});
.main_chagen {
width: 100%;
float: left;
position: relative;
}
#main_chagen img {
width: 100%;
height: 26rem;
object-fit: cover;
}
#next-btn,
#pre-btn {
position: absolute;
top: 15rem;
padding: 5px 20px;
}
#next-btn {
right: 0;
}
#pre-btn {
left: 0;
}
#main_chagen li {
display: none;
}
li.active {
display: block !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<ul id="main_chagen">
<li>
<img src="https://via.placeholder.com/150/0000FF/808080?text=1">
</li>
<li>
<img src="https://via.placeholder.com/150/0000FF/080808?text=2">
</li>
<li>
<img src="https://via.placeholder.com/150/FF00FF/808080?text=3">
</li>
<li>
<img src="https://via.placeholder.com/150/00FFFF/808080?text=4">
</li>
<li>
<img src="https://via.placeholder.com/150/AABBFF/808080?text=5">
</li>
</ul>
<button id="next-btn">next</button>
<button id="pre-btn">pre</button>
</div>
As the title states, I am wanting my hamburger navbar to close when I click on the tags I have tried many ways for the last couple hours but am unable to solve my problem?
I Have tried setting the hide() property with jquery but no luck think it may be because i am pretty new to JS and am just wanting to get my website finished.
const menuBtn = document.querySelector(".menu-btn");
const mobileContent = document.querySelector(".mobile-content");
const mobileItem = document.querySelector(".mobile-item");
const mobileItems = document.querySelectorAll(".mobile-items");
// Set Initial State Of Menu
let showMenu = false;
menuBtn.addEventListener("click", toggleMenu);
function toggleMenu() {
if (!showMenu) {
menuBtn.classList.add("close");
mobileContent.classList.add("show");
mobileItem.classList.add("show");
mobileItems.forEach(item => item.classList.add("show"));
// Set Menu State
showMenu = true;
} else {
menuBtn.classList.remove("close");
mobileContent.classList.remove("show");
mobileItem.classList.remove("show");
mobileItems.forEach(item => item.classList.remove("show"));
// Set Menu State
showMenu = false;
}
}
.mobile-nav {
display: block;
position: fixed;
width: 100%;
top: 0;
z-index: 3;
}
.mobile-nav .menu-btn {
position: absolute;
z-index: 3;
right: 20px;
top: 20px;
cursor: pointer;
}
.mobile-nav .menu-btn .btn-line {
width: 28px;
height: 3px;
margin: 0 0 5px 0;
background: #333;
}
.mobile-content {
position: fixed;
top: 0;
width: 100%;
opacity: 0.9;
visibility: hidden;
}
.mobile-content.show {
visibility: visible;
}
.mobile-content .mobile-item {
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
float: right;
width: 100%;
height: 100vh;
overflow: hidden;
margin: 0;
padding: 0;
background: blue;
list-style: none;
transform: translate3d(0, -100%, 0);
}
.mobile-content .mobile-link {
display: inline-block;
position: relative;
font-size: 2rem;
padding: 1rem 0;
font-weight: bold;
color: #333;
text-decoration: none;
}
<!-- Mobile Nav -->
<div class="mobile-nav">
<div class="menu-btn">
<div class="btn-line"></div>
<div class="btn-line"></div>
<div class="btn-line"></div>
</div>
<h2>MATTY</h2>
<nav class="mobile-content">
<ul class="mobile-item">
<li class="mobile-items">
<a href="#about-me" class="mobile-link">
ABOUT
</a>
</li>
<li class="mobile-items">
<a href="#the-portfolio" class="mobile-link">
PORTFOLIO
</a>
</li>
<li class="mobile-items">
<a href="#" class="mobile-link">
BLOG
</a>
</li>
<li class="mobile-items">
<a href="#contact-me" class="mobile-link">
CONTACT
</a>
</li>
</ul>
</nav>
</div>
I had to remove some of your CSS as it was not working in the snippet.
Recommend you use element.classList.toggle() as below.
Note how much simpler the code becomes.
EDIT: Clicking any a tag will now close menu
document.addEventListener("click", (e) => {
if(e.target.matches('.menu-btn')
|| e.target.matches('.btn-line')
|| e.target.matches('a')) {
toggleMenu();
}
});
function toggleMenu() {
document.querySelector('.mobile-content').classList.toggle('hide');
}
.btn-line {
display: block;
width: 50px;
margin: 5px;
border: 2px solid black;
}
.mobile-nav {
display: block;
width: 100%;
z-index: 3;
}
.mobile-content {
position: fixed;
width: 100%;
opacity: 0.9;
}
.hide {
display: none;
}
<!-- Mobile Nav -->
<div class="mobile-nav">
<div class="menu-btn">
<span class="btn-line"></span>
<span class="btn-line"></span>
<span class="btn-line"></span>
</div>
<a href="#home">
<h2>MATTY</h2>
</a>
<nav class="mobile-content hide">
<ul class="mobile-item">
<li class="mobile-items">
<a href="#about-me" class="mobile-link">
ABOUT
</a>
</li>
<li class="mobile-items">
<a href="#the-portfolio" class="mobile-link">
PORTFOLIO
</a>
</li>
<li class="mobile-items">
<a href="#" class="mobile-link">
BLOG
</a>
</li>
<li class="mobile-items">
<a href="#contact-me" class="mobile-link">
CONTACT
</a>
</li>
</ul>
</nav>
</div>
#MPB A good way to dabble into some simple JQuery language is a way to fix your problem. A quick and easy way to make a good Hamburger Navigation menue is with the toggleClass(); function in JQuery. Just make a #keyframes-animation within an un-set class and toggleClass(); will switch between the two seamlessly. I do this all the time, comment if you'd like me to forward the code to you for you to use.
I have a simple tabbed gallery which I managed to make with setAttribute.
But sometimes when I click in one of my thumbnails, setAttribute returns "null"
not always but sometimes it does.
And I'm not understanding why is this happening.
I'll appreciate your help.
here is a link to code:
code
and here is my code:
var tabs = document.querySelector('.tabs');
var tab = document.querySelectorAll('.tab');
var showTab = document.querySelector('.showtab');
var img = document.querySelector('.showtabimg');
tab.forEach(thumbNail => {
thumbNail.addEventListener('click', function(item) {
// delete all active or normal elements active class
tab.forEach(i => i.classList.remove('active'));
var content = item.target.getAttribute("src");
this.classList.toggle('active')
img.setAttribute('src', content);
});
});
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul li{
list-style: none;
}
.showtab{
width: 200px;
height: 100px;
color: red;
font-weight: bold;
display: flex;
margin-bottom: 20px;
}
.showtab img{
width: 100%;
}
.tabs{
display: flex;
}
.tabs li{
display: flex;
cursor: pointer;
width: 100px;
height: 100px;
margin-right: 10px;
}
.tabs li img{
width: 100%;
}
.active{
opacity: 1 !important;
}
.inActive{
opacity: .3;
}
<div class="tab-container">
<div class="showtab active">
<img class='showtabimg' src="https://images.unsplash.com/photo-1516308354296-1c9c5b561e0b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="showtabimg">
</div>
<ul class="tabs">
<li class="tab tab1 inActive active">
<img src="https://images.unsplash.com/photo-1516308354296-1c9c5b561e0b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="foto1" class='img '>
</li>
<li class="tab tab2 inActive">
<img src="https://images.unsplash.com/photo-1513346940221-6f673d962e97?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="foto2" class='img'>
</li>
<li class="tab tab3 inActive">
<img src="https://images.unsplash.com/photo-1475489991311-e12f9e89705e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1352&q=80" alt="foto3" class='img'>
</li>
</ul>
</div>
PS:
I have read this but it doesn't answer my question.
document.getElementById sometimes returns null