React scroll to ref with multiple scrollbars - javascript

I have a small problem that I can't figure out.
I have an element inside my page with a scrollbar. This means I got the main page scrollbar and a second scrollbar. I have a button inside that element that triggers a new div with some content inside of it. But that div is outside the view of the element so you need to scroll to see it. This is not really user friendly so I am trying to add a function that when you click on that button it scrolls to the new div.
Picture of element: https://imgur.com/8wIOTqo
button is the gold coloured one
The problem is that it is using the main page scrollbar and not the scrollbar of the element. Does anyone know how to fix this? Here is my code
// Function to open the element and scroll to the ref
function enableOtherAddressActive() {
secondDeliveryAddressRef.current.scrollIntoView();
setOtherAddress(true);
}
<div className="deliveryaddress__different">
{otherAddress ? (
<div className="deliveryaddress__different-btn btn btn--primary" onClick={disableOtherAddressActive}>Afwijkend bezorgadres verwijderen</div>
) : (
<div className="deliveryaddress__different-btn btn btn--primary" onClick={enableOtherAddressActive}>Afwijkend bezorgadres toevoegen</div>
)}
</div>
<div className="deliveryaddress__second" ref={secondDeliveryAddressRef}>
{otherAddress ? (
<div className="deliveryaddress__inner">
<h3 className="deliveryaddress__title">
Afwijkend bezorgadres toevoegen
</h3>
</div>
) : undefined}
</div>
</div>

One of the way to scroll to the element is assigning a id to the div and using scrollInto that
I have done in the codesandbox below refer it shows how to scroll into a particular element even if it is nested scrollbar
Code:
const handleScrollTo = () => {
setTimeout(() => {
document.getElementById(`element`) &&
document.getElementById(`element`).scrollIntoView({
behavior: "smooth",
block: "center"
});
}, 1000);
};

Related

How can I make left/right button disappear when the scroll gets to the end of the container?

I have created a list of tab items, wrapped by a <ul> container. I have given this container a max-width and overflow-x properties, so the list of tab items overflows it.
This is the base code for the <ul> wrapper and the mapped list of tab items.
<ul className="tabs" ref={wrapperRef}>
{tabs.map((tab) => (
<li
onClick={() => setActive(tab)}
className={`tab ${tab === active ? "active" : ""}`}
key={tab}
>
{tab}
</li>
))}
</ul>
Then, I have added two buttons, positioned absolute, to the left and the right. These buttons will scroll to the left end or the right end of the container. When we get to the right end of the container, for example, the "Right" button must disappear. Same for the other side, the "Left" button disappears.
The code is as follows:
<div className="tabs__wrapper">
<ul className="tabs" ref={wrapperRef}>
{tabs.map((tab) => (
<li
onClick={() => setActive(tab)}
className={`tab ${tab === active ? "active" : ""}`}
key={tab}
>
{tab}
</li>
))}
</ul>
<button className="left" onClick={() => adjustView("left")}>
Left
</button>
<button className="right" onClick={() => adjustView("right")}>
Right
</button>
}
</div>
However, there is a problem. If we interact with the scroll manually, the buttons are still displayed like the last time we've interacted with them. For example, if I click the "Right" button, it scrolls to the end and the "Right" button disappears as expected, but, if I use the mouse to scroll the container to the left side, the "Right" button is still hidden, when it should show up, and the "Left" button should be hidden instead.
How can I do this?
Oh and one more thing, I would like the buttons to disappear only when the scroll has finished. I guess conditionally rendering the Buttons is not a solution anymore.
Here is the full Sandbox.
https://codesandbox.io/s/tab-scroll-3tzi80
You could do it like this (see this codesandbox ):
Listen for scroll event:
<ul className="tabs" ref={wrapperRef} onScroll={handleScroll}>
calculate if we're left, right or in between with the scroll event params, and update state:
const handleScroll = () => {
if (wrapperRef.current) {
const { scrollLeft, scrollWidth, clientWidth } = wrapperRef.current;
switch (scrollLeft + clientWidth) {
//Scroll is utter left
case clientWidth:
setDisableButton("left");
break;
//Scroll is utter right
case scrollWidth:
setDisableButton("right");
break;
//Scroll somewhere in between
default:
setDisableButton("none");
}
}
};
//Adjust view based on state
function adjustView(position) {
if (position === "left") {
scrollTabbar(wrapperRef?.current, 0);
} else {
scrollTabbar(wrapperRef?.current, wrapperRef.current?.scrollWidth);
}
}
The buttons also disappear only when scrolling is finished, so that's solved too! Both buttons are shown when we're neither left nor right.

Trigger play on video when two divs match up

