How do make this stack cards effect without position:sticky css? - javascript

How do i ignore position:sticky properties and make this same effect without position sticky? Because lots of browser does nto support this sticky position. You will see there is stack-cards__item class name has a css that called position:sticky.. is there any way where i can ignore this css and keep this same stacking cards effect..
<script>document.getElementsByTagName("html")[0].className += " js";</script>
<style>
.container {
width: 100%;
margin-left: auto;
margin-right: auto; }
.col {
max-width: 100%; }
.is-visible {
display: block !important; }
.is-hidden {
display: none !important; }
.stack-cards {
--stack-cards-gap: 10; }
.stack-cards__item {
position: relative;
position: -webkit-sticky;
position: sticky;
top: 10;
height: 0;
padding-bottom: 50%;
-webkit-transform-origin: center top;
transform-origin: center top;
overflow: hidden; }
.stack-cards__item > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%; }
</style>
<div class="container max-width-adaptive-md margin-bottom-lg">
<ul class="stack-cards js-stack-cards">
<li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
<div class="grid">
<div class="col-6 flex items-center height-100%">
<div class="text-component padding-md ">
<h2>Card One</h2>
<p class="display#xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
<p>Read more</p>
</div>
</div>
<div class="col-6 height-100%">
<img class="block width-100% height-100% object-cover" src="assets/img/img-1.jpg" alt="Image description">
</div>
</div>
</li>
<li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
<div class="grid">
<div class="col-6 flex items-center height-100%">
<div class="text-component padding-md ">
<h2>Card Two</h2>
<p class="display#xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
<p>Read more</p>
</div>
</div>
<div class="col-6 height-100%">
<img class="block width-100% height-100% object-cover" src="assets/img/img-2.jpg" alt="Image description">
</div>
</div>
</li>
<li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
<div class="grid">
<div class="col-6 flex items-center height-100%">
<div class="text-component padding-md ">
<h2>Card Three</h2>
<p class="display#xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
<p>Read more</p>
</div>
</div>
<div class="col-6 height-100%">
<img class="block width-100% height-100% object-cover" src="assets/img/img-3.jpg" alt="Image description">
</div>
</div>
</li>
</ul>
</div>
<div class="container max-width-adaptive-sm">
<div class="text-component line-height-lg v-space-md">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Rem repellat non ratione eum provident quaerat obcaecati dicta autem voluptates sit cum quis distinctio, atque sint commodi reprehenderit perspiciatis iure velit molestiae eos molestias ipsa nihil quia? Porro tempore in fugit, aspernatur et temporibus aliquam magnam adipisci deleniti dicta repellat alias nostrum impedit quidem odit excepturi nam. Itaque numquam unde quae dignissimos exercitationem placeat, ipsa amet tempora vitae ullam animi! Hic asperiores in esse atque expedita dolorem officia illo commodi fugit earum ab, assumenda optio, sed repellat. Maiores laudantium reprehenderit suscipit accusamus assumenda, debitis nemo ut sapiente numquam doloremque alias explicabo minus autem harum illum dicta. Unde obcaecati inventore repellat id eligendi eaque, rerum aliquam maiores aspernatur cumque tenetur quo qui mollitia atque quasi voluptate ipsum neque explicabo voluptatem quibusdam beatae quae iste vero doloribus! Natus libero quibusdam molestias harum atque, assumenda doloribus quis, quam corporis, voluptas suscipit magni! Enim sapiente totam consequatur repellat maxime placeat perferendis iste maiores soluta, obcaecati incidunt expedita eius cumque ipsa quo sed. Minus distinctio culpa cumque labore nulla laborum ex, explicabo magni mollitia eaque aliquam vero blanditiis quae, id necessitatibus error voluptas harum tempora sint porro. Facilis beatae quasi soluta et ipsum suscipit repellendus inventore.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Possimus, ipsam molestias. Fuga similique, dolor tempora rerum perferendis ipsam ullam doloribus beatae esse facilis quae sit excepturi expedita non, sunt accusantium magnam? Animi nesciunt nostrum eligendi iusto voluptatum hic qui. Quod distinctio qui nobis et doloremque. Fuga, itaque? Laborum dignissimos nobis quaerat optio voluptatum similique unde, neque cupiditate, vel, fugiat dolore? Accusantium neque deserunt ducimus enim, illum laborum magni ipsam eos optio aspernatur nam necessitatibus quod natus, dolor laboriosam illo velit.</p>
</div>
</div>
<script>
(function() {
var StackCards = function(element) {
this.element = element;
this.items = this.element.getElementsByClassName('js-stack-cards__item');
this.scrollingFn = false;
this.scrolling = false;
initStackCardsEffect(this);
initStackCardsResize(this);
};
function initStackCardsEffect(element) { // use Intersection Observer to trigger animation
setStackCards(element); // store cards CSS properties
var observer = new IntersectionObserver(stackCardsCallback.bind(element), { threshold: [0, 1] });
observer.observe(element.element);
};
function initStackCardsResize(element) { // detect resize to reset gallery
element.element.addEventListener('resize-stack-cards', function(){
setStackCards(element);
animateStackCards.bind(element);
});
};
function stackCardsCallback(entries) { // Intersection Observer callback
if(entries[0].isIntersecting) {
if(this.scrollingFn) return; // listener for scroll event already added
stackCardsInitEvent(this);
} else {
if(!this.scrollingFn) return; // listener for scroll event already removed
window.removeEventListener('scroll', this.scrollingFn);
this.scrollingFn = false;
}
};
function stackCardsInitEvent(element) {
element.scrollingFn = stackCardsScrolling.bind(element);
window.addEventListener('scroll', element.scrollingFn);
};
function stackCardsScrolling() {
if(this.scrolling) return;
this.scrolling = true;
window.requestAnimationFrame(animateStackCards.bind(this));
};
function setStackCards(element) {
// store wrapper properties
element.marginY = getComputedStyle(element.element).getPropertyValue('--stack-cards-gap');
getIntegerFromProperty(element); // convert element.marginY to integer (px value)
element.elementHeight = element.element.offsetHeight;
// store card properties
var cardStyle = getComputedStyle(element.items[0]);
element.cardTop = Math.floor(parseFloat(cardStyle.getPropertyValue('top')));
element.cardHeight = Math.floor(parseFloat(cardStyle.getPropertyValue('height')));
// store window property
element.windowHeight = window.innerHeight;
// reset margin + translate values
if(isNaN(element.marginY)) {
element.element.style.paddingBottom = '0px';
} else {
element.element.style.paddingBottom = (element.marginY*(element.items.length - 1))+'px';
}
for(var i = 0; i < element.items.length; i++) {
if(isNaN(element.marginY)) {
element.items[i].style.transform = 'none;';
} else {
element.items[i].style.transform = 'translateY('+element.marginY*i+'px)';
}
}
};
function getIntegerFromProperty(element) {
var node = document.createElement('div');
node.setAttribute('style', 'opacity:0; visbility: hidden;position: absolute; height:'+element.marginY);
element.element.appendChild(node);
element.marginY = parseInt(getComputedStyle(node).getPropertyValue('height'));
element.element.removeChild(node);
};
function animateStackCards() {
if(isNaN(this.marginY)) { // --stack-cards-gap not defined - do not trigger the effect
this.scrolling = false;
return;
}
var top = this.element.getBoundingClientRect().top;
if( this.cardTop - top + this.element.windowHeight - this.elementHeight - this.cardHeight + this.marginY + this.marginY*this.items.length > 0) {
this.scrolling = false;
return;
}
for(var i = 0; i < this.items.length; i++) { // use only scale
var scrolling = this.cardTop - top - i*(this.cardHeight+this.marginY);
if(scrolling > 0) {
var scaling = i == this.items.length - 1 ? 1 : (this.cardHeight - scrolling*0.05)/this.cardHeight;
this.items[i].style.transform = 'translateY('+this.marginY*i+'px) scale('+scaling+')';
} else {
this.items[i].style.transform = 'translateY('+this.marginY*i+'px)';
}
}
this.scrolling = false;
};
// initialize StackCards object
var stackCards = document.getElementsByClassName('js-stack-cards'),
intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype),
reducedMotion = Util.osHasReducedMotion();
if(stackCards.length > 0 && intersectionObserverSupported && !reducedMotion) {
var stackCardsArray = [];
for(var i = 0; i < stackCards.length; i++) {
(function(i){
stackCardsArray.push(new StackCards(stackCards[i]));
})(i);
}
var resizingId = false,
customEvent = new CustomEvent('resize-stack-cards');
window.addEventListener('resize', function() {
clearTimeout(resizingId);
resizingId = setTimeout(doneResizing, 500);
});
function doneResizing() {
for( var i = 0; i < stackCardsArray.length; i++) {
(function(i){stackCardsArray[i].element.dispatchEvent(customEvent)})(i);
};
};
}
}());
</script>

