What is going on here is I want to add a slider HTML with extra HTML beneath the main slider.
What is the problem?
Things are working fine because we have a mouse scroll on the desktop. As soon as you see the output on mobile device things work differently because now touch comes in the picture. after the 4th slider, you can't move the slider. but I have still content left on the page after the fourth slide.
HTML
<section class="slider-part">
<div class="swiper-container mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide bg-y">Slide 1</div>
<div class="swiper-slide bg-r">Slide 2</div>
<div class="swiper-slide bg-g">Slide 3</div>
<div class="swiper-slide bg-v">Slide 4</div>
</div>
<div class="swiper-pagination"></div>
</div>
</section>
<section class="content-part">
<div class="container-xl">
<div class="row">
<div class="col-12 pt-5 pb-5">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla, rerum sint pariatur natus mollitia nesciunt. Porro sit odit veniam eos quaerat animi sint ipsam aspernatur ut repellat tenetur quibusdam, corrupti optio cupiditate quis. Ipsa sapiente explicabo quam quibusdam facere, minus fugit modi impedit illo doloremque quisquam tempore corrupti quis mollitia.
</p>
</div>
</div>
<div class="row">
<div class="col-12 pt-5 pb-5">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla, rerum sint pariatur natus mollitia nesciunt. Porro sit odit veniam eos quaerat animi sint ipsam aspernatur ut repellat tenetur quibusdam, corrupti optio cupiditate quis. Ipsa sapiente explicabo quam quibusdam facere, minus fugit modi impedit illo doloremque quisquam tempore corrupti quis mollitia.
</p>
</div>
</div>
<div class="row">
<div class="col-12 pt-5 pb-5">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla, rerum sint pariatur natus mollitia nesciunt. Porro sit odit veniam eos quaerat animi sint ipsam aspernatur ut repellat tenetur quibusdam, corrupti optio cupiditate quis. Ipsa sapiente explicabo quam quibusdam facere, minus fugit modi impedit illo doloremque quisquam tempore corrupti quis mollitia.
</p>
</div>
</div>
</div>
</section>
<footer>
<div class="container-xl">
<div class="row">
<div class="col-12">
<h2>I am Footer</h2>
</div>
</div>
</div>
</footer>
CSS
.mySwiper {
height: 100vh;
}
.swiper-slide {
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
.bg-y {
background-color: #eccc68;
}
.bg-r {
background-color: #ff7f50;
}
.bg-g {
background-color: #a4b0be;
}
.bg-v {
background-color: #70a1ff;
}
footer {
background-color: #ffa502;
padding: 20px 0;
}
footer h2 {
color: #fff;
text-align: center;
}
body {
-ms-overflow-style: none;
scrollbar-width: none;
}
body::-webkit-scrollbar {
display: none;
}
JS
var swiper = new Swiper(".mySwiper", {
direction: "vertical",
slidesPerView: 1,
mousewheel: true,
speed: 1000,
// simulateTouch: false,
keyboard: {
enabled: true,
},
mousewheel: {
releaseOnEdges: true,
forceToAxis: true,
sensitivity: 1,
},
pagination: {
el: ".swiper-pagination",
clickable: true,
},
on: {
slideChange: function () {
setTimeout(function () {
swiper.params.mousewheel.releaseOnEdges = false;
}, 500);
},
reachEnd: function() {
setTimeout(function () {
swiper.params.mousewheel.releaseOnEdges = true;
}, 750);
}
},
});
What I want is after the slider complete. I can move things normally the same as we scroll down the normal HTML.
Right now in the mobile output, you can't move the slider after the 4th slider I think it's stuck because of slider enable so you can't see content till the footer.
Related
In the images below, the small box is like a tab, when clicked it will show the content at the bottom of it.
When the window / viewed in a smaller screen it will reduce the columns accordingly, however it should preserve its functionality.
Tablet
Mobile
const about = document.querySelector(".wrapper");
const btns = document.querySelectorAll(".accordion");
const articles = document.querySelectorAll(".content");
about.addEventListener("click", function(e) {
const id = e.target.dataset.id;
if (id) {
// remove selected from other buttons
btns.forEach(function(btn) {
btn.classList.remove("active");
});
e.target.classList.add("active");
// hide other articles
articles.forEach(function(article) {
article.classList.remove("active");
});
const element = document.getElementById(id);
element.classList.add("active");
}
});
* {
margin: 0 auto;
padding: 0;
max-width: 1000px;
box-sizing: border-box;
background-color: gray;
}
.accordion {
margin-top: 5px;
background-color: #eee;
color: #444;
padding: 15px;
width: 50%;
transition: 0.4s;
}
.accordion.active {
background-color: #ccc;
}
.post-container {
content: "";
display: table;
clear: both;
}
.container {
display: flex;
flex-direction: row;
gap: 6px;
}
.wrapper {
display: flex;
flex-direction: column;
}
.content {
display: none;
}
.wrapper2 {
width: 100%;
}
.content.active {
display: block;
padding: 20px;
}
.active,
.accordion:hover {
background-color: #ccc;
}
<main class="wrapper">
<section class="wrapper2">
<div class="container">
<button data-id="1" class="accordion">Section 1</button>
<button data-id="2" class="accordion">Section 2</button>
<button data-id="3" class="accordion">Section 3</button>
</div>
<div id="1" class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure ipsa optio eaque placeat aut deleniti facere nisi repudiandae sequi distinctio? Error dignissimos excepturi perferendis pariatur ad a ratione dolore atque.</div>
<div id="2" class="content">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Assumenda nesciunt autem dignissimos commodi ut velit iure sequi eveniet repudiandae. Nisi impedit ad, libero voluptates autem minima corporis mollitia illo eum.</div>
<div id="3" class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus, numquam culpa. Impedit voluptates ad ea distinctio a doloremque ex officiis ducimus, nobis nihil qui repudiandae, dolore, pariatur ratione error nemo.</div>
</section>
<section class="wrapper2">
<div class="container">
<button data-id="4" class="accordion">Section 4</button>
<button data-id="5" class="accordion">Section 5</button>
<button data-id="6" class="accordion">Section 6</button>
</div>
<div id="4" class="content">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolor ducimus cupiditate fuga ratione tempore eveniet possimus maiores quod sequi natus? Iusto dolor hic facilis culpa ad illo vel deserunt minima?</div>
<div id="5" class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur nihil obcaecati a cumque quos adipisci aliquam illum perspiciatis fugit, tempora aperiam officiis dignissimos odit incidunt modi tempore corporis. Porro, a.</div>
<div id="6" class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, quis est. Animi fuga ipsum porro ullam blanditiis illum inventore magnam, earum nesciunt ab quis placeat iste quo! Repudiandae, ratione sapiente!</div>
</section>
</main>
I spent the weekend trying to get my head around the Intersection Observer Animation for an animation that I'm trying to achieve. From my understanding of the intersection observer my code should work as I intended but the reality is it doesn't 🥲
My goal is that the scroll animation starts when the element reaches a certain point within the viewport. In my codepen, I've marked the point where the animation should start with a border. However, the animation starts as soon as the div enters the viewport.
Also, when the element gets below the border again, the animation should stop.
I would very much appreciate any help to achieve my goal.
Code example: https://codepen.io/aki-sol/pen/RwJPJrW?editors=1111
Also, if you have any feedback on my animation approach I'm very happy to receive criticism/ better way of approaching this.
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
<div class="box">
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
</div>
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
body {
position: relatvie;
heig;
}
body:after {
content: '';
position: fixed;
bottom: 40%;
height: 1px;
width: 100%;
border-bottom: 1px solid blue;
}
.text {
background-color: brown;
color: white;
height: 150vh;
}
.box {
display: flex;
position: relative;
}
.box-content {
width: 200px;
height: 200px;
background-color: greenyellow;
margin-right: 50px;
}
const boxElement = document.querySelector(".box");
//this function calls the aniamtion function and observes the window scroll position
function getWindowScrollPos() {
let windowPosition = window.scrollY;
window.addEventListener("scroll", () => {
windowPosition = window.scrollY;
animateBox(boxElement, windowPosition);
});
}
function animateBox(box, scrollPosition) {
let boxOffsetPosition = scrollPosition;
box.style.left = `${-boxOffsetPosition}px `;
}
function boxObserver(element) {
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
getWindowScrollPos();
}
});
},
{ rootMargin: "0% 0% 60% 0%" }
);
observer.observe(element);
}
boxObserver(boxElement);
Thanks a lot!
There are two things to note here, I guess.
First, the Intersection Observer (along with Resize Observer) is not the best thing to test in online sandboxes, because they run code in an iframe, which leads to such a behavior. You should try to run your code in a browser.
There are questions related to this problem. E.g.: In codepen, Intersection observer has different behavior from browser window
Second, you're probably misunderstanding rootMargin. You set it to 0% 0% 60% 0% which means “add 60% of the height of the root to the very root, and use it as a bottom border for intersection”.
What you actually want to is to decrease the bottom border, not to increase. So, just set it to 0% 0% -40% 0% and it will work.
The Intersection Observer tutorial that helped me a bit to understand the rootMargin weirdness. Maybe it will be useful for you too.
Demo
Here's your snippet that I changed a bit to make it work inside an iframe. I've added a container node and use it instead of window.
const boxElement = document.querySelector('.box');
const container = document.getElementById('container');
function setupListener() {
let scrollPosition = container.scrollTop;
animateBox(boxElement, scrollPosition);
container.addEventListener('scroll', () => {
scrollPosition = container.scrollTop;
animateBox(boxElement, scrollPosition);
});
}
function animateBox(box, scrollPosition) {
let boxOffsetPosition = scrollPosition;
box.style.left = `${-boxOffsetPosition}px`;
}
function boxObserver(element) {
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setupListener();
}
});
},
{
root: document.getElementById('container'),
rootMargin: `0px 0px -40% 0px`
}
);
observer.observe(element);
}
boxObserver(boxElement);
body {
margin: 0;
overflow: hidden;
}
body:after {
content: "";
position: fixed;
bottom: 40%;
height: 1px;
width: 100%;
border-bottom: 1px solid blue;
}
.container {
overflow: scroll;
max-height: 100vh;
}
.text {
background-color: brown;
color: white;
height: 150vh;
}
.box {
display: flex;
position: relative;
}
.box-content {
width: 200px;
height: 200px;
background-color: greenyellow;
margin-right: 50px;
}
<div class="container" id="container">
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
<div class="box">
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
<div class="box-content"></div>
</div>
<div class="text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Expedita provident unde, sequi aliquid porro ipsa vitae nulla dolor neque aliquam quisquam nam magnam architecto, consequuntur est in beatae, nihil optio.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, architecto eveniet assumenda praesentium in laboriosam vitae atque, sunt minima aliquid quam distinctio voluptatum commodi veniam iure officia provident voluptas ea?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet quo commodi laborum perspiciatis nemo voluptates quod odio quis necessitatibus perferendis? Ipsum, quasi nesciunt. Debitis omnis consequuntur laboriosam veniam, non impedit!
</div>
</div>
What may be improved
Also, if you have any feedback on my animation approach I'm very happy to receive criticism/ better way of approaching this.
Well, you surely should think about the scroll listener you will have after the intersection started. If you don't remove it, it will hang. Or even worse, they will be increasing during each intersection. Not a good thing.
Also it's better to animate transform, not left. It's good for optimization. Otherwise you'll get junky animation which will freeze the whole site. Check this set of articles by Google: web.dev/animations/.
I have a tabbed section which showcases 1 .section__content area based on what tab is clicked.
In my demo below, I have used fadeTo( "slow", 1 ) instead of fadeOut(), so that the parent div isn't always resizing after tab change. However, if I click on tab-2 it'll render below where tab-1 would be (because the opacity is 0, but block height is still there). But, if I do display: none, the fade effects are not fluent.
$(function() {
$(".section__label:first").addClass("active");
$(".section__content:first").fadeIn();
$('.section__label').click(function() {
var id = $(this).attr('data-item');
$(".section__label").removeClass("active");
$(this).addClass("active");
$(".section__content").fadeTo( "slow", 0 );
$(".section__content[data-item='"+id+"']").fadeTo( "slow", 1 );
});
});
.section {
background: lightblue;
padding: 100px 0;
border: 1px solid black;
}
.section__tabs {
display: flex;
flex-direction: column;
}
.section__label {
cursor: pointer;
display: inline-block;
}
.section__label.active {
color: orange;
}
.section__content {
display: none;
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="section">
<div class="container">
<div class="row justify-content-between">
<div class="col-3">
<div class="section__tabs">
<span class="section__label" data-item="tab-1">Tab 1</span>
<span class="section__label" data-item="tab-2">Tab 2</span>
<span class="section__label" data-item="tab-3">Tab 3</span>
</div>
</div>
<div class="col-7">
<div class="section__content" data-item="tab-1">
<p>Text for tab 1</p>
</div>
<div class="section__content" data-item="tab-2">
<p>Text for tab 2</p>
</div>
<div class="section__content" data-item="tab-3">
<p>Text for tab 3</p>
</div>
</div>
</div>
</div>
</div>
Here's a way to do that using fadeIn() and fadeOut(). I also added in a locking mechanism to prevent the UI from getting over-clicked.
https://api.jquery.com/fadein/
let locked = false;
$(function() {
$(".section__label:first").addClass("active");
$(".section__content:first").addClass("active");
$('.section__label').click(function() {
if (locked) return;
locked = true;
var id = $(this).attr('data-item');
$(".section__label").removeClass("active");
$(this).addClass("active");
$(".section__content.active").fadeOut(500, function() {
$(this).removeClass("active");
$(".section__content[data-item='" + id + "']").addClass('active').fadeIn(1000, function() {
locked = false;
})
});
});
});
.section {
background: lightblue;
padding: 100px 0;
border: 1px solid black;
}
.section__tabs {
display: flex;
flex-direction: column;
}
.section__label {
cursor: pointer;
display: inline-block;
}
.section__label.active {
color: orange;
}
.section__content {
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="section">
<div class="container">
<div class="row justify-content-between">
<div class="col-3">
<div class="section__tabs">
<span class="section__label" data-item="tab-1">Tab 1</span>
<span class="section__label" data-item="tab-2">Tab 2</span>
<span class="section__label" data-item="tab-3">Tab 3</span>
</div>
</div>
<div class="col-7">
<div class="section__content" data-item="tab-1">
<p>Text for tab 1. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam </p>
</div>
<div class="section__content" data-item="tab-2">
<p>Text for tab 2 .Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam </p>
</div>
<div class="section__content" data-item="tab-3">
<p>Text for tab 3. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam </p>
</div>
</div>
</div>
</div>
</div>
Here's another option. Instead of hide()/show(), you can use css transitions along with opacity and max-height to create an accordian effect.
$(function() {
$(".section__label:first").addClass("active");
$(".section__content:first").addClass("active");
$('.section__label').click(function() {
var id = $(this).attr('data-item');
$(".section__label").removeClass("active");
$(this).addClass("active");
$(".section__content.active").removeClass('active');
$(".section__content[data-item='" + id + "']").addClass('active');
});
});
.section {
background: lightblue;
padding: 100px 0;
border: 1px solid black;
}
.section__tabs {
display: flex;
flex-direction: column;
}
.section__label {
cursor: pointer;
display: inline-block;
}
.section__label.active {
color: orange;
}
.section__content {
max-height: 0;
opacity: 0;
overflow: hidden;
transition: all .4s ease-in-out;
border: 1px solid red;
}
.section__content.active {
max-height: 1000px;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="section">
<div class="container">
<div class="row justify-content-between">
<div class="col-3">
<div class="section__tabs">
<span class="section__label" data-item="tab-1">Tab 1</span>
<span class="section__label" data-item="tab-2">Tab 2</span>
<span class="section__label" data-item="tab-3">Tab 3</span>
</div>
</div>
<div class="col-7">
<div class="section__content" data-item="tab-1">
<p>Text for tab 1. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam </p>
</div>
<div class="section__content" data-item="tab-2">
<p>Text for tab 2 .Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam </p>
</div>
<div class="section__content" data-item="tab-3">
<p>Text for tab 3. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam </p>
</div>
</div>
</div>
</div>
</div>
I am working on a blog layout which have its content on the left side and a 'table of contents' sidebar on the right. The sidebar is fixed with a full viewport height but scrollable incase the items inside are too many.
It is also worth noting that the active state changes on the links in the sidebar based on their corresponding content in the viewport. What I mean to say is that whenever a blog post is in the viewport, its link gets active state in the sidebar. And it is done by Intersection Observer API.
Now the core functionality works fine except there is one issue.
When there are a lot of blog posts, there will be a lot of links on the sidebar. So naturally the bottom links are not visible on the sidebar as they are at the bottom and can't be seen until the scrollbar is pulled down. Therefore, the active state is not visible as well.
Suppose a user tries to read blog post Text 8, the corresponding Text 8 link should've been visible on the sidebar but it is not. Only upto Text 7 is visible in the demo (based on my viewport).
What I wanted to achieve is how can I move the scrollbar up and down based on which blog posts the user is reading? I mean if the user is reading Text 8 then the sidebar will scroll downward and show Text 8 link. If he is reading Text 9, it will scroll to Text 9 link. Now if he decides to read Text 7 from Text 9 then the scrollbar will move upward two places and display Text 7 link.
I don't know if I could explain it properly but this is the best I could write.
It would be a great help if you could help me with this.
Here's the codepen.
Here's the snippet:
const asideContent = $('#aside-content .aside-content');
const asideContentItem = $('#aside-content a');
const callback = (entries, observer) => {
$(entries).each((idx, item) => {
const navItem = $('#' + item.target.id);
if (item.isIntersecting) {
$(asideContentItem).each((i, eachLink) => {
if ($(eachLink).attr("href") === ('#' + $(navItem).attr('id'))) {
$(eachLink).addClass('active');
} else {
$(eachLink).removeClass('active');
}
})
}
})
};
const options = {
threshold: 0.2
};
const observer = new IntersectionObserver(callback, options);
const container = $('#main');
const targetElements = $('.main-content .inner-container');
$(targetElements).each((idx, item) => {
observer.observe(item);
});
.header-content {
background-color: blue;
height: 800px;
margin: 20px 0;
}
#main {
margin: 20px auto;
}
.main-content {
background-color: cyan;
}
#aside-content {
position: sticky;
top: 0;
align-self: flex-start;
background-color: red;
height: 100vh;
overflow-y: auto;
}
#aside-content a {
display: block;
margin: 40px auto;
text-decoration: none;
}
#aside-content a.active {
background-color: rgba(0, 255, 0, 0.5);
}
.aside-fixed {
position: fixed;
top: 0;
right: 0;
}
footer {
background-color: brown;
height: 200px;
}
<link href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/litera/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Test</a>
</nav>
<section class="container">
<div class="row">
<div class="col-md-12">
<div class="header-content">
<h3>header content</h3>
</div>
</div>
</div>
</section>
<section class="container" id="main">
<div class="row">
<div class="col-8">
<div class="main-content">
<div id="text1" class="inner-container">
<h2>Text 1</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit.
</div>
<div id="text2" class="inner-container">
<h2>Text 2</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harumti aspernatur delectus mollitia libero similique assumenda quos sequi eligendi?
</div>
<div id="text3" class="inner-container">
<h2>Text 3</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, maxime repellat aperiam labore exercitationem enim possimus. Suscipit facilis debitis quidem excepturi?
</div>
<div id="text4" class="inner-container">
<h2>Text 4</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text5" class="inner-container">
<h2>Text 5</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text6" class="inner-container">
<h2>Text 6</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text7" class="inner-container">
<h2>Text 7</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text8" class="inner-container">
<h2>Text 8</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text9" class="inner-container">
<h2>Text 9</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
</div>
</div>
<div class="col-4" id="aside-content">
<div class="aside-content">
<h3>Table of Contents</h3>
<div>
Text 1
Text 2
Text 3
Text 4
Text 5
Text 6
Text 7
Text 8
Text 9
</div>
</div>
</div>
</section>
<footer>
<h3>footer</h3>
</footer>
You can solve this by setting the scrollbar position to the specific offset as the active class changes. This could be achieved by editing your JS and adding the scrolling logic to the add addClass('active') section.
Basically you have to update the scrollbar position as the active class is added to any link.
document.querySelector("#aside-content").scrollTo(0,position)
And the position to which the scrollbar has to be set, can be fetched from the current active element's/link's offset.
document.querySelector("#aside-content > div > div > a.active").offsetTop
Therefore just after adding class the above stated steps can be done
$(eachLink).addClass('active');
var position = document.querySelector("#aside-content > div > div > a.active").offsetTop;
document.querySelector("#aside-content").scrollTo(0,position);
But, the above code will always set the position, and due to which at first link will set the scrolling to itself and not let "table of contents" text to be visible ever. To fix this situation, updating logic can be made conditional by checking if the active element is first child of the scrolling div.
So, the overall working code should be as follow:
const asideContent = $('#aside-content .aside-content');
const asideContentItem = $('#aside-content a');
const callback = (entries, observer) => {
$(entries).each((idx, item) => {
const navItem = $('#' + item.target.id);
if (item.isIntersecting) {
$(asideContentItem).each((i, eachLink) => {
if ($(eachLink).attr("href") === ('#' + $(navItem).attr('id'))) {
$(eachLink).addClass('active');
if (document.querySelector("#aside-content > div > div > a.active").parentNode.firstElementChild != document.querySelector("#aside-content > div > div > a.active")) {
document.querySelector("#aside-content").scrollTo(0, document.querySelector("#aside-content > div > div > a.active").offsetTop);
} else {
document.querySelector("#aside-content").scrollTo(0, 0);
}
} else {
$(eachLink).removeClass('active');
}
})
}
})
};
const options = {
threshold: 0.2
};
const observer = new IntersectionObserver(callback, options);
const container = $('#main');
const targetElements = $('.main-content .inner-container');
$(targetElements).each((idx, item) => {
observer.observe(item);
});
.header-content {
background-color: blue;
height: 800px;
margin: 20px 0;
}
#main {
margin: 20px auto;
}
.main-content {
background-color: cyan;
}
#aside-content {
position: sticky;
top: 0;
align-self: flex-start;
background-color: red;
height: 100vh;
overflow-y: auto;
}
#aside-content a {
display: block;
margin: 40px auto;
text-decoration: none;
}
#aside-content a.active {
background-color: rgba(0, 255, 0, 0.5);
}
.aside-fixed {
position: fixed;
top: 0;
right: 0;
}
footer {
background-color: brown;
height: 200px;
}
<link href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/litera/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Test</a>
</nav>
<section class="container">
<div class="row">
<div class="col-md-12">
<div class="header-content">
<h3>header content</h3>
</div>
</div>
</div>
</section>
<section class="container" id="main">
<div class="row">
<div class="col-8">
<div class="main-content">
<div id="text1" class="inner-container">
<h2>Text 1</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit.
</div>
<div id="text2" class="inner-container">
<h2>Text 2</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harumti aspernatur delectus mollitia libero similique assumenda quos sequi eligendi?
</div>
<div id="text3" class="inner-container">
<h2>Text 3</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi, maxime repellat aperiam labore exercitationem enim possimus. Suscipit facilis debitis quidem excepturi?
</div>
<div id="text4" class="inner-container">
<h2>Text 4</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text5" class="inner-container">
<h2>Text 5</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text6" class="inner-container">
<h2>Text 6</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text7" class="inner-container">
<h2>Text 7</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text8" class="inner-container">
<h2>Text 8</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
<div id="text9" class="inner-container">
<h2>Text 9</h2>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet provident recusandae, omnis laborum ad, pariatur debitis hic velit magni, expedita dicta vel nemo asperiores aperiam quia soluta esse consequuntur! Praesentium voluptate delectus, consequatur
dolore veniam vitae sint error ea, facere nisi reprehenderit harum doloremque asperiores repudiandae eligendi.
</div>
</div>
</div>
<div class="col-4" id="aside-content">
<div class="aside-content">
<h3>Table of Contents</h3>
<div>
Text 1
Text 2
Text 3
Text 4
Text 5
Text 6
Text 7
Text 8
Text 9
</div>
</div>
</div>
</section>
<footer>
<h3>footer</h3>
</footer>
I came across this accordion I would like to use for my site:
http://jsfiddle.net/subhranild/u5d35La7/1/
<div class="accordion">
<div class="accorfion-section">
<a class="accordion-section-title" href="#accordion-1">Accordion section #1</a>
<div id="accordion-1" class="accordion-section-content">
<p>This is first accordion section</p>
</div>
<a class="accordion-section-title" href="#accordion-2">Accordion section #2</a>
<div id="accordion-2" class="accordion-section-content">
<p> this is second accordian section</p>
</div>
<a class="accordion-section-title" href="#accordion-3">Accordion section #3</a>
<div id="accordion-3" class="accordion-section-content">
<p> this is third accordian section</p>
</div>
</div>
</div>
$(document).ready(function(){
$('.accordion-section-title').click(function(e){
var currentAttrvalue = $(this).attr('href');
if($(e.target).is('.active')){
$(this).removeClass('active');
$('.accordion-section-content:visible').slideUp(300);
} else {
$('.accordion-section-title').removeClass('active').filter(this).addClass('active');
$('.accordion-section-content').slideUp(300).filter(currentAttrvalue).slideDown(300);
}
});
});
however, whenever one of the headers is opened, the scroll moves to have the opened content at the top of the page. How can I edit this code to disable the auto-scroll?
I've seen some people online saying change the href to equal #, but when I do that the accordion no longer works.
Thanks.
Just by adding e.preventDefault(); on the click function in your Javascript as below working example.
$(document).ready(function() {
$('.accordion-section-title').click(function(e) {
e.preventDefault();
var currentAttrvalue = $(this).attr('href');
if($(e.target).is('.active')) {
$(this).removeClass('active');
$('.accordion-section-content:visible').slideUp(300);
} else {
$('.accordion-section-title').removeClass('active').filter(this).addClass('active');
$('.accordion-section-content').slideUp(300).filter(currentAttrvalue).slideDown(300);
}
});
});
.wrapper {
height: 100%;
}
.accordion
{
overflow:hidden;
border-radius:4px;
background:#f7f7f7;
}
.accordion-section-title
{
width:100%;
padding:15px;
}
.accordion-section-title
{
width: 100%;
padding: 15px;
display: inline-block;
background-color: #333;
border-bottom: 1px solid #1a1a1a;
font-size: 1.2em;
color: #fff;
transition: all linear 0.5s;
text-decoration:none;
}
.accordion-section-title.active
{
background-color:#4c4c4c;
text-decoration:none;
}
.accordion-section-title:hover
{
background-color:grey;
text-decoration:none;
}
.accordion-section:last-child .accordion-section-title
{
border-bottom:none;
}
.accordion-section-content
{
padding:15px;
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrapper">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium voluptates earum facilis eveniet mollitia assumenda aperiam, ex temporibus neque aspernatur similique eligendi est harum obcaecati, ipsam velit, quis doloremque expedita, hic! Soluta, omnis itaque optio, inventore, assumenda totam adipisci vel eius, distinctio amet dolorem tempore sit. Accusamus, voluptas! Quam animi, esse soluta porro nesciunt incidunt nisi autem distinctio corrupti, dolores impedit obcaecati. Sequi sit facilis, accusamus neque quod tempore, amet ratione, veritatis commodi, velit necessitatibus dolorum maxime. Facere qui esse, rerum quo nihil, accusamus sint assumenda. Eaque asperiores recusandae, dolores omnis tempore laborum sequi ipsa unde in ipsam dolore maxime.
</p>
<div class="accordion">
<div class="accorfion-section">
<a class="accordion-section-title" href="#accordion-1">Accordion section #1</a>
<div id="accordion-1" class="accordion-section-content">
<p>This is first accordion section</p>
</div>
<a class="accordion-section-title" href="#accordion-2">Accordion section #2</a>
<div id="accordion-2" class="accordion-section-content">
<p> this is second accordian section</p>
</div>
<a class="accordion-section-title" href="#accordion-3">Accordion section #3</a>
<div id="accordion-3" class="accordion-section-content">
<p> this is third accordian section</p>
</div>
</div>
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium voluptates earum facilis eveniet mollitia assumenda aperiam, ex temporibus neque aspernatur similique eligendi est harum obcaecati, ipsam velit, quis doloremque expedita, hic! Soluta, omnis itaque optio, inventore, assumenda totam adipisci vel eius, distinctio amet dolorem tempore sit. Accusamus, voluptas! Quam animi, esse soluta porro nesciunt incidunt nisi autem distinctio corrupti, dolores impedit obcaecati. Sequi sit facilis, accusamus neque quod tempore, amet ratione, veritatis commodi, velit necessitatibus dolorum maxime. Facere qui esse, rerum quo nihil, accusamus sint assumenda. Eaque asperiores recusandae, dolores omnis tempore laborum sequi ipsa unde in ipsam dolore maxime.
</p>
</div>