Make dynamic div elements collapse like collapsable headers - javascript

I'm looking to achieve something like this demo here, but for each element of a class, it will stop scrolling and drag the next div up from the bottom. This could be a similar thing to a printer printing paper. I'm not sure how it will fully work for the JS side but what I have is below. I'm close, but it doesn't like doing more than 2 elements. Adding the support for the extra elements would be amazing because then this could be released as a library to achieve the effect.
If the below snippet doesn't look like it works quite right view it here on codepen.
$(document).ready(function() {
$('.container:first-child').css('position', 'relative');
});
$(window).scroll(function() {
$('.container').each(function(i) {
var winheight = $(window).scrollTop() + $(window).height();
var distToTop = $(this).position().top + $(this).height();
var dist = distToTop - winheight;
if ((dist) <= 0) {
$(this).css('position', 'fixed').css('top', ($(this).children().height() - $(window).height()) / (-2) + 'px');
} else if (dist == $(this).height()) {
$(this).css('position', 'relative').css('top', $(window).height() + 'px').css('z-index','1');
}
console.log(dist + ' ' + i);
});
});
body {
margin: 0;
padding: 0;
}
.container {
position: fixed;
top: 100%;
}
.container:first-child {
background: tan;
width: 100%;
height: 100%;
}
.container:nth-child(2) {
background: blue;
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='big'>
<div class='container'>
<div class='t'>
<img src='http://placehold.it/500x250'>
<img src='http://placehold.it/500x250'>
</div>
</div>
<div class='container'>
<div class='t2'>
<img src='http://placehold.it/500x250/fff'>
<img src='http://placehold.it/500x250/fff'>
</div>
</div>
<div class='container'>
<div class='t'>
<img src='http://placehold.it/500x250'>
<img src='http://placehold.it/500x250'>
</div>
</div>
<div class='container'>
<div class='t2'>
<img src='http://placehold.it/500x250/fff'>
<img src='http://placehold.it/500x250/fff'>
</div>
</div>
</div>
The Demo on this site is currently a little wonky because of the difference in windows sizes.

Related

Add different images when mouse moving in jquery

I'm trying to make a jquery code where you can show different images (1-3 different images) when you move the mouse around.
The images will be right beside the cursor, and they will only appear 1-3, not more than that. And each time the mouse moves, these images will change.
I currently have this as my html code,
<div class="mainbody">
<section class="container">
<div class="img_div">
</div>
</section>
</div>
And my jquery code looks like this:
let img_array = ['./img/awards_icon.png', './img/norinuri_icon.png'];
$("div.mainbody").mousemove(function(e) {
for(i=0; i<img_array.length; i++){
$('.img_div').append("<img src='" + img_array[i] +"'/>");
$('.img_div').fadeIn("5000");
$('.img_div').finish().fadeOut("5000");
$('.img_div').offset({
left: e.pageX,
top: e.pageY + 20
});
}
});
The 2 images that I have in my jquery array appears when the mouse moves, but instead of only having 2 images these images add continuously, without stopping.
So each time I would move my mouse, the images would continue to add infinitely.
I will add more images in the jquery array for sure,
but how should I have only two images added, and change these images as I move the mouse?
Use background-image
var imageArr=["https://www.w3schools.com/css/paper.gif","https://www.w3schools.com/css/gradient_bg.png","https://www.w3schools.com/css/img_tree.png"];
var count=0;
$( ".mainbody" ).mouseover(function() {
$( ".img_div" ).css('background-image', 'url("' + imageArr[count] + '")');
if(count == imageArr.length-1)
count=0;
else
count++;
});
.mainbody{
width: 500px;
height: 500px;
border:1px solid red;
}
.img_div{
width: 200px;
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="mainbody">
<section class="container">
<div class="img_div">
</div>
</section>
</div>
Here is working fiddle;
USING mousemove (to avoid the images to change so many times while mouse move I use timeout)
var imageArr=["https://www.w3schools.com/css/paper.gif","https://www.w3schools.com/css/gradient_bg.png","https://www.w3schools.com/css/img_tree.png"];
var count=0;
var timeoutid = 0;
function setImage() {
$( ".img_div" ).css('background-image', 'url("' + imageArr[count] + '")');
if(count == imageArr.length-1)
count=0;
else
count++;
}
$(".mainbody").mousemove(function() {
clearTimeout(timeoutid);
timeoutid = setTimeout(setImage, 100);
});
.mainbody{
width: 500px;
height: 500px;
border:1px solid red;
}
.img_div{
width: 200px;
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="mainbody">
<section class="container">
<div class="img_div">
</div>
</section>
</div>
화이팅!
I have created a working example for you. You can try it now:
<div class="mainbody">
<section class="container">
<div class="img_div">
hello
</div>
</section>
css
.mainbody {
border:1px solid red;
display:block;
height:1000px
}
jquery
let img_array = ['https://anotherjavaduke.files.wordpress.com/2018/08/avataaars-2.png',
'https://images2.minutemediacdn.com/image/upload/c_crop,h_1192,w_2121,x_0,y_111/f_auto,q_auto,w_1100/v1554921884/shape/mentalfloss/22461-istock-176984635.jpg'];
$("div.mainbody").on('mousemove', function(e) {
var i;
$('.img_div').html('')
for (i = 0; i < img_array.length; i++) {
console.log($('.img_div').has('img').length)
if ($('.img_div').has('img').length < img_array.length) {
$('.img_div').append("<img style='width:100px; height:100px' src='" + img_array[i] + "'/>");
$('.img_div').fadeIn("5000");
$('.img_div').finish().fadeOut("5000");
$('.img_div').offset({
left: e.pageX,
top: e.pageY + 20
});
}
}
});
Working example
[Codepen] https://codepen.io/prashen/pen/ZEEqJEo

Add fade in/out effect to logos in header when they switch from one to the other on scroll down

I have logo1 in the header changing to logo2 when user scrolls down. However, I don't want the logos to instantly switch but rather the first logo gradually fade out as the second logo fades in. I have added .fadeIn(slow) and .fadeOut(slow) in various places in my js but it's had no effect. Hoping I can get some help with this.
I've updated my question with more code. I've had 2 answers but can't get either to work for me and no more responses. Hoping an edited question with more detail will get a bit more attention.
<header>
<div id="nav" class="navbar">
<div id="nav_left">
HOME
SERVICES
PORTFOLIO
</div>
<a href="index.html" id="logo" class="Claire_logo">
<img src="images/logo_6_small.png" alt="logo2" id="logo_Claire" class="logo_main"
style="display:none" />
<img src="images/logo_bluebird_90_cc.png" alt="logo1" id="logo_Claire_blue" class="logo" />
</a>
<div id="nav_right">
BLOG
ABOUT
GET IN TOUCH
</div>
</div>
</header>
$(document).ready(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > 0) {
$(".navbar").addClass("navbar-scroll");
$(".logo").show();
} else {
$(".navbar").removeClass("navbar-scroll");
$(".logo").hide();
}
if (scroll > 120) {
// $(".navbar").addClass("nav-color");
$(".logo_main").show();
$(".logo").hide();
} else {
// $(".navbar").removeClass("nav-color");
$(".logo_main").hide();
$(".logo").show();
}
});
});
You can do that using jQuery replaceWith
$(document).ready(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > 0) {
$('#oldlogo').fadeOut(500, function() {
$('#oldlogo').replaceWith('<div id="newlogo"><img src="newlogo" alt="newlogo"/></div>').fadeIn(500);
});
}
});
});
body {
height: 200vh
}
header {
height: 50px;
position: fixed;
top: 0;
width: 100%;
background: white;
}
#nav {
display: flex;
justify-content: center;
flex-direction: row;
height: 180px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<div id="nav" class="navbar">
<div id="oldlogo"> <img src="oldlogooldlogo" alt="oldlogo" /></div>
</div>
</header>
I edited my answer. I missed the error in your code. I commented below in codes. You can use both fadeIn & fadeOut or show & hide methods as well. But for fadeing effect using fadeIn & fadeOut maybe looks better than show & hide
$(document).ready(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 0 && scroll <= 120) { // I missed this logic mistake for the first time.
$(".navbar").addClass("navbar-scroll");
$(".logo").fadeIn(300); // or show(300)
} else {
$(".navbar").removeClass("navbar-scroll");
$(".logo").fadeOut(0); // or hide()
}
if (scroll > 120) {
// $(".navbar").addClass("nav-color");
$(".logo_main").fadeIn(300);
$(".logo").fadeOut(0);
} else {
// $(".navbar").removeClass("nav-color");
$(".logo_main").fadeOut(0);
$(".logo").fadeIn(300);
}
});
});