Almost there, still a little problem with what comes after the cards: it appears below the sticky cards. You can fix that fiddling with z-index.
The principle is that any time a card comes to the top of the viewport, we clone it, position the clone as fixed, and make the original card invisible.
Better viewed in full page mode:
const cards = document.querySelectorAll('.stack-cards__item');
cards.forEach(card => card.style.zIndex = 1);
const offsetTop = cards[0].getBoundingClientRect().y - document.body.getBoundingClientRect().y;
window.addEventListener('scroll', _e => {
cards.forEach((card, index) => {
const pos = card.getBoundingClientRect();
const STICK_AT = 10;
if (pos.y < offsetTop) {
//console.log(pos.y, pos.height);
if (!card.stickyClone) {
card.stickyClone = card.cloneNode(true);
card.stickyClone.style.position = 'fixed';
card.stickyClone.style.width = '100%';
card.stickyClone.style.zIndex = 0;
card.stickyClone.style.top = offsetTop + 'px';
card.parentNode.append(card.stickyClone);
card.style.visibility = 'hidden';
}
} else if (card.stickyClone) {
card.style.visibility = '';
card.stickyClone.remove();
card.stickyClone = null;
}
});
});
.container {
background: white; /* added that for tests */
width: 100%;
margin-left: auto;
margin-right: auto;
}
.col {
max-width: 100%;
}
.is-visible {
display: block !important;
}
.is-hidden {
display: none !important;
}
.stack-cards {
--stack-cards-gap: 10;
}
.stack-cards__item {
position: relative;
top: 10px;
height: 100vh;
-webkit-transform-origin: center top;
transform-origin: center top;
overflow: hidden;
}
.stack-cards__item > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<div class="container max-width-adaptive-md margin-bottom-lg">
<ul class="stack-cards js-stack-cards">
<li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
<div class="grid">
<div class="col-6 flex items-center height-100%">
<div class="text-component padding-md ">
<h2>Card One</h2>
<p class="display#xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
<p>Read more</p>
</div>
</div>
<div class="col-6 height-100%">
<img class="block width-100% height-100% object-cover" src="https://picsum.photos/seed/card1/200/300" alt="Image description">
</div>
</div>
</li>
<li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
<div class="grid">
<div class="col-6 flex items-center height-100%">
<div class="text-component padding-md ">
<h2>Card Two</h2>
<p class="display#xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
<p>Read more</p>
</div>
</div>
<div class="col-6 height-100%">
<img class="block width-100% height-100% object-cover" src="https://picsum.photos/seed/card2/200/300" alt="Image description">
</div>
</div>
</li>
<li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
<div class="grid">
<div class="col-6 flex items-center height-100%">
<div class="text-component padding-md ">
<h2>Card Three</h2>
<p class="display#xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
<p>Read more</p>
</div>
</div>
<div class="col-6 height-100%">
<img class="block width-100% height-100% object-cover" src="https://picsum.photos/seed/card3/200/300" alt="Image description">
</div>
</div>
</li>
</ul>
</div>
<div class="container max-width-adaptive-sm">
<div class="text-component line-height-lg v-space-md">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Rem repellat non ratione eum provident quaerat obcaecati dicta autem voluptates sit cum quis distinctio, atque sint commodi reprehenderit perspiciatis iure velit molestiae eos molestias ipsa
nihil quia? Porro tempore in fugit, aspernatur et temporibus aliquam magnam adipisci deleniti dicta repellat alias nostrum impedit quidem odit excepturi nam. Itaque numquam unde quae dignissimos exercitationem placeat, ipsa amet tempora vitae ullam
animi! Hic asperiores in esse atque expedita dolorem officia illo commodi fugit earum ab, assumenda optio, sed repellat. Maiores laudantium reprehenderit suscipit accusamus assumenda, debitis nemo ut sapiente numquam doloremque alias explicabo minus
autem harum illum dicta. Unde obcaecati inventore repellat id eligendi eaque, rerum aliquam maiores aspernatur cumque tenetur quo qui mollitia atque quasi voluptate ipsum neque explicabo voluptatem quibusdam beatae quae iste vero doloribus! Natus
libero quibusdam molestias harum atque, assumenda doloribus quis, quam corporis, voluptas suscipit magni! Enim sapiente totam consequatur repellat maxime placeat perferendis iste maiores soluta, obcaecati incidunt expedita eius cumque ipsa quo sed.
Minus distinctio culpa cumque labore nulla laborum ex, explicabo magni mollitia eaque aliquam vero blanditiis quae, id necessitatibus error voluptas harum tempora sint porro. Facilis beatae quasi soluta et ipsum suscipit repellendus inventore.</p>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Possimus, ipsam molestias. Fuga similique, dolor tempora rerum perferendis ipsam ullam doloribus beatae esse facilis quae sit excepturi expedita non, sunt accusantium magnam? Animi nesciunt
nostrum eligendi iusto voluptatum hic qui. Quod distinctio qui nobis et doloremque. Fuga, itaque? Laborum dignissimos nobis quaerat optio voluptatum similique unde, neque cupiditate, vel, fugiat dolore? Accusantium neque deserunt ducimus enim, illum
laborum magni ipsam eos optio aspernatur nam necessitatibus quod natus, dolor laboriosam illo velit.</p>
</div>
</div>

