Jquery Start from Beginning When A Div Reaches The End of Scroll - javascript

So i was trying to create a automatic horizontal scroll div which keeps on scrolling its elements in an infinite loop. This is what I have achieved so far:
$(document).ready(function(){
function animatethis(targetElement, speed) {
var scrollWidth = $(targetElement).get(0).scrollWidth;
var clientWidth = $(window).width();
$(targetElement).animate({ scrollLeft: scrollWidth - clientWidth },
{
duration: speed,
complete: function () {
$(targetElement).scrollLeft(0);
animatethis(targetElement, speed);
}
});
};
animatethis($('.editors-pick-slideshow'), 10000);
});
.editors-pick-slideshow {
border: 1px solid;
width: 100%;
height: 500px;
overflow-y: hidden;
overflow-x: auto;
display: block;
margin: auto;
}
.editors-pick-container {
width: 3150px;
}
.editors-pick-container > div {
display: inline-block;
width: 1000px;
margin: 0px 20px;
}
.editors-pick-elements {
display: grid;
grid-template-columns: 1fr 1fr;
max-width: 1000px;
min-width: 300px;
border: 1px solid green;
height: 500px;
grid-gap: 20px;
margin: auto;
}
.pick1 {
background-color: #ccc;
}
.pick2 {
background-color: #ccc;
}
.pick3 {
background-color: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="editors-pick-slideshow">
<div id="editorsPickContainer" class="editors-pick-container">
<div>
<div id="group1" class="editors-pick-elements">
<div class="pick1">Grid 1</div>
<div class="pick2">Grid 1</div>
</div>
</div>
<div>
<div id="group2" class="editors-pick-elements">
<div class="pick1">Grid 2</div>
<div class="pick2">Grid 2</div>
</div>
</div>
<div>
<div id="group3" class="editors-pick-elements">
<div class="pick1">Grid 3</div>
<div class="pick2">Grid 3</div>
</div>
</div>
</div>
</div>
As you can see in above snippet that when the animation reaches the end of the div it starts abruptly from the beginning. What I want to achieve here is when the animation reaches the end it should continue its flow towards the grid 1 element and keep on scrolling smoothly in an infinite manner. I hope what I am saying makes sense.

You can add a boolean parameter indicating which direction to scroll toward and negate the parameter each time the animation is complete.
function animatethis(targetElement, toEnd, speed) {
let pos;
if (toEnd) {
let scrollWidth = $(targetElement).get(0).scrollWidth;
let clientWidth = $(window).width();
pos = scrollWidth - clientWidth;
} else {
pos = 0;
}
$(targetElement).animate({
scrollLeft: pos
}, {
duration: speed,
complete: function() {
animatethis(targetElement, !toEnd, speed);
}
});
}
animatethis($('.editors-pick-slideshow'), true, 10000);
Live Example:
$(document).ready(function(){
function animatethis(targetElement, toEnd, speed){
let pos;
if(toEnd){
let scrollWidth = $(targetElement).get(0).scrollWidth;
let clientWidth = $(window).width();
pos = scrollWidth - clientWidth;
} else {
pos = 0;
}
$(targetElement).animate({ scrollLeft: pos},
{
duration: speed,
complete: function () {
animatethis(targetElement, !toEnd, speed);
}
});
}
animatethis($('.editors-pick-slideshow'), true, 10000);
});
.editors-pick-slideshow {
border: 1px solid;
width: 100%;
height: 500px;
overflow-y: hidden;
overflow-x: auto;
display: block;
margin: auto;
}
.editors-pick-container {
width: 3150px;
}
.editors-pick-container > div {
display: inline-block;
width: 1000px;
margin: 0px 20px;
}
.editors-pick-elements {
display: grid;
grid-template-columns: 1fr 1fr;
max-width: 1000px;
min-width: 300px;
border: 1px solid green;
height: 500px;
grid-gap: 20px;
margin: auto;
}
.pick1 {
background-color: #ccc;
}
.pick2 {
background-color: #ccc;
}
.pick3 {
background-color: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="editors-pick-slideshow">
<div id="editorsPickContainer" class="editors-pick-container">
<div>
<div id="group1" class="editors-pick-elements">
<div class="pick1">Grid 1</div>
<div class="pick2">Grid 1</div>
</div>
</div>
<div>
<div id="group2" class="editors-pick-elements">
<div class="pick1">Grid 2</div>
<div class="pick2">Grid 2</div>
</div>
</div>
<div>
<div id="group3" class="editors-pick-elements">
<div class="pick1">Grid 3</div>
<div class="pick2">Grid 3</div>
</div>
</div>
</div>
</div>

Related

Equal height of children of unrelated parents

I want to have an equal height of two unrelated divs. Basically, I need to equalize the height of Parent B's child to Parent A's child. Below is the image to highlight what it is about:
Any idea how this can be accomplished with jQuery. Most of the equal height solutions I came across are about children of the same parent.
The code I used is for children within a container.
$(document).ready(function(){
$('.containers').each(function(){
var min_highestBox = 0;
$('.columns', this).each(function(){
if($(this).height() > min_highestBox) {
min_highestBox = $(this).height();
}
});
$('.columns',this).height(min_highestBox);
});
});
.containers {border:1px solid; width:100%; display:inline-block;}
.columns {border:1px solid red; padding: 20px; min-width:20%; float:left;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="containers">
<div class="columns">This is<br />the highest<br />column</div>
<div class="columns">One line</div>
<div class="columns">Four<br />lines<br />the highest<br />column</div>
</div>
<div class="containers">
<div class="columns">One line</div>
<div class="columns">Two<br>lines</div>
<div class="columns">One line</div>
</div>
I have tried it with a CSS grid but in this specific situation, a CSS grid is not a solution.
Update: the actual containers are both separate and independent of each other:
.a, .b {border:2px solid; padding: 25px; float:left; width: 200px;}
.a div, .b div {border:2px solid red;}
<div class="a">Parent A
<div>Child of A <br> some additional text</div>
</div>
<div class="b">Parent B
<div>Child of B</div>
</div>
In the case that they can't be placed inside a wrapper you can make use of a sorting from lowest to heighest and apply the heighest value to all affected nodes and a MutationObserver to easily monitor changes on these nodes to call the height-adjust routine again.
For equal height of parents:
$(document).ready(() => {
const selector = ".containers";
function resize() {
const nodes = $(selector)
.css("height", "auto")
.sort((a, b) => $(a).height() - $(b).height()),
heighest = nodes.last().height();
if (nodes.first().height() != heighest)
$(selector).css(`height`, `${heighest}px`);
}
resize();
const observer = new MutationObserver(resize);
$(selector).each((idx, el) => observer.observe(el, { childList: true, subtree: true }));
// Examples:
setTimeout(() => {
$(".columns").first().append("<br>Lorem<br>Ipsum<br>Dolor<br>sit<br>Amet");
}, 1500);
setTimeout(() => {
$(".columns").last().append("<br>Lorem<br>Ipsum<br>Dolor<br>sit<br>Amet");
}, 3000);
setTimeout(() => {
$(".columns").last().append("<br>Lorem<br>Ipsum<br>Dolor<br>sit<br>Amet");
}, 5000);
})
.containers {
border: 1px solid;
width: 100%;
display: inline-block;
}
.columns {
border: 1px solid red;
padding: 20px;
min-width: 20%;
float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="containers">
<div class="columns">This is<br>the highest<br>column</div>
<div class="columns">One line</div>
<div class="columns">Four<br>lines<br>the highest<br>column</div>
</div>
<div class="containers">
<div class="columns">One line</div>
<div class="columns">Two<br>lines</div>
<div class="columns">One line</div>
</div>
For equal height of childs:
$(document).ready(() => {
const selector = ".columns";
function resize() {
const nodes = $(selector)
.css("height", "auto")
.sort((a, b) => $(a).height() - $(b).height()),
heighest = nodes.last().height();
if (nodes.first().height() != heighest)
$(selector).css(`height`, `${heighest}px`);
}
resize();
const observer = new MutationObserver(resize);
$(selector).each((idx, el) => observer.observe(el, { childList: true, subtree: true }));
// Examples:
setTimeout(() => {
$(".columns").first().append("<br>Lorem<br>Ipsum<br>Dolor<br>sit<br>Amet");
}, 1500);
setTimeout(() => {
$(".columns").last().append("<br>Lorem<br>Ipsum<br>Dolor<br>sit<br>Amet");
}, 3000);
setTimeout(() => {
$(".columns").last().append("<br>Lorem<br>Ipsum<br>Dolor<br>sit<br>Amet");
}, 5000);
})
.containers {
border: 1px solid;
width: 100%;
display: inline-block;
}
.columns {
border: 1px solid red;
padding: 20px;
min-width: 20%;
float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="containers">
<div class="columns">This is<br>the highest<br>column</div>
<div class="columns">One line</div>
<div class="columns">Four<br>lines<br>the highest<br>column</div>
</div>
<div class="containers">
<div class="columns">One line</div>
<div class="columns">Two<br>lines</div>
<div class="columns">One line</div>
</div>
If you consider an extra wrapper you can do it with only CSS
.wrapper {
display: grid;
gap: 5px;
grid-auto-rows: 1fr; /* eqaul containers */
}
.containers {
border: 1px solid;
display: flex; /* equal childs */
}
.columns {
border: 1px solid red;
padding: 20px;
min-width: 20%;
}
<div class="wrapper">
<div class="containers">
<div class="columns">This is<br />the highest<br />column</div>
<div class="columns">One line</div>
<div class="columns">Four<br />lines<br />the highest<br />column</div>
</div>
<div class="containers">
<div class="columns">One line</div>
<div class="columns">Two<br>lines</div>
<div class="columns">One line</div>
</div>
</div>

Horizantal scroll right to element

I am trying to scroll to right of each element, but could not calculate right of element and scroll to it.
var $scroller = $('.scroller');
$('button').on('click', function() {
var divIdx = $('input').val();
var scrollTo = $('#d' + divIdx)
.css('background', '#9f3')
.position().left;
console.log(scrollTo);
$scroller
.animate({
'scrollLeft': scrollTo
}, 500);
});
.scroller {
width: 300px;
height: 100px;
overflow-x: auto;
overflow-y: hidden;
direction: rtl;
}
.container {
position: relative;
/*important for the .position() method */
height: 100px;
width: 770px;
}
.container div {
height: 90px;
width: 60px;
float: right;
margin: 5px;
background: #39f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroller">
<div class="container">
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
<div id="d5"></div>
<div id="d6"></div>
<div id="d7"></div>
<!-- ... -->
</div>
</div>
<button>Scroll to: </button> <input type="text" value="4" />
How to calculate right of element and scroll to right of element?
How to calculate right of element and scroll to right of element?
How to calculate right of element and scroll to right of element?
You can use this one.
var $scroller = $('.scroller');
$('button').on('click', function() {
var divIdx = $('input').val();
var div = $('#d' + divIdx);
div.css('background', '#9f3');
var divLeft = div.offset().left;
var divWidth = div.width();
var scrollerWidth = $('.scroller').width();
var scrollTo = divLeft - scrollerWidth + divWidth;
$scroller
.animate({
'scrollLeft': scrollTo
}, 500);
});
.scroller {
width: 300px;
height: 100px;
overflow-x: auto;
overflow-y: hidden;
}
.container {
position: relative;
/*important for the .position() method */
height: 100px;
width: 770px;
}
.container div {
height: 90px;
width: 60px;
float: left;
margin: 5px;
background: #39f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroller">
<div class="container">
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
<div id="d5"></div>
<div id="d6"></div>
<div id="d7"></div>
<!-- ... -->
</div>
</div>
<button>Scroll to: </button> <input type="text" value="5" />
You just need to add some right margin and it's all done!
var $scroller = $('.scroller');
$('button').on('click', function() {
var divIdx = $('input').val();
var scrollTo = $('#d' + divIdx)
.css('background', '#9f3')
.position().left;
console.log(scrollTo);
$scroller
.animate({
'scrollLeft': scrollTo
}, 500);
});
.scroller {
width: 300px;
height: 100px;
overflow-x: auto;
overflow-y: hidden;
}
.container {
position: relative;
/*important for the .position() method */
height: 100px;
width: 600px;
}
.container div {
height: 90px;
width: 60px;
float: right;
margin: 5px;
background: #39f;
}
.container div:first-child {
margin-right: 240px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroller">
<div class="container">
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
<div id="d5"></div>
<div id="d6"></div>
<div id="d7"></div>
<!-- ... -->
</div>
</div>
<button>Scroll to: </button> <input type="text" value="4" />
There are two points to consider -
position().left gives you the value of the distance upto left edge of element only. So to get the value upto right edge, you can take left position of the element + the width of the element. $('#d' + divIdx).position().left + $('#d' + divIdx).width()
There should be additional one item's width white space after the last item which allow the scrollbar to move upto the end of the last item.

Resize sidebar on content scroll

Im trying to achieve this example for my layout.
https://youtu.be/itV7jvKpWXc
when i scroll content horizontally, my sidebar should change in width for the same amount of horizontal scroll till i reach min-width of sidebar ?
Any easy way to approach it ?
Add to your main-content onscroll
<div class="main-content" onscroll="resizeSidebar()"></div>
In your javascript add the function:
function resizeSidebar(){
document.getElementById("sidebar").style.width = "50px";
}
you can add to the sidebar css:
.sidebar {
transition: 0.5s;
}
It makes the animation for open with slide
this is plus minus what i was trying to achieve, tho it have smull ugly bug when i use horizontal scroll when sidebar reduces in size it makes scrollbar jump also :D
$('.content').scroll(function() {
var scrolling = $(".content").scrollLeft();
console.log(scrolling);
if (scrolling >= 50) {
if(!$(".sidebar").hasClass('SmallSidebar')){
$(".sidebar").addClass("smallSidebar");
}
}
else{
$(".sidebar").removeClass("smallSidebar");
}
if (scrolling >= 50) {
if(!$(".content").hasClass('smallContent')){
$(".content").addClass("smallContent");
}
}
else{
$(".content").removeClass("smallContent");
}
});
$(function(){
var curDown = false,
curYPos = 0,
curXPos = 0;
$('.content').mousemove(function(m){
if(curDown === true){
$('.content').scrollTop($('.content').scrollTop() + (curYPos - m.pageY));
$('.content').scrollLeft($('.content').scrollLeft() + (curXPos - m.pageX));
}
});
$('.content').mousedown(function(m){
curDown = true;
curYPos = m.pageY;
curXPos = m.pageX;
});
$('.content').mouseup(function(){
curDown = false;
});
})
var width = 0;
$('.inner-content').each(function() {
width += $(this).outerWidth( true );
});
$('.block').css('width', width);
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
div {
box-sizing: border-box;
}
.wrapper {
width: 100%;
height: 100vh;
}
.sidebar {
width: 33.33333%;
float: left;
background: blue;
height: 100vh;
transition: width 0.2s;
}
.sidebar.smallSidebar {
width: 80px;
}
.content {
width: 66.66666%;
float: left;
background: #171717;
height:100%;
overflow-y:hidden;
height: 100vh;
transition: width 0.2s;
position: relative;
}
.content.smallContent {
width: calc(100% - 80px);
}
.inner-content {
height: 100%;
padding: 50px 0px;
box-sizing: border-box;
display: flex;
align-items: center;
transition: width 0.2s;
position: absolute;
}
.block {
background: yellow;
max-width: 320px;
height: 400px;
float: left;
width: 100%;
margin: 0 20px;
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="sidebar"></div>
<div class="content">
<div class="inner-content">
<div style="background: #c39eb2;" class="block"></div>
<div style="background: #a4af93" class="block"></div>
<div style="background: #0fe7ad;" class="block"></div>
<div style="background: #f75f31;" class="block"></div>
<div style="background: #9473c0;" class="block"></div>
<div style="background: #46087f;" class="block"></div>
<div style="background: #f59000;" class="block"></div>
<div style="background: #22e318;" class="block"></div>
<div style="background: #71454e;" class="block"></div>
<div style="background: #7eb544;" class="block"></div>
<div style="background: #2fe218;" class="block"></div>
<div style="clear: both;"></div>
</div>
</div>
<div style="clear: both;"></div>
</div>

Pause jQuery On Hover

I just want the ability to be able to pause the animation on mouse hover. I trying to looking good way to do that, but there was some issues. I tested some hover/stop functions, but I can't get these working correctly.
jQuery(document).ready(function() {
setInterval(function() {
jQuery('#testimonials .slide').filter(':visible').fadeOut(1000, function() {
if (jQuery(this).next('.slide').size()) {
jQuery(this).next().fadeIn(1000);
} else {
jQuery('#testimonials .slide').eq(0).fadeIn(1000);
}
});
}, 5000);
});
#quote {
width: 100%;
height: 130px;
background-position: center bottom;
background-repeat: no-repeat;
margin-bottom: 65px;
overflow: hidden;
}
#testimonials .slide {
color: #555555;
}
#testimonials .testimonial-quote {
display: inline;
width: 600px;
height: 170px;
margin: 0;
padding: 0;
float: left;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="quote">
<div id="testimonials">
<div class="slide">
<div class="testimonial-quote">
<p>Text 1</p>
<h4 class="title">Title 1</h4>
</div>
</div>
</div>
</div>
You can achieve this by calling clearInterval() when the slide is hovered, then re-creating the interval again when the mouse leaves the slide, something like this:
jQuery(document).ready(function($) {
var $slides = $('#testimonials .slide');
function beginSlideInterval() {
return setInterval(function() {
$slides.filter(':visible').fadeOut(1000, function() {
var $next = $(this).next().length ? $(this).next() : $slides.first();
$next.fadeIn(1000);
});
}, 3000);
}
var slideInterval = beginSlideInterval();
$slides.on('mouseenter', function() {
clearInterval(slideInterval);
}).on('mouseleave', function() {
slideInterval = beginSlideInterval();
});
});
#quote {
width: 100%;
height: 130px;
background-position: center bottom;
background-repeat: no-repeat;
margin-bottom: 65px;
overflow: hidden;
}
#testimonials .slide {
color: #555555;
}
#testimonials .testimonial-quote {
display: inline;
width: 600px;
height: 170px;
margin: 0;
padding: 0;
float: left;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="quote">
<div id="testimonials">
<div class="slide">
<div class="testimonial-quote">
<p>Text 1</p>
<h4 class="title">Title 1</h4>
</div>
</div>
</div>
</div>
Note that I shortened the interval to make the effect more obvious.

Closable div - Left div slides close, while right div width expands

I'm trying to make a div on the left side that can close by sliding to the left While the content in the right div expands to 100% filling the space of the closed div. image example
I found a demo here but its only for the closable div.
<div id="intro-wrap">
<div class="open-intro">+</div>
<div class="close-intro">-</div>
<div id="contentWrap">
<h1 class="main-header">Here is a Title</h1>
<p class="main-desc">You can write whatever you want about yourself here. You can say you're a superhuman alien ant, arrived from the nether regions of Dwarf-Ant-Dom.</p>
</div>
</div>
It has some work to do, but it'll get you started.
$(function() {
"use strict";
var isOpen = true;
$('#open-close').on('click', function() {
if (isOpen) {
animate(false);
isOpen = false;
} else {
animate(true);
isOpen = true;
}
});
});
function animate(action) {
if (action) {
$('#left').animate({ width: "30vw" }, 600);
$('#right').animate({width: "70vw",marginLeft: "-5px"}, 600);
} else {
$('#left').animate({width: "0px"}, 600);
$('#right').animate({width: "99vw" }, 600);
}
}
* {
padding: 0;
margin: 0;
}
#wrapper{
width: 100vw;
height: 100px;
border: 2px solid purple;
}
#wrapper > *{
display: inline-block;
}
#left {
position: relative;
width: 30vw;
height: 100px;
background: green;
}
#right {
position: relative;
width: 65vw;
height: 100px;
background: navy;
}
#open-close {
position: absolute;
width: 10px;
height: 10px;
margin-top: 5px;
margin-left: 5px;
background: red;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="left"></div>
<div id="right">
<div id="open-close"></div>
</div>
</div>

Categories