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>
Related
Well, what I need is so complex for me that I can't even explain what I want.
I have a main section, where I need this main section to scroll between the main sections.
Inside the first main section I have another section and I need it to scroll independently of the main section, i.e. only this section scrolls.
Can anyone help me with this?
const prevBtn = document.getElementById("prev-btn");
const nextBtn = document.getElementById("next-btn");
const allSection = document.getElementsByTagName("section");
const sections = [];
let count = 0;
for (let i = 0; i < allSection.length; i++) {
let sectionArr = document.getElementById(`section-${i + 1}`);
sections.push(sectionArr);
}
function next() {
prevBtn.classList.remove("disabled");
if (count < allSection.length - 1) {
sections[count].classList.add("d-none");
count++;
console.log(count);
sections[count].classList.remove("d-none");
}
if (count === allSection.length - 1) {
nextBtn.classList.add("disabled");
}
}
function prev() {
nextBtn.classList.remove("disabled");
if (count !== 0) {
sections[count].classList.add("d-none");
count--;
sections[count].classList.remove("d-none");
}
if (count === 0) {
prevBtn.classList.add("disabled");
}
}
#page-content {
width:100%;
display:flex;
justify-content:space-between;
}
#sect-one, #sect-two {
width:50%;
height: 500px;
background-color:red;
}
#media(max-width:768px) {
#page-content {
flex-direction: column;
}
#sect-one, #sect-two {
width:100%;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Section, prev & next</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css"
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery#3.5.1/dist/jquery.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct"
crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/7a83d58e46.js" crossorigin="anonymous"></script>
</head>
<body>
<button id="prev-btn" class="btn" onclick="prev()">« Prev</button>
<button id="next-btn" class="btn" onclick="next()">Next »</button>
<section id="section-1" class="container">
<main id='page-content'>
<section id='sect-one'>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis aut distinctio magni dolorem nobis illum
perferendis modi tempora inventore quis!</p>
</section>
<section id='sect-two'>
<section id="section-6" class="container">
<button id="prev-btn" class="btn" onclick="prev()">« Prev</button>
<button id="next-btn" class="btn" onclick="next()">Next »</button>
<h2>Section 1</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis aut distinctio magni dolorem nobis illum
perferendis modi tempora inventore quis!</p>
</div>
</section>
<section id="section-7" class="container d-none">
<button id="prev-btn" class="btn" onclick="prev()">« Prev</button>
<button id="next-btn" class="btn" onclick="next()">Next »</button>
<h2>Section 2</h2>
<div>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Molestiae iure iste fugit dolor dicta voluptate
magnam perferendis, beatae, ipsam id placeat magni voluptatem accusamus animi eum officiis atque hic
temporibus.</p>
</div>
</section>
<section id="section-8" class="container d-none">
<button id="prev-btn" class="btn" onclick="prev()">« Prev</button>
<button id="next-btn" class="btn" onclick="next()">Next »</button>
<h2>Section 3</h2>
<div>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sed amet suscipit omnis nisi nesciunt hic
expedita optio blanditiis, reiciendis fugit tempora distinctio odit cumque! Dolore eos ratione magnam
ducimus laboriosam natus vel officia, blanditiis illo ullam pariatur, delectus nostrum deleniti.</p>
</div>
</section>
<section id="section-9" class="container d-none">
<button id="prev-btn" class="btn" onclick="prev()">« Prev</button>
<button id="next-btn" class="btn" onclick="next()">Next »</button>
<h2>Section 4</h2>
<div>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sed amet suscipit omnis nisi nesciunt hic
expedita optio blanditiis, reiciendis fugit tempora distinctio odit cumque! Dolore eos ratione magnam
ducimus laboriosam natus vel officia, blanditiis illo ullam pariatur, delectus nostrum deleniti.</p>
</div>
</section>
<section id="section-10" class="container d-none">
<button id="prev-btn" class="btn" onclick="prev()">« Prev</button>
<button id="next-btn" class="btn" onclick="next()">Next »</button>
<h2>Section 5</h2>
<div>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sed amet suscipit omnis nisi nesciunt hic
expedita optio blanditiis, reiciendis fugit tempora distinctio odit cumque! Dolore eos ratione magnam
ducimus laboriosam natus vel officia, blanditiis illo ullam pariatur, delectus nostrum deleniti.</p>
</div>
</section>
</section>
</main>
</section>
<section id="section-2" class="container d-none">
<h2>Section 2</h2>
<div>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Molestiae iure iste fugit dolor dicta voluptate
magnam perferendis, beatae, ipsam id placeat magni voluptatem accusamus animi eum officiis atque hic
temporibus.</p>
</div>
</section>
<section id="section-3" class="container d-none">
<h2>Section 3</h2>
<div>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sed amet suscipit omnis nisi nesciunt hic
expedita optio blanditiis, reiciendis fugit tempora distinctio odit cumque! Dolore eos ratione magnam
ducimus laboriosam natus vel officia, blanditiis illo ullam pariatur, delectus nostrum deleniti.</p>
</div>
</section>
<section id="section-4" class="container d-none">
<h2>Section 4</h2>
<div>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sed amet suscipit omnis nisi nesciunt hic
expedita optio blanditiis, reiciendis fugit tempora distinctio odit cumque! Dolore eos ratione magnam
ducimus laboriosam natus vel officia, blanditiis illo ullam pariatur, delectus nostrum deleniti.</p>
</div>
</section>
<section id="section-5" class="container d-none">
<h2>Section 5</h2>
<div>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sed amet suscipit omnis nisi nesciunt hic
expedita optio blanditiis, reiciendis fugit tempora distinctio odit cumque! Dolore eos ratione magnam
ducimus laboriosam natus vel officia, blanditiis illo ullam pariatur, delectus nostrum deleniti.</p>
</div>
</section>
<script src="script.js"></script>
</body>
</html>
Each <p> are hidden on initial load and I want to click on the <h3> then want the p-tag to show using Javascript.
I have a section in my HTML that looks as follow
<div id="bio-sections">
<div id="history">
<h3 onclick="openFunction()">My History</h3>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Fuga alias hic officia dolor quidem maiores quasi architecto veritatis obcaecati debitis, rem suscipit quo blanditiis perspiciatis deleniti id a rerum quae!</p>
</div>
<div id="schooling">
<h3>My Schooling</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. In iure distinctio voluptatum non quia maxime numquam amet eum at, quo ut iusto est quos hic placeat. Repudiandae dolorem cupiditate illo.</p>
</div>
<div id="work">
<h3>My Work experience</h3>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quisquam dolor nemo nostrum consequuntur. Tempora, quia nobis eligendi, labore porro natus voluptates nam, consectetur corporis vitae eius hic sed ea earum.</p>
</div>
<div id="hobbies">
<h3>My Hobbies</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolor perspiciatis ipsam suscipit voluptas ab distinctio a doloribus, dolorem officia iure nemo qui incidunt soluta dolores ratione saepe. In, mollitia! Voluptatem!</p>
</div>
</div>
My question is how do you reference the following div (or in this case p-tag) given the H3 you pressed?
If you press the H3 under #history then only that p-tag must show and the same with the other divs. But how do you do this in Javascript without duplicating code with different id's or classes.
My approach avoid the use of inline JS inside HTML, which is a bad practice.
Select all <h3> that are clickable and should open the <p> tags, then add the listener to them all.
Now, all you need is the function using this, that refers to the clicked h3, get it's sibling element, check if it is displaying or not, and do the toggle.
See below code
openFunction = function(ev) {
let pTagElem = this.nextElementSibling
if (pTagElem.style.display == "inline") {
pTagElem.style.display = "none"
} else {
pTagElem.style.display = "inline"
}
}
//select all <h3> that should be clickable (inside bio-sections divs)
let h3s = document.querySelectorAll("#bio-sections div h3")
//add the listener to them all
for (let h3 of h3s) {
h3.onclick = openFunction
}
#bio-sections div p {
display: none
}
#bio-sections div h3 {
cursor: pointer
}
<div id="bio-sections">
<div id="history">
<h3>My History</h3>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Fuga alias hic officia dolor quidem maiores quasi architecto veritatis obcaecati debitis, rem suscipit quo blanditiis perspiciatis deleniti id a rerum quae!</p>
</div>
<div id="schooling">
<h3>My Schooling</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. In iure distinctio voluptatum non quia maxime numquam amet eum at, quo ut iusto est quos hic placeat. Repudiandae dolorem cupiditate illo.</p>
</div>
<div id="work">
<h3>My Work experience</h3>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quisquam dolor nemo nostrum consequuntur. Tempora, quia nobis eligendi, labore porro natus voluptates nam, consectetur corporis vitae eius hic sed ea earum.</p>
</div>
<div id="hobbies">
<h3>My Hobbies</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolor perspiciatis ipsam suscipit voluptas ab distinctio a doloribus, dolorem officia iure nemo qui incidunt soluta dolores ratione saepe. In, mollitia! Voluptatem!</p>
</div>
</div>
you can use javascript parameters like this, and move the id into the p tag
<div>
<h3 onclick="openFunction('history')">My History</h3>
<p id="history">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Fuga alias hic officia dolor quidem maiores quasi architecto veritatis obcaecati debitis, rem suscipit quo blanditiis perspiciatis deleniti id a rerum quae!</p>
</div>
<script>
function openFunction(id) {
document.getElementById(id).show()
}
</script>
You can use closest() and delegation.
const container = document.querySelector("#bio-sections");
container.addEventListener("click", function (event) {
const parentSectionDiv = event.target.closest(".section");
if (parentSectionDiv !== null) {
parentSectionDiv.querySelector("p").classList.remove("hidden");
}
});
.hidden {
display:none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <link rel="stylesheet" href="style.css" /> -->
<title>Sign in & Sign up Form</title>
</head>
<body>
<div id="bio-sections">
<div id="history" class="section">
<h3>My History</h3>
<p class="hidden">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Fuga alias
hic officia dolor quidem maiores quasi architecto veritatis obcaecati
debitis, rem suscipit quo blanditiis perspiciatis deleniti id a rerum
quae!
</p>
</div>
<div id="schooling" class="section">
<h3>My Schooling</h3>
<p class="hidden">
Lorem ipsum dolor sit amet consectetur adipisicing elit. In iure
distinctio voluptatum non quia maxime numquam amet eum at, quo ut
iusto est quos hic placeat. Repudiandae dolorem cupiditate illo.
</p>
</div>
<div id="work" class="section">
<h3>My Work experience</h3>
<p class="hidden">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quisquam
dolor nemo nostrum consequuntur. Tempora, quia nobis eligendi, labore
porro natus voluptates nam, consectetur corporis vitae eius hic sed ea
earum.
</p>
</div>
<div id="hobbies" class="section">
<h3>My Hobbies</h3>
<p class="hidden">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolor
perspiciatis ipsam suscipit voluptas ab distinctio a doloribus,
dolorem officia iure nemo qui incidunt soluta dolores ratione saepe.
In, mollitia! Voluptatem!
</p>
</div>
</div>
</body>
<script src="script.js"></script>
</html>
It depends a bit on how stable your HTML is, but if you are confident it remains like that you don't need to change it and can on the click get the p element.
There's several ways of doing this. This snippet gets the common parent and the first p element in it.
function openFunction() {
console.log(event.target);
console.log(event.target.parentElement.querySelector('p:first-of-type'));
}
<div id="bio-sections">
<div id="history">
<h3 onclick="openFunction()">My History</h3>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Fuga alias hic officia dolor quidem maiores quasi architecto veritatis obcaecati debitis, rem suscipit quo blanditiis perspiciatis deleniti id a rerum quae!</p>
</div>
<div id="schooling">
<h3>My Schooling</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. In iure distinctio voluptatum non quia maxime numquam amet eum at, quo ut iusto est quos hic placeat. Repudiandae dolorem cupiditate illo.</p>
</div>
<div id="work">
<h3>My Work experience</h3>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quisquam dolor nemo nostrum consequuntur. Tempora, quia nobis eligendi, labore porro natus voluptates nam, consectetur corporis vitae eius hic sed ea earum.</p>
</div>
<div id="hobbies">
<h3>My Hobbies</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolor perspiciatis ipsam suscipit voluptas ab distinctio a doloribus, dolorem officia iure nemo qui incidunt soluta dolores ratione saepe. In, mollitia! Voluptatem!</p>
</div>
</div>
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>
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>
Im using the following code from their website
<nav>
<div class="nav-wrapper">
<form>
<div center class="input-field">
<input id="search" type="search" required>
<label for="search"><i class="material-icons">search</i></label>
<i class="material-icons">close</i>
</div>
</form>
</div>
</nav>
Is there any way to search through the website, and highlight the words when the user types them?
You can use hilitor.js for that.
HTML:
<nav>
<div class="nav-wrapper">
<form>
<div center class="input-field">
<input id="search" type="search" required placeholder="Search...">
<label for="search"></label>
</div>
</form>
</div>
</nav>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit praesentium ad placeat voluptates perspiciatis eaque odio non nisi impedit ea. Praesentium similique perferendis animi, cumque neque placeat deserunt facere ut. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit praesentium ad placeat voluptates perspiciatis eaque odio non nisi impedit ea. Praesentium similique perferendis animi, cumque neque placeat deserunt facere ut. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit praesentium ad placeat voluptates perspiciatis eaque odio non nisi impedit ea. Praesentium similique perferendis animi, cumque neque placeat deserunt facere ut.</p>
CSS:
::-webkit-input-placeholder {
color: #fff;
}
::-moz-placeholder {
color: #fff;
opacity: 1;
}
:-ms-input-placeholder {
color: #fff;
}
input {
margin: 0;
}
p {
margin: 0;
padding: 15px 60px;
background: #d66367;
color: #fff;
}
JS:
var myHilitor2;
document.addEventListener("DOMContentLoaded", function() {
myHilitor2 = new Hilitor("playground");
myHilitor2.setMatchType("left");
}, false);
document.getElementById("search").addEventListener("keyup", function() {
myHilitor2.apply(this.value);
}, false);
Here is a Codepen.
Don't forget to include hilitor.js.
Next time provide better topic name and tags, because your issue is not related to materialize or materializecss.