Related

Bootstrap 5.2: Scrollspy not updating nav

little stumped here when trying to make my new website. I decided I wanted to add a scrollspy using Bootstrap so it looks for lively. I tried it but nothing seems to be happening to the navigation bar when I scroll the webpage.
<nav class="nav nav-pills nav-justified d-flex justify-content-center py-3 px-3 fixed-top mainnavbar" id="navbar">
<li class="nav-item">Welcome</li>
<li class="nav-item">Features</li>
<li class="nav-item">Pricing</li>
<li class="nav-item">FAQs</li>
<li class="nav-item">Servers</li>
<li class="nav-item">About</li>
</nav>
<div class="cover d-flex aligns-items-center">
<div class="center-if-small" id="welcome">
<h1 class="header align-middle">Hello!</h1>
<p class="footer align-middle">Welcome to my new website!</p>
</div>
</div>
<div class="container" id="sspy" data-bs-spy="scroll" data-bs-target="#navbar" data-bs-smooth-scroll="true">
<hr>
<h2 class="text-center" id="features">Features</h2>
...
<hr>
<h2 class="text-center" id="pricing">Pricing</h2>
...
<hr>
<h2 class="text-center" id="faqs">FAQs</h2>
...
<hr>
<h2 class="text-center" id="servers">Servers</h2>
...
<hr>
<h2 class="text-center" id="about">About</h2>
...
</div>
I've tried several stuff to fix it, but nothing is happening. Really need help, thanks!
Full code below if needed:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Website</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#650&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<style>
* {
font-family: 'Montserrat', sans-serif;
color: white;
position: relative;
}
body {
background: #313131
}
.cover {
background: url(bg.svg) no-repeat center center fixed;
background-color: #313131;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
color: white;
/* margin: 0; */
/* position: absolute; */
/* top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%); */
padding-left: 2.5vw;
height: 100%;
width: 100%;
}
.mainnavbar {
background: #313131b6
}
#media screen {
.center-if-small {
text-align: left;
}
.header {
font-size: xx-large;
max-width: 700px;
margin-top: 40vh;
}
.footer {
font-size: small;
margin-bottom: 40vh;
}
}
#media screen and (max-width: 768px) {
.center-if-small {
text-align: center;
padding-left: 5vw;
padding-right: 5vw;
}
.header {
font-size: x-large;
}
.footer {
font-size: x-small;
}
}
#media screen and (max-width: 1160px) {
.cover {
background: #313131
}
}
</style>
</head>
<body>
<nav class="nav nav-pills nav-justified d-flex justify-content-center py-3 px-3 fixed-top mainnavbar" id="navbar">
<li class="nav-item">Welcome</li>
<li class="nav-item">Features</li>
<li class="nav-item">Pricing</li>
<li class="nav-item">FAQs</li>
<li class="nav-item">Servers</li>
<li class="nav-item">About</li>
</nav>
<div class="cover d-flex aligns-items-center">
<div class="center-if-small" id="welcome">
<h1 class="header align-middle">Hello!</h1>
<p class="footer align-middle">Welcome to my new website!</p>
</div>
</div>
<div class="container" id="sspy" data-bs-spy="scroll" data-bs-target="#navbar" data-bs-smooth-scroll="true">
<hr>
<h2 class="text-center" id="features">Features</h2>
Lorem ipsum dolor sit amet consectetur adipisicing elit. In excepturi assumenda velit est ullam id iusto veniam consequuntur, nihil repellat omnis magni praesentium ratione. Voluptatem inventore ea voluptates ut cum.
Perferendis dicta veniam error ad obcaecati possimus veritatis facere cupiditate laudantium numquam temporibus fuga consequuntur, exercitationem eligendi sed eveniet qui corporis aperiam at incidunt? Commodi officia odit est unde modi.
Laborum tempora vel minus iure accusantium aliquam aliquid quo nihil earum. Corrupti eaque quas, et impedit doloribus blanditiis inventore, sint natus odio corporis ipsa tenetur reiciendis mollitia molestiae similique officia?
<hr>
<h2 class="text-center" id="pricing">Pricing</h2>
Lorem ipsum dolor sit amet consectetur adipisicing elit. In excepturi assumenda velit est ullam id iusto veniam consequuntur, nihil repellat omnis magni praesentium ratione. Voluptatem inventore ea voluptates ut cum.
Perferendis dicta veniam error ad obcaecati possimus veritatis facere cupiditate laudantium numquam temporibus fuga consequuntur, exercitationem eligendi sed eveniet qui corporis aperiam at incidunt? Commodi officia odit est unde modi.
Laborum tempora vel minus iure accusantium aliquam aliquid quo nihil earum. Corrupti eaque quas, et impedit doloribus blanditiis inventore, sint natus odio corporis ipsa tenetur reiciendis mollitia molestiae similique officia?
<hr>
<h2 class="text-center" id="faqs">FAQs</h2>
Lorem ipsum dolor sit amet consectetur adipisicing elit. In excepturi assumenda velit est ullam id iusto veniam consequuntur, nihil repellat omnis magni praesentium ratione. Voluptatem inventore ea voluptates ut cum.
Perferendis dicta veniam error ad obcaecati possimus veritatis facere cupiditate laudantium numquam temporibus fuga consequuntur, exercitationem eligendi sed eveniet qui corporis aperiam at incidunt? Commodi officia odit est unde modi.
Laborum tempora vel minus iure accusantium aliquam aliquid quo nihil earum. Corrupti eaque quas, et impedit doloribus blanditiis inventore, sint natus odio corporis ipsa tenetur reiciendis mollitia molestiae similique officia?
<hr>
<h2 class="text-center" id="servers">Servers</h2>
Lorem ipsum dolor sit amet consectetur adipisicing elit. In excepturi assumenda velit est ullam id iusto veniam consequuntur, nihil repellat omnis magni praesentium ratione. Voluptatem inventore ea voluptates ut cum.
Perferendis dicta veniam error ad obcaecati possimus veritatis facere cupiditate laudantium numquam temporibus fuga consequuntur, exercitationem eligendi sed eveniet qui corporis aperiam at incidunt? Commodi officia odit est unde modi.
Laborum tempora vel minus iure accusantium aliquam aliquid quo nihil earum. Corrupti eaque quas, et impedit doloribus blanditiis inventore, sint natus odio corporis ipsa tenetur reiciendis mollitia molestiae similique officia?
<hr>
<h2 class="text-center" id="about">About</h2>
Lorem ipsum dolor sit amet consectetur adipisicing elit. In excepturi assumenda velit est ullam id iusto veniam consequuntur, nihil repellat omnis magni praesentium ratione. Voluptatem inventore ea voluptates ut cum.
Perferendis dicta veniam error ad obcaecati possimus veritatis facere cupiditate laudantium numquam temporibus fuga consequuntur, exercitationem eligendi sed eveniet qui corporis aperiam at incidunt? Commodi officia odit est unde modi.
Laborum tempora vel minus iure accusantium aliquam aliquid quo nihil earum. Corrupti eaque quas, et impedit doloribus blanditiis inventore, sint natus odio corporis ipsa tenetur reiciendis mollitia molestiae similique officia?
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script>
$(function(){
// $('#sspy').on('activate.bs.scrollspy')
$('#sspy').scrollspy();
});
</script>
</body>
</html>
You have missed to add the js file of bootstrap, Add the below file in your code beside jquery.
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.11.5/dist/umd/popper.min.js" integrity="sha384-Xe+8cL9oJa6tN/veChSP7q+mnSPaj5Bcu9mPX5F5xIGE0DVittaqT5lorf0EI7Vk" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.min.js" integrity="sha384-ODmDIVzN+pFdexxHEHFBQH3/9/vQ9uori45z4JjnFsRydbmQbmL5t1tQ0culUzyK" crossorigin="anonymous"></script>
For more please check : https://jsfiddle.net/ponsiva/j80t5c39/1/