How to make an element scroll between two points [duplicate]

This question already has answers here:
Stop div scrolling once it reaches another div
(2 answers)
Closed 5 years ago.
I need to heading to scroll with the user, however only between two points. So scroll from its starting position with the user, to a certain position (above the contact us container) and then back with the user up.
Here is the current code used, this allows the heading to scroll until a certain point as required however does not scroll back up when the user scrolls up.
HTML:
<div id="header" class="row">
<div class="col-sm-5">
<h1 id="scrollwith">Our Services.</h1>
</div>
<div class="col-sm-6 col-sm-offset-1">
<img src="images/backdroppattern.png" style="width: 100%; height: 3000px;">
</div>
</div>
</div>
<div id="contact-container">
<div class="row">
<div class="col-sm-12">
<a class="contact-link" href="#"><h2>Contact us ➔</h2></a>
</div>
</div>
</div>
JS:
$(document).ready(function(){
var windw = this;
$.fn.followTo = function ( pos ) {
var $this = this,
$window = $(windw);
$window.scroll(function(e){
if ($window.scrollTop() > pos) {
$this.css({
position: 'absolute',
top: pos
});
} else {
$this.css({
position: 'fixed'
});
}
});
};
$('#scrollwith').followTo(2700);
});
All credits to this answer goes to #MicronXD from the post here.
jQuery.fn.extend({
followTo: function(elem, marginTop) {
var $this = $(this);
var $initialOffset = $this.offset().top;
setPosition = function() {
if ($(window).scrollTop() > $initialOffset) {
if (elem.offset().top > ($(window).scrollTop() + $this.outerHeight() + marginTop)) {
$this.css({
position: 'fixed',
top: marginTop
});
}
if (elem.offset().top <= ($(window).scrollTop() + $this.outerHeight() + marginTop)) {
$this.css({
position: 'absolute',
top: elem.offset().top - $this.outerHeight()
});
}
}
if ($(window).scrollTop() <= $initialOffset) {
$this.css({
position: 'relative',
top: 0
});
}
}
$(window).resize(function() {
setPosition();
});
$(window).scroll(function() {
setPosition();
});
}
});
$('#scrollwith').followTo($('#contact-container'), 0);
#contact-container {
background: red;
height: 900px;
}
#scrollwith {
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header" class="row">
<div class="col-sm-5">
<h1 id="scrollwith">Our Services.</h1>
</div>
<div class="col-sm-6 col-sm-offset-1">
<img src="images/backdroppattern.png" style="width: 100%; height: 3000px;">
</div>
</div>
<div id="contact-container">
<div class="row">
<div class="col-sm-12">
<a class="contact-link" href="#">
<h2>Contact us ➔</h2>
</a>
</div>
</div>
</div>