I have created a way to scroll through divs, one has a menu and the others have divs with blanks but one has a video.
At the top of the page is a navigation menu that contains "next", "previous", "reload" and "start".
Those commands are warped in functions,
$("#next-item").on("click", function(){,
The page looks like this:
<div class="webcam-left">
<div class="bottom-panel">
<div class="center" id="content">
<div class="bottom-panel-post internal start"></div>
<div class="bottom-panel-post internal video-post"><video src="https://ia800606.us.archive.org/12/items/ACTV_News_open/ACTV_News_open.mp4"></video></div>
<div class="bottom-panel-post internal"></div>
</div>
</div>
</div>
<div class="nav-right nav-main">
<div class="rundown-panel">rundown</div>
<div class="rundown-items">
<div class="irl-today first"><div class="current">Welcome</div></div>
<div class="irl-today override">Category name</div>
<div class="irl-today">the end</div>
</div>
</div>
</div>
What I'm trying to do is when scrolling down the list, how do you trigger play on a video when a video is shown?
When scrolling down, I added classes to the divs that contain a video.
The left side has .override and the video side has .video-post.
I tried doing if hasClass() but it plays on the first click:
if ( $('.rundown-items').is('.override') ) {
if ($( '.bottom-panel-post' ).has('video')) {
$('video').trigger('play');
};
};
Working code - https://jsfiddle.net/openbayou/paonbxcL/8/
I figured it out, the problem was that it was looking for a class across all items and not each one individually so I added an .each function to look for a class on each individual div.
$(".slider-slide-wrap").each(function (i) {
var posLeft = $(this).position().left
var w = $(this).width();
// add shown class on a div
if (scrollLeft >= posLeft && scrollLeft < posLeft + w) {
$(this).addClass('shown').siblings().removeClass('shown');
}
// if .shown has .play-video, trigger play
if ($('.shown').is(".play-video")) {
$('video').trigger('play');
};
});

Clear part of div

This pop-up-category has height 0. When button is pressed, i am adding height 100%. Inside have pop-up-wrap-category div where my data is stored.
Also have div for user controls ( Close pop-up).
<div class="pop-up-category">
<div class="pop-up-wrap-category">
<p>clear just this content</p>
//this this should be still visible(populated)
<div class="user-controls">
<span class="close-popup btn btn-danger">Close</span>
</div>
</div>
</div>
js :
$(document).on("click", ".close-popup", function () {
// console.log("sdasd");
$('.pop-up-wrap-category').empty();
});
How to clear content from pop-up-wrap-category but users controls still stay visible ?
Find the p and clear p
$(document).on("click", ".close-popup", function () {
// console.log("sdasd");
$('.pop-up-wrap-category > p').empty(); //use .remove() if you want to get the p tag deleted from DOM
});

SlideToggle animation breaks with image and text

I'm trying to get a slidetoggle to work properly on a div. I have html in the following format:
<div class="root-div first-service">
<div class="title-div gradient">
<div class="title-div-left">
<p>$ServiceName</p>
</div>
<div class="title-div-right">
<p>▲</p>
</div>
</div>
<div class="description-div show minimum-height">
<div class="description-content-div">
$ServiceDescription
</div>
</div>
<div class="services-image-two">
<img src="themes/theinneryou/images/ServicesImage2.jpg" alt="Missing Image"/>
</div>
</div>
I also have javascript as follows:
$('.title-div').on('click', function () {
var arrow = $(this).find('.title-div-right');
if (proceed) {
proceed = false;
$(this).closest('.root-div').find('.services-image-two').slideToggle("slow");
$(this).closest('.root-div')
.find('.description-div')
.slideToggle("slow", function () {
$(arrow).text().trim().charCodeAt(0) == 9650 ? $(arrow).html('<p>▼</p>') : $(arrow).html('<p>▲</p>');
proceed = true;
});
}
});
The effect that I get is that the image itself plays the animation of slide and then gets hidden, then the rest of the next div which contains text only gets hidden without any animation. The image is overlapping the text div as I have it under absolute positioning. You can see the live demo at tiu.azularis.com/Services
Is there a way to make them gracefuly slide together when I click the arrow and then appear together when I click the down arrow?
I also tried moving the image div inside the description div and also tried setting .delay after first animation, but neither does the trick.
Change line 83 in Services.css:
.services-wrapper .expansion-wrap .first-service .minimum-height {
/* min-height: 20.4rem; */
height: 20.4rem;
}
min-height is messing it up.
Otherwise you have to fix your HTML + CSS for that whole section because it is not ideal.

Pop-up Div to appear on hover of button

I am creating a website where i want to display a div on hover of a button. Currently i am able to do this but it's not the desired effect. I have created a DEMO in jsfiddle to show what i have achieved and i will paste my HTML, jQuery and only the CSS which is pertaining to this question.
HTML
<div class="cart-btn" >CART
</div>
<div class="minicart" >
Items : 5
Total : $250
VIEW CART
</div>
jQuery
$(document).ready(function () {
$(".cart-btn").hover(
function () {
$(".minicart").show(100);
}, function () {
$(".minicart").hide(2000);
});
});
CSS
.minicart {
width:164px;
display: none;
background-color:#0A3151;
opacity:0.8;
position:absolute;
z-index:9999;
margin-left:450px;
margin-top:30px;
}
ISSUE: The desired effect i want is, "The div should slide from under the button" and dissapear in the same manner".
However my main concern is that the div should remain focused even when i hover over it. Currently it disappears as soon as i take my mouse away from the button. The div once displayed should remain displayed unless the user takes the mouse away either from the div or button.
A few things to note, when using absolute positioning use top instead of margin-top and so on.
Second to avoid the popup folding up when you leave the button use the following selector:
$(".cart-btn, .minicart").hover(
function () {
$(".minicart").slideDown(100);
}, function () {
$(".minicart").slideUp(2000);
});
Use slideDown and slideUp as BeNdErR sugested, here's an updated version of his fiddle
Wrap both button and div in another div. The use this div for hover-event.
<div id="cbutt">
<div class="cart-btn" >CART
</div>
<div class="minicart">Items : 5 Total : $250 VIEW CART
</div>
</div>
$(document).ready(function () {
$("#cbutt").hover(
function () {
$(".minicart").show(100);
}, function () {
$(".minicart").hide(2000);
});
})
Here is a fiddle:
http://jsfiddle.net/Ncj2E/
Hope this is what you wanted.

Categories