Accordion with text button innerHTML

I have an accordion that basically works except for one detail. Instead of the usual arrow, which shows whether the accordion is closed or not, I have the text - "Open". I use innerHTML in Pure JS to change it to "Close". When I click on the button on the item that I want to close, everything works, but when I click on another item, I need the rest of the items to change the text to "Open", but this does not happen. My code is below and this is the link to the codepen
document.addEventListener("DOMContentLoaded", function(event) {
const accordionItems = document.querySelectorAll('.acc__item');
accordionItems.forEach((acc) => {
const btns = acc.querySelectorAll('.acc__button')
btns.forEach(btn => {
btn.addEventListener("click", () => {
if (acc.classList.contains('open') && btn.innerHTML !== "Open") {
btn.innerHTML = "Open";
} else {
btn.innerHTML = "Close";
}
accordionItems.forEach((item) => {
if (item !== acc) {
item.classList.remove("open");
}
});
acc.classList.toggle("open");
});
});
});
});
.acc__item {
border: 1px solid navy;
}
.acc__title {
display: flex;
justify-content: space-between;
}
.acc__content {
display: none;
}
.acc__button {
background-color: none;
width: 30%
}
.open .acc__content {
display: block;
}
<div class="acc">
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>
Try to get the button inside the div and change the text like this
item.getElementsByTagName("button")[0].innerHTML = "Open";
Demo below:
document.addEventListener("DOMContentLoaded", function(event) {
debugger;
const accordionItems = document.querySelectorAll('.acc__item');
accordionItems.forEach((acc) => {
debugger;
const btns = acc.querySelectorAll('.acc__button')
btns.forEach(btn => {
btn.addEventListener("click", () => {
debugger;
if (acc.classList.contains('open') && btn.innerHTML !== "Open") {
btn.innerHTML = "Open";
} else {
btn.innerHTML = "Close";
}
accordionItems.forEach((item) => {
if (item !== acc) {
debugger;
item.classList.remove("open");
//getting the button by tag name and updating it
item.getElementsByTagName("button")[0].innerHTML = "Open";
}
});
acc.classList.toggle("open");
});
});
});
});
.acc__item {
border: 1px solid navy;
}
.acc__title {
display: flex;
justify-content: space-between;
}
.acc__content {
display: none;
}
.acc__button {
background-color: none;
width: 30%
}
.open .acc__content {
display: block;
}
<div class="acc">
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>
<div class="acc__item">
<div class="acc__title">
<h4>Title 1</h4>
<button class="acc__button">Open</button>
</div>
<div class="acc__content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus nemo inventore, assumenda aliquam aut sed aspernatur pariatur velit vel, facere mollitia tempore ratione minima incidunt repudiandae veniam harum fuga laudantium.
</div>
</div>