Function acting funny on resize

I have this banner ticker which works as you first load the page, but it gets messed up as you resize the second time and my assumption is that I am not calling the function in the right way on the resize event, any advice so I can understand what is going on?
jsfiddle
html
<div class="">
<div class="topBanners" style="float: left; width: 200px; ">
<p>First one</p>
</div>
<div class="topBanners" style="float: left; width: 200px; ">
<p>Second</p>
</div>
<div class="topBanners" style="float: left; width: 200px; ">
<p>Third</p>
</div>
</div>
js
$(document).ready(function() {
currentTopBanner = 0;
var topBanners = $('.topBanners');
console.log(topBanners.length);
function rotateTopBanners() {
if ($(window).width() < 768) {
topBanners.hide();
$(topBanners[currentTopBanner]).fadeIn('slow').delay(100).fadeOut('slow');
$(topBanners[currentTopBanner]).queue(function () {
currentTopBanner = currentTopBanner < topBanners.length - 1 ? currentTopBanner + 1 : 0;
rotateTopBanners();
$(this).dequeue();
});
} else {
topBanners.show();
}
}
rotateTopBanners();
$(window).resize(function () {
rotateTopBanners();
});
});

Horizontal scroller edge detection

How would I modify my script so it will detect the edge and not scroll more than the container width?
Mark-up and JS included and also JSFiddle - http://jsfiddle.net/carlozdre/4HSLb/8/
<div id="content">
<div class="inner">
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
</div>
</div>
<div style="">
<a class="left" href="#">LEEEEFT</a>
<a class="right" href="#">RIGHHHT</a>
</div>
<style>
#content { float: left; width: 600px; overflow: scroll; white-space: nowrap; max-width: 3000px;}
.inner {width: 300px;}
</style>
$(function () {
$('.left').click(function (e) {
e.preventDefault();
$('.inner').animate({
marginLeft: "-=" + 20 + "px"
}, 'fast');
});
$('.right').click(function (e) {
e.preventDefault();
$('.inner').animate({
marginLeft: "+=" + 20 + "px"
}, 'fast');
});
});
You need to make a couple of changes to ensure the size of the inner container is fixed to the size of the images within, and then check the left and right position of the inner container.
You are also better to animate to a specific coordinate rather than adding or subtracting from the previous one, as it will handle fast clicks much better.
Working example: http://jsfiddle.net/4HSLb/13/
Markup:
<div id="content">
<div class="inner">
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
<img src="http://lorempixum.com/300/300" />
</div>
</div>
<div style=""> <a class="left" href="#">LEEEEFT</a>
<a class="right" href="#">RIGHHHT</a>
</div>
CSS:
#content {
float: left;
width: 610px;
overflow: hidden;
white-space: nowrap;
max-width: 3000px;
}
.inner {
background:#444;
height:300px;
}
.inner img {
float:left;
margin-right:10px;
}
Script:
var left = 0;
var contentWidth = 0;
var innerWidth = 0;
var imgCount = 0;
var imgWidth = 310;
$(function () {
contentWidth = parseInt($('#content').innerWidth());
left = parseInt($('.inner').css('margin-left'));
imgCount = $('.inner img').size()
innerWidth = parseInt(imgCount * imgWidth);
$('.inner').width(innerWidth + "px");
$('.left').click(function (e) {
e.preventDefault();
updatePos(imgWidth);
if (left <= 0) {
$('.inner').animate({
marginLeft: left + "px"
}, 'fast');
}
});
$('.right').click(function (e) {
e.preventDefault();
updatePos(0 - imgWidth);
if (left >= 0 - innerWidth + (imgWidth * 2)) {
$('.inner').animate({
marginLeft: left + "px"
}, 'fast');
}
});
});
function updatePos(distance) {
console.log("NewPos: " + (left + distance));
console.log(0 - innerWidth);
if (left + distance <= 0 && left + distance >= 0 - innerWidth + (imgWidth * 2)) {
left = left + distance;
}
//console.log(left);
}
Edit:
Updated to prevent over scrolling when fast clicking.
Edit 2:
Updated code to allow the number of images in view to be easily changed. Rather than editing the example code above, here is an example on jsFiddle: http://jsfiddle.net/4HSLb/14/

Categories