Horizontal scroller edge detection - javascript

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/

Related

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>

jQuery bind / unbind not working

I'm trying to create a simple slider. Here is a example but slider next and prev button not working properly.
// next
var next = $('.next').click(function() {
var storepos = $(".storepos").val();
$('.prev').bind('click');
$('.storepos').val($('.storepos').val() / 1 + 110);
$('.container').animate({
scrollLeft: $('.storepos').val()
}, 200);
});
//prev
$('.prev').click(function() {
var storepos = $(".storepos").val();
$('.next').bind('click');
$('.storepos').val($('.storepos').val() / 1 - 110);
$('.container').animate({
scrollLeft: $('.storepos').val()
}, 200);
});
//after scrollend right event
$('.container').bind('scroll', function() {
if ($('.container').scrollLeft() + $(this).innerWidth() >= $(this)[0].scrollWidth) {
$('.next').unbind('click');
}
});
//after scrollend left event
$('.container').bind('scroll', function() {
if ($('.container').scrollLeft() < 1) {
$('.prev').unbind('click');
}
});
.container {
overflow: hidden !important
}
.container::-webkit-scrollbar {
width: 0;
height: 0
}
.content {
width: 1600px
}
.items {
background: black;
color: white;
margin-left: 10px;
width: 100px;
height: 100px;
float: left;
text-align: center
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content">
<div class="items">1</div>
<div class="items">2</div>
<div class="items">3</div>
<div class="items">4</div>
<div class="items">5</div>
<div class="items">6</div>
<div class="items">7</div>
<div class="items">8</div>
<div class="items">9</div>
<div class="items">10</div>
</div>
</div>
Prev / Next
<input class="storeposx" value="" />
<input class="storepos" value="" />
fiddle
I see two errors. First, the previous button is active from the begging, enabling scrolling to negative values. Second, you do unbind the events when reaching the end both sides, but you're not bind them back after that.
I used two variables where I keep the buttons status. When I reach the start or end position I don't unbind them, instead I just return false on click.
// next
var next = $('.next').click(function() {
if (!nextIsActive || $('.container').is(':animated')) return false;
var storepos = $(".storepos").val();
$('.prev').bind('click');
$('.storepos').val($('.storepos').val() / 1 + 110);
$('.container').animate({
scrollLeft: $('.storepos').val()
}, 200);
});
//prev
$('.prev').click(function() {
if (!prevIsActive || $('.container').is(':animated')) return false;
var storepos = $(".storepos").val();
$('.next').bind('click');
$('.storepos').val($('.storepos').val() / 1 - 110);
$('.container').animate({
scrollLeft: $('.storepos').val()
}, 200);
});
var nextIsActive=true;
var prevIsActive=false;
//after scrollend right event
$('.container').bind('scroll', function() {
if ($('.container').scrollLeft() + $(this).innerWidth() >= $(this)[0].scrollWidth) {
nextIsActive=false;
}else{
nextIsActive=true;
}
});
//after scrollend left event
$('.container').bind('scroll', function() {
if ($('.container').scrollLeft() < 1) {
prevIsActive=false;
}else{
prevIsActive=true;
}
});
.container{overflow:hidden !important}
.container::-webkit-scrollbar {
width:0;
height:0
}
.content {width:1600px}
.items { background:black;
color:white;
margin-left:10px;
width:100px;
height:100px;
float:left;
text-align:center
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content">
<div class="items">1</div>
<div class="items">2</div>
<div class="items">3</div>
<div class="items">4</div>
<div class="items">5</div>
<div class="items">6</div>
<div class="items">7</div>
<div class="items">8</div>
<div class="items">9</div>
<div class="items">10</div>
</div>
</div>
Prev / Next
<input class="storeposx" value="" />
<input class="storepos" value="" />

jQuery - How to make images overlap when fading in and out?

So I have this:
https://jsfiddle.net/ysr50m2m/1/
Html
class="photoset">
<img src="http://inspirebee.com/wp-content/uploads/2013/04/animal-fashion-parade.jpg" />
<img src="http://www.fubiz.net/wp-content/uploads/2013/03/Fashion-Zoo-Animals18.jpg" />
<img src="http://inspirebee.com/wp-content/uploads/2013/04/animal-in-fashion.jpg" />
<img src="http://www.fubiz.net/wp-content/uploads/2013/03/Fashion-Zoo-Animals20.jpg" />
</div>
<div class="photoset">
<img src="http://www.fubiz.net/wp-content/uploads/2013/03/Fashion-Zoo-Animals26.jpeg" />
<img src="http://www.fubiz.net/wp-content/uploads/2013/03/Fashion-Zoo-Animals14.jpg" />
<img src="http://inspirebee.com/wp-content/uploads/2013/04/animal-fashion.jpg" />
<img src="https://framboisemood.files.wordpress.com/2013/04/fashion-zoo-animals13.jpg" />
<img src="http://www.fubiz.net/wp-content/uploads/2013/03/Fashion-Zoo-Animals9.jpg" />
</div>
CSS
.photoset > img:not(:first-child) {
display: none;
}
JavaScript
$(document).ready(function() {
$('.photoset').each(function(){
$(this).data('counter', 0);
});
var showCurrent = function(photoset) {
$items = photoset.find('img');
var counter = photoset.data('counter');
var numItems = $items.length;
var itemToShow = Math.abs(counter % numItems);
$items.fadeOut();
$items.eq(itemToShow).fadeIn();
};
$('.photoset').on('click', function(e) {
e.stopPropagation();
var photoset = $(this);
var pWidth = photoset.innerWidth();
var pOffset = photoset.offset();
var x = e.pageX - pOffset.left;
if (pWidth / 2 > x) {
photoset.data('counter', photoset.data('counter') - 1);
showCurrent(photoset);
} else {
photoset.data('counter', photoset.data('counter') + 1);
showCurrent(photoset);
}
});
});
and I want the images to overlap. When I click an image, the next one appears first on the bottom and then it appears in place of the first image.
How can I solve this issue? Thanks in advance.
Since 2 elements can't occupy the same position unless they're positioned to do so, I absolutely placed the other image above the previous one, and when the previous one disappears, I removed the absolute positioning.
Fiddle:
https://jsfiddle.net/qu1Lxjo1/
CSS:
.photoset {
position: relative;
}
.photoset img {
position: relative;
top: 0px;
left: 0pxx
}
JS:
$items.fadeOut();
$items.eq(itemToShow).fadeIn({done: function() {
$(this).css('position','relative')
}}).css('position', 'absolute');
};

Make dynamic div elements collapse like collapsable headers

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.

How can i unify 2 images with drag and drop?

i have 2 css classes , left side and right side of screen and i need to put them togheter, in these classes i have images which look like a puzzle:
By dragging image from the right side to the left side.At drop,must fit with the image from left side. I read about drag and drop but didnt find something like that :(
What i've tried?
EDIT: http://postimg.org/image/je31ptb6d/ (this is an example with my pictures.On top are images separated as classes - class="left" for ca and class="right" for nă.On bottom are images after i drop the image from right to one from left.My question is how to specify the correct drop zone to make images look like bottom one from link after i drop image from right side? )
JS/Jquery:
// shuffle function for right side only
$(document).ready(function() {
var a = $(".right > img").remove().toArray();
for (var i = a.length - 1; i >= 1; i--) {
var j = Math.floor(Math.random() * (i + 1));
var bi = a[i];
var bj = a[j];
a[i] = bj;
a[j] = bi;
}
$(".right").append(a);
});
// drag and drop
$(function() {
$( ".right img" ).draggable
({
cursor: 'move',
revert: 'invalid',
});
$( ".left img" ).droppable({
tolerance: 'fit',
});
});
HTML:
<div class="left">
<img class="piese" id="piesa1" src="images/Text_1.svg" />
<img class="piese" id="piesa2" src="images/Text_2.svg" />
<img class="piese" id="piesa3" src="images/Text_3.svg" />
<img class="piese" id="piesa4" src="images/Text_4.svg" />
</div>
<div class="right">
<img class="piese" id="piesa5" src="images/Text_5.svg" />
<img class="piese" id="piesa6" src="images/Text_6.svg" />
<img class="piese" id="piesa7" src="images/Text_7.svg" />
<img class="piese" id="piesa8" src="images/Text_8.svg" />
</div>
To solve your problem you must build a grid
and use drag drop by taking as a reference the location of the squares of the grid.
This is a simple example to give you an idea.
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<style>
#grid{
background-color: #09F;
height: 130px;
width: 390px;
position:relative;
margin:100px auto;
}
.square{
height: 128px;
width: 128px;
border:1px solid #999;
float:left;
}
#first-image{
position: absolute;
left: 0px;
}
#second-image{
position: absolute;
right: 0px;
}
</style>
</head>
<body>
<!--take two images by 120px with this class and id -->
<div id="grid">
<img class="dr" id="first-image" src="your-image.png" width="128" height="128">
<img class="dr" id="second-image" src="your-image.png" width="128" height="128">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
for(xx = 0; xx < 3; xx++) {
$("#grid").append($('<div class="square"></div>'));
};
$('.dr').on("dragstart", function (event) {
var dt = event.originalEvent.dataTransfer;
dt.setData('Text', $(this).attr('id'));
});
$('div.square').on("dragenter dragover drop", function (event) {
event.preventDefault();
if (event.type === 'drop') {
var data = event.originalEvent.dataTransfer.getData('Text',$(this).attr('id'));
de=$('#'+data).detach();
var x = $(this).position().left;
var y = $(this).position().top;
de.css({'position':'absolute','top':y+'px','left':x+'px'}).appendTo($(this));
};
});
});
</script>
</body>
</html>

Categories