How can I resolve this problem 'Cannot read property 'style' of null at HTMLBodyElement'?

I've a navigation menu which dissappears when the breakpoint is 400px and icon bars appear. I added an eventListener and when I click on the icon I've my message in the console, but when I added if statements I've got an error message 'Cannot read property 'style' of null at HTMLBodyElement'.
I've already read similar questions but still I can't resolve the problem.
.cont-menu-a{
margin-top: 10%;
margin-left: 10%;
margin-right: 10%;
margin-bottom: 35%;
height: 62%;
#media only screen and (max-width: $sm) {
display : none;
}
}
.fa-grip-lines{
color: #212529;
font-size: 2rem;
margin-left: 5%;
margin-top: 5%;
#media only screen and (min-width: $sm) {
display : none;
}}
`<div class="about-page">
<div class="sous-menu-burger">
<i class="fas fa-grip-lines"></i>
</div>
<div class="cont-main">
<div class="cont-menu-a">
<div class="home-a">Home</div>
<div class="about-a">About</div>
<div class="skills-a">Skills</div>
<div class="projects-a">Projects</div>
<div class="contacts-a">Contacts</div>
</div>
<div class="cont-text">
<div class="titre">About</div>
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. A repellat natus praesentium ratione ullam ipsa, perspiciatis consectetur, optio excepturi id cum maxime recusandae corrupti nihil. Illo deleniti eaque quod enim.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil laudantium optio ex nobis. Voluptatibus optio inventore doloremque. Perspiciatis temporibus ipsa quisquam expedita officiis? Nulla quod perferendis maiores repudiandae, vero eaque!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Perspiciatis earum a impedit, laborum magni fugit molestias, modi possimus quod hic consequuntur ad rem sed. Repudiandae, cupiditate perspiciatis! Pariatur, quia voluptatem.
</div>
</div>
</div>
</div>`;
const contSousmenu = document.querySelector('.cont-menu-a');
document.body.addEventListener('click', function (e) {
if (e.target.matches('.fa-grip-lines')) {
console.log('toto');
if (contSousmenu.style.display === 'none') {
contSousmenu.style.display = 'block';
} else {
contSousmenu.style.display = 'none';
}
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="about-page">
<div class="sous-menu-burger">
<i class="fas fa-grip-lines"></i>
</div>
<div class="cont-main">
<div class="cont-menu-a">
<div class="home-a">Home</div>
<div class="about-a">About</div>
<div class="skills-a">Skills</div>
<div class="projects-a">Projects</div>
<div class="contacts-a">Contacts</div>
</div>
<div class="cont-text">
<div class="titre">About</div>
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. A repellat
natus praesentium ratione ullam ipsa, perspiciatis consectetur,
optio excepturi id cum maxime recusandae corrupti nihil. Illo
deleniti eaque quod enim. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Nihil laudantium optio ex nobis. Voluptatibus
optio inventore doloremque. Perspiciatis temporibus ipsa quisquam
expedita officiis? Nulla quod perferendis maiores repudiandae, vero
eaque! Lorem ipsum dolor sit amet consectetur adipisicing elit.
Perspiciatis earum a impedit, laborum magni fugit molestias, modi
possimus quod hic consequuntur ad rem sed. Repudiandae, cupiditate
perspiciatis! Pariatur, quia voluptatem.
</div>
</div>
</div>
</div>
<script>
const hamburger = document.querySelector(".fa-grip-lines");
const contSousmenu = document.querySelector(".cont-menu-a");
hamburger.addEventListener("click", function (e) {
console.log("toto");
if (contSousmenu.style.display === "none") {
contSousmenu.style.display = "block";
} else {
contSousmenu.style.display = "none";
}
});
</script>
</body>
</html>

Getting biggest height of group of divs

I need to find the height of the biggest div in a group of divs with the class name termPanel.
How do I access each 'termPanel' div in the terms array?
function resizePanelsToBiggest(){
var maxheight = 0;
var terms = $('.termPanel');
for(var i = 0;i<terms.length;++i){
if(maxheight < terms[i].height){
maxheight = terms[i].height;
}
}
}
Use Math.max.apply
function resizePanelsToBiggest() {
var maxheight = 0;
var terms = $('.termPanel');
var allH = terms.map(function() {
return $(this).height();
}).get();
var maxH = Math.max.apply(null, allH);
console.log(maxH);
}
Check this demo:
resizePanelsToBiggest();
function resizePanelsToBiggest() {
var maxheight = 0;
var terms = $('.termPanel');
terms.each(function(ndx){
if ($(this).height() > maxheight) {
maxheight = $(this).height();
}
});
console.log(maxheight);
}
.termPanel {
width: 90px;
display: inline-block;
vertical-align: top;
color: white;
}
.termPanel:nth-of-type(even) {
background: black;
}
.termPanel:nth-of-type(odd) {
background: red;
}
.termPanel:nth-of-type(1) {
height: 100px;
}
.termPanel:nth-of-type(2) {
height: 250px;
}
.termPanel:nth-of-type(4) {
height: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="termPanel"></div>
<div class="termPanel"></div>
<div class="termPanel">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut temporibus reiciendis officia veniam quos id velit quibusdam, asperiores ipsum. Obcaecati illum, hic facere repellat dolor modi commodi eum tenetur voluptas veritatis expedita consequuntur repellendus provident error, nisi quos! Aliquid error consectetur voluptates ea dicta, vero, dolores numquam, rerum quasi molestias nemo. Explicabo tenetur, omnis quos unde iusto, necessitatibus consectetur, dolorem deleniti atque doloremque repellendus earum quae sit sint, inventore nesciunt sapiente perspiciatis voluptatum corporis soluta at fugiat. Delectus excepturi unde eos deleniti soluta natus commodi ipsum sit et veniam! Eius aut, ut, ad commodi at esse facere asperiores repellat labore alias nostrum, consequatur tempora illo quasi. Nulla deleniti, mollitia soluta, repellat fugiat officiis voluptatibus odio distinctio libero, illo delectus obcaecati!</div>
<div class="termPanel"></div>
This way it seems a bit easier and more understandable to me:
function returnHighest() {
var maxH = 0;
$('.termPanel').each(function(index, elmt){
var elmtH = $(elmt).outerHeight();
if (elmtH > maxH) {
maxH = elmtH;
}
});
return maxH;
}
var h = returnHighest();
$('.termPanel').css('height', h);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="termPanel" style="float:left;width:50px;border:2px solid red"></div>
<div class="termPanel" style="float:left;width:50px;border:2px solid green"></div>
<div class="termPanel" style="float:left;width:50px;border:2px solid blue"></div>
<div class="termPanel" style="float:left;width:300px;border:2px solid red">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut temporibus reiciendis officia veniam quos id velit quibusdam, asperiores ipsum. Obcaecati illum, hic facere repellat dolor modi commodi eum tenetur voluptas veritatis expedita consequuntur repellendus provident error, nisi quos! Aliquid error consectetur voluptates ea dicta, vero, dolores numquam, rerum quasi molestias nemo....</div>

Remove class if clicked outside an element

How do I make it so that if I click outside a paragraph element then the background color is removed? Note I want to it to only be able to highlight one p at a time.
$('p').click(function() {
$('p').removeClass('yellow');
$(this).addClass('yellow');
});
.yellow {
background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-12">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit tenetur sequi amet sit dolorem, nulla inventore quo cum ad distinctio aut nesciunt reprehenderit dolorum quidem animi unde aspernatur. Esse, eius!</p>
<p>Deleniti vitae rerum eum saepe eaque tenetur libero, omnis nisi sapiente dicta est repellat, provident placeat quia inventore, at architecto quisquam, pariatur minus quam magni totam praesentium dignissimos. Incidunt, sequi.</p>
<p>Fuga cupiditate consectetur, corporis architecto, doloremque impedit ullam quia praesentium voluptatibus molestiae dolor sint, odio amet atque culpa fugit blanditiis ea nam repellat necessitatibus. Aliquam voluptate fuga quo, omnis mollitia.</p>
</div>
</div>
</div>
Here is what you want:
$('p').click(function(e) {
$('p').removeClass('yellow'); //If there is any p with class yellow, it removes that
$(e.target).closest('p').addClass('yellow'); //This find closest target when you click, in our case current paragraph(p)
});
$(document).click(function(e){ //Here is when you click in your entire document
if($(e.target).closest('p').length==0) { // If click is not paragraph
$('p').removeClass('yellow'); //It removes this class existed from any paragraph
}
})
.yellow {
background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-12"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit tenetur sequi amet sit dolorem, nulla inventore quo cum ad distinctio aut nesciunt reprehenderit dolorum quidem animi unde aspernatur. Esse, eius!</p>
<p>Deleniti vitae rerum eum saepe eaque tenetur libero, omnis nisi sapiente dicta est repellat, provident placeat quia inventore, at architecto quisquam, pariatur minus quam magni totam praesentium dignissimos. Incidunt, sequi.</p>
<p>Fuga cupiditate consectetur, corporis architecto, doloremque impedit ullam quia praesentium voluptatibus molestiae dolor sint, odio amet atque culpa fugit blanditiis ea nam repellat necessitatibus. Aliquam voluptate fuga quo, omnis mollitia.</p></div>
</div>
</div>
Use this code
$("p").click(function (e){
$("p").removeClass("yellow");
$(this).addClass("yellow");
});
$(document).click(function (e){
var element = $("p.yellow");
if (!element.is(e.target) && element.has(e.target).length === 0)
element.removeClass("yellow");
});
.yellow {
background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="yellow">Text text text</p>
<p>Text text text</p>
<p>Text text text</p>
You can set a listener to the <body> and check if the click was onto a <p>:
$('body').click(function(event) {
if(!$(event.target).is('p')) {
$('p').removeClass('yellow');
}
else {
$(event.target).addClass('yellow');
}
});

Categories