Calculating multiple elements' position in order to .offset() it - javascript

Where I'm At
I've managed to get the location of all of the headshots of politicans in index.html using jQuery's .offset()
Where I'm Stuck
I'm looking to get each individual image's location on the page (using their class or id) and then change the current top and left values of the tooltip (which contains info about each of the politicians), using .offset() so it's appears near/above where the corresponding image of that politician is on the page.
UPDATE #1
#Roko: Can you elaborate on why the positioning needs to be fixed in this case. Likewise, with your suggested change, I can see the HTML for div class="tooltip" style="display: block; top: ... px; left ... px;"></div> but the numbers seem to have shifted the tooltip too much.
Tried:
$('img').each(function(){
var img = $(this);
img.click(function(){
$('.tooltip')
.show(100)
.text(img.attr('alt'))
.offset({
top : img.offset().top + img.height(),
left : img.offset().left
});
});
});
AND
var position = $el.data('.elem'),
ImagePosition = $el.offset(),
ImageSize = {
'width': $el.outerWidth(),
'height': $el.outerHeight()
};
'top': ImagePosition.top - el.outerHeight()
'left': ImagePosition.left - (elelment.outerWidth()/2) + (elementSize.width/2)
scripts.js
// Positioning of the tooltips
$(".headshot").click(function(){
// Fades in the tooltip
$(".tooltip").fadeIn("fast");
// This is the coordinates for current position of a tooltip
var coords = $(".tooltip").offset();
var height = $(".tooltip").height();
console.log(height);
var width = $(".tooltip").width();
console.log(width);
// How do I figure out how much top or left I need to move it?
alert("Top: " + coords.top + " Left: " + coords.left);
console.log(coords);
});
index.html
<div class="tooltip">
<div class="info">
<p class="tooltipName"></p>
<p class="tooltipParty"></p> <p class="tooltipConstuency"></p>
<p class="tooltipEthnicity"></p> <p class="tooltipAge"></p>
</div><!-- /.info -->
<div class="arrow-down">
</div><!-- /.arrow-down -->
</div><!-- /.tooltip -->
<img src="assets/img/headshots/allan.jpg" alt="" id="0" class="headshot NDP Female White">
<img src="assets/img/headshots/allum.jpg" alt="" id="1" class="headshot NDP Male White">
<img src="assets/img/headshots/altemeyer.jpg" alt="" id="2" class="headshot NDP Male White">
tooltip.scss
/*----------------------------------
TOOLTIP
----------------------------------*/
.tooltip {
display: none;
position: relative;
left: -12px;
top: -5px;
}
.info {
#include serifLight;
background: $yellow;
color: $black;
font-size: 1.4rem;
padding: 10px;
width: 9%;
text-align: center;
p {
margin: 0px;
}
}
.tooltipName, {
font-family: 'Roboto Slab',serif;
font-weight: 700;
}
.tooltipEthnicity, .tooltipAge {
display: inline;
}
.arrow-down {
width: 0;
height: 0;
border-left: 15px solid transparent;

jsBin demo
$('img').click(function(){
var img = $(this);
$('.tooltip')
.show(100)
.text( this.alt )
.css({
top : img.offset().top + img.height(),
left : img.offset().left
});
});
and
.tooltip {
display: none;
position: absolute; /* set to absolute */
left: -12px;
top: -5px;
}
also make sure to actually have some value inside the alt="" attribute!

Related

How to set the window size on a div as oppose to the entire window? [jQuery]

Good day,
I've came across the following CodePen from Estelle Pasquin. I would like to add this Apple-like scroll effect to my website.
Getting this to work on my site is no problem. However I would like to place content above this animation and this is where the problem comes in.
Based on the above CodePen content is structured like this:
<div class="intro mac"></div>
<div id="mac" class="mac"></div>
<div class="content">
<h2>Heading</h2>
<p>Content here</p>
</div>
However I need additional content above this animation section, like:
<div class="contentOne">
<h2>Heading 1</h2>
<p>Content here</p>
</div>
<div class="animationContent">
<div class="intro mac"></div>
<div id="mac" class="mac"></div>
</div>
<div class="content">
<h2>Heading 2 </h2>
<p>More content here</p>
</div>
In other words:
User scrolls through website content
User gets to a content break section where they see this big image, scroll, see the nice animation
User continues scrolling through rest of site
However this existing code only works when placed at the top of the page. Like a hero image.
In the JS file is can see the following variable declarations:
var $window = $(window);
var $intro = $('.intro');
var $mac = $('#mac');
var $h1 = $('h1');
My attempt
Looking at
var $window = $(window);
I can see the scroll is set on the window size. However I was thinking can't this be changed to a div. For example
var $window = $('#animationContent');
I would like this animation to work exactly as is just within a div placed on the page as opposed to being the first piece of content.
$(function() {
// cache all elements before we do anything
var $window = $(window);
var $intro = $('.intro');
var $mac = $('#mac');
var $h1 = $('h1');
// define variables and prefill
var offset = $mac.offset();
var windowHeight = $window.height();
var windowTop = $window.scrollTop();
var scrollPercent = (offset.top - windowTop) / offset.top;
var scale = 'scale(' + scrollPercent + ')';
// listen to scroll
$window.on('scroll', function() {
windowTop = $window.scrollTop();
// hide intro if point is reached
if (windowTop >= 940) {
$intro.hide();
} else {
if (windowTop < 200 && windowTop > 100) {
// only perform in a 100px range
$h1.fadeOut(500);
}
$intro.show();
scrollPercent = (offset.top - windowTop) / offset.top;
scale = 'scale(' + scrollPercent + ')';
$intro.css({
'transform': scale
});
}
});
});
#import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,800);
body {
color: #333;
font-family: Open sans;
}
h1 {
position: fixed;
top: 50%;
transform: translateY(-50%);
width: 100%;
text-align: center;
font-size: 52px;
z-index: 999;
color: rgba(255, 255, 255, 0.3);
}
.mac {
height: 613px;
width: 764px;
margin: 1340px auto 100px;
background: white url("https://i.imgur.com/AyELvGR.jpg") no-repeat 0 0;
background-size: 764px 613px;
backface-visibility: hidden;
}
.mac.intro {
position: fixed;
width: 2548px;
height: 2052px;
background-size: 100% auto;
margin: 0;
top: 0;
left: 50%;
margin-top: -300px;
margin-left: -1274px;
transform-origin: 50%;
}
.content {
width: 500px;
margin: 0 auto 150px;
}
.content h2 {
font-size: 52px;
line-height: 1.0865;
font-weight: 300;
margin-bottom: 48px;
}
.content p {
font-size: 18px;
margin: 1em 0 0 0;
line-height: 1.8;
color: #555;
font-weight: 400;
}
.content p a {
color: #555;
text-decoration: underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<h1>Just scroll!</h1>
<div class="intro mac"></div>
<div id="mac" class="mac"></div>
<div class="content">
<h2>Apple iMac scrolling effect.</h2>
<p>
iMac 27" mockup by Koy Carraway.<br/> Picture from WallWideHD - Transfagarasan.<br/> Read more about Transfagarasan <a href="http://en.wikipedia.org/wiki/Transf%C4%83g%C4%83r%C4%83%C8%99an"
target="_blank">here</a>.
</p>
</div>

appendTo adds element to another one, but it does not show on the website

I am trying to add arrows to my simple lightbox. The arrows are simple symbols "<" and ">. I have created them with jquery and when I try to add them to the image, they show up in the developer tools but not in the website for whatever reason. Can you tell me what's the problem please?
Here is the screenshot of the issue, if you did not understand my poor english. As you can see, the arrows are created in developer tools, but they cannot be found on the website. https://prnt.sc/26lyfbc
//Gallery Lightbox made with Jquery
let gallery = $('#gallery'),
overlay = $('<div = id = "overlay"></div>').appendTo('body').hide();
//Opens the lightbox with chosen image
gallery.find('a').on("click", function(event){
event.preventDefault();
let href = $(this).attr('href'),
image = $('<img>', {src: href}),
larrow = $('<div = id = "larrow"> < </div>'); //LEFT ARROW
rarrow = $('<div = id = "rarrow"> > </div>'); //RIGHT ARROW
image.appendTo(overlay);
larrow.appendTo(image);
overlay.show();
//Closes the Lightbox with the image, by clicking on the overlay
$(document).on("click", "#overlay", function(){
overlay.hide();
image.remove();
})
})
.gallery {
display: none;
opacity: 0;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
width: 1004px;
margin: 0 auto;
}
.gallery img {
position: relative;
top: 100px;
height: 200px;
width: 300px;
margin: 0 1em;
}
#overlay {
background: rgba(0, 0, 0, .7);
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
text-align: center;
z-index: 10;
}
#overlay img {
margin-top: 5%;
border: solid 5px white;
border-radius: 5px;
}
//Dont mind these, the silly values are just for testing purposes
#larrow {
font-size: 500px;
color: red;
z-index: 2000;
}
#rarrow {
font-size: 500px;
color: red;
z-index: 2000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="gallery" id="gallery">
<img src="img\placeholder1.jpg" alt="">
<img src="img\placeholder2.jpg" alt="">
<img src="img\placeholder3.jpg" alt="">
<img src="img\placeholder4.jpg" alt="">
<img src="img\placeholder5.jpg" alt="">
<img src="img\placeholder6.jpg" alt="">
</div>
</body>
You have a few errors in your code. Instead of
larrow = $('<div = id = "larrow"> < </div>'); //LEFT ARROW
rarrow = $('<div = id = "rarrow"> > </div>'); //RIGHT ARROW
You should write it like this. There is no need for the '=' between div and id.
larrow = $('<div id = "larrow"> < </div>'); //LEFT ARROW
rarrow = $('<div id = "rarrow"> > </div>'); //RIGHT ARROW
The same goes for the following tags:
overlay = $('<div id = "overlay"></div>').appendTo('body').hide();
Putting the div tags in the image will also not work. Instead you should put the image and the arrows in a container together like this:
<div id="overlay">
<img src ... </img>
<div id = "larrow"> < </div>
<div id = "rarrow"> > </div>
</div>
Refer to Floating Div Over An Image to see the needed css.

Javascript: How to change the images inside of a div on scroll?

so I am trying to create the effect seen on this website (for the photos on the left side of the column):
https://www.franshalsmuseum.nl/en/
I want to be able to change the image on scroll inside of a div.
And preferably, it won't scroll down past the page until all of the images have been scrolled through!
I'm trying to get the hang of javascript before adding things like jQuery, so can someone help with this using pureJS?`
window.onscroll = function() {
console.log(window.pageYOffset);
var img1 = document.getElementById('img1');
var img2 = document.getElemebtById('img2')
if ( window.pageYOffset > 1000 ) {
img1.classList.add("hidden");
img2.classList.remove("hidden");
} else {
img2.classList.add("hidden");
img1.classList.remove("hidden");
}
}
.rightPhotos {
max-width: 50%;
height: 50%;
overflow: auto;
}
.aPhoto {
max-height: 100%;
}
.hidden {
visibility: hidden;
}
.images {
width: 100%;
height: 100%;
}
<div class="other">
<div class="rightPhotos" onscroll="myFunction()">
<div class="aPhoto">
<img class ="images" id="img1" src="IMAGES/sunglasses.jpeg" alt="Woman with Sunglasses">
</div>
<div class="aPhoto hidden">
<img class="images" src="IMAGES/dancer1.jpg" alt="A Dancer">
</div>
</div>
</div>
`
The page you linked actually looks very nice, so I took a while to make something looking a bit closer to it than what other answers do.
I added a properly working transition, similar to one on franshalsmuseum.nl.
I styled the page to deal relatively well with being resized:
The sizing of panes and images is all ralative,
Scroll steps are relative to page height,
Images are shown using <div> with background-image instead of <img> tag. Depending on the size of the window, they are slightly cropped to adjust to changing aspect ratio of viewport.
I made the number of image sets very simple to change. It could be improved by creating the html elements in Javascript, but that doesn't look necessary. At least, it wouldn't be for the original page.
How it works
HTML
Images are put into special envelop elements (.img-wrapper), that provide proper sizing and positioning position: relative is important there). Each image element gets url (as background image url) and image set number to be used by javascript:
<div class="img visible" data-imageset="1"
style="background-image: url('http://placeimg.com/640/480/people');">
</div>
Class visible is set to show imageset 1 at the beginning.
CSS
The key points are these definitions (and similar for #bottom-image). As the element enveloping the image has overflow: hidden, we can hide the image by moving it outside of visible area. When we set coordinates back to normal, the image will slide back, using the smooth transition.
/* hiding images in #top-image */
#left-pane #top-image .img {
top: 100%;
}
#left-pane #top-image .img.visible {
top: 0;
}
JS
The Javascript code is very minimal, the interaction with DOM is really one line. However, it uses some tricks that may not be obvious, so there is this line with some links to documentation:
document.querySelectorAll('#left-pane .img').forEach((img) => {
    img.classList.toggle('visible', img.dataset.imageset <= currentSet);
}
It just finds all images and adds or removes class visible depending on the data-imageset attribute of the image.
Full snippet with demo
See snippet below. Demo looks much better if you use "Full page" link after running the snippet.
let currentSet = 1;
function updateSelectedImgSet() {
const currentScroll = document.scrollingElement.scrollTop;
const scrollMax = document.scrollingElement.scrollHeight - document.scrollingElement.clientHeight;
const setsCount = 3;
const scrollPerSet = scrollMax / setsCount;
const scrolledSet = Math.floor(currentScroll / scrollPerSet) + 1;
if (scrolledSet == currentSet) {
return;
}
currentSet = scrolledSet;
document.querySelectorAll('#left-pane .img').forEach((img) => {
img.classList.toggle('visible', img.dataset.imageset <= currentSet);
});
}
window.onscroll = updateSelectedImgSet;
window.onresize = updateSelectedImgSet;
/* Left pane, fixed */
#left-pane {
position: fixed;
height: 100%;
width: 40vw;
}
#left-pane .img-wrapper {
position: relative;
height: 50%;
width: 100%;
overflow: hidden;
}
#left-pane .img-wrapper .img {
position: absolute;
width: 100%;
height: 100%;
/* Sizing and cropping of image */
background-position: center;
background-size: cover;
/* Transition - the slow sliding of images */
transition: 0.5s all ease-in-out;
}
/* hiding images in #top-image */
#left-pane #top-image .img {
top: 100%;
}
#left-pane #top-image .img.visible {
top: 0;
}
/* hiding images in #bottom-image */
#left-pane #bottom-image .img {
bottom: 100%;
}
#left-pane #bottom-image .img.visible {
bottom: 0;
}
/* Right pane, scrolling with the page */
#right-pane {
margin-left: 40vw;
}
.scrollable-content {
font-size: 40vw;
writing-mode: vertical-rl;
white-space: nowrap;
}
<div id="left-pane">
<div id="top-image" class="img-wrapper">
<div class="img visible" data-imageset="1"
style="background-image: url('http://placeimg.com/640/480/people');">
</div>
<div class="img" data-imageset="2"
style="background-image: url('http://placeimg.com/640/480/animals');">
</div>
<div class="img" data-imageset="3"
style="background-image: url('http://placeimg.com/640/480/any');">
</div>
</div>
<div id="bottom-image" class="img-wrapper">
<div class="img visible" data-imageset="1"
style="background-image: url('http://placeimg.com/640/480/nature');">
</div>
<div class="img" data-imageset="2"
style="background-image: url('http://placeimg.com/640/480/tech');">
</div>
<div class="img" data-imageset="3"
style="background-image: url('http://placeimg.com/640/480/arch');">
</div>
</div>
</div>
<div id="right-pane">
<div class="scrollable-content">Scrollable content!</div>
</div>
see code bellow:(I set 60 insteed 1000 (in function)for see changes)
I use one image and onscroll change the src of image
window.onscroll = function() {
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2')
if ( window.pageYOffset > 60 ) {
document.getElementById("img1").src = "https://material.angular.io/assets/img/examples/shiba2.jpg";
} else {
document.getElementById("img1").src = "https://material.angular.io/assets/img/examples/shiba1.jpg";
}
}
.rightPhotos
{
max-width: 50%;
height:50%;
overflow: auto;
}
.aPhoto
{
max-height: 100%;
}
.images
{
width: 100%;
height: 500px;
}
<div class="other">
<div class="rightPhotos" onscroll="myFunction()">
<div class="aPhoto">
<img class ="images" id="img1" src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Woman with Sunglasses"/>
</div>
</div>
</div>
You can use the CSS properties to show/ hide the elements; instead of having custom CSS with hidden class.
if ( window.pageYOffset > 1000 ) {
img1.style.visibility = 'hidden';
img2.style.visibility = 'visible';
} else {
img2.style.visibility = 'hidden';
img1.style.visibility = 'visible';
}
The above would hide the element, but the DOM element would still occupy space.
For it now to have space occupied (like to remove it)
if ( window.pageYOffset > 1000 ) {
img1.style.display = 'none';
img2.style.display = 'block';
} else {
img1.style.display = 'block';
img2.style.display = 'none';
}
//window.pageYOffset
var scrollingDiv = document.getElementById('scrollContainer');
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
scrollingDiv.onscroll = function(event) {
if (scrollingDiv.scrollTop < 500) {
img1.src = "https://placeimg.com/250/100/arch";
img2.src = "https://placeimg.com/250/100/animals";
}
if (scrollingDiv.scrollTop > 500) {
img1.src = "https://placeimg.com/250/100/nature";
img2.src = "https://placeimg.com/250/100/people";
}
if (scrollingDiv.scrollTop > 1000) {
img1.src = "https://placeimg.com/250/100/tech";
img2.src = "https://placeimg.com/250/100/any";
}
}
.container{
display: table;
width: 100%;
height: 100%;
}
body{
margin: 0;
}
.container > div {
vertical-align:top;
}
.left, .middle, .right {
display: table-cell;
height: 100vh;
box-sizing: border-box;
}
.left, .right{
width:40%;
background: gray;
}
.middle{
overflow: auto;
position: relative;
}
.in-middle{
background: tomato;
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 0;
}
.in-in-middle{
height: 500px;
background: tomato;
}
.in-in-middle:nth-child(2){
background: pink;
}
.in-in-middle:nth-child(3){
background: skyblue;
}
.left img{
width: 100%;
transition: all 0.5s;
}
<div class="container">
<div class="left">
<img id="img1" src="https://placeimg.com/250/100/arch">
<img id="img2" src="https://placeimg.com/250/100/animals">
</div>
<div class="middle" id="scrollContainer">
<div class="in-middle">
<div class="in-in-middle" id="1"></div>
<div class="in-in-middle" id="2"></div>
<div class="in-in-middle" id="3"></div>
</div>
</div>
</div>

Cycle through jQuery lightbox photos [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm having trouble knowing how to build the functionality to be able to click to scroll through my photos in the lightbox. I'm thinking a solution could be to iterate through each one and go to the next index with each click, but I'm not sure how to do it. I'm new to programming and am trying to build from scratch without a plugin. My code is below, and I've included a link so you can see the project so far.
https://abharms.github.io/Interactive_Photo_Gallery/
HTML
<body>
<div class="form-container">
<form>
<input type="text" name="search" value="Search">
</form>
</div>
<div class="photos-container">
<div class="row">
<div class="col-3 images">
<img src="photos/thumbnails/01.jpg" alt="I love hay bales. Took this snap on a drive through the countryside past some straw fields.">
<img src="photos/thumbnails/02.jpg" alt="The lake was so calm today. We had a great view of the snow on the mountains from here.">
<img src="photos/thumbnails/03.jpg" alt="I hiked to the top of the mountain and got this picture of the canyon and trees below.">
</div>
<div class="col-3 images">
<img src="photos/thumbnails/04.jpg" alt="It was amazing to see an iceberg up close, it was so cold but didn’t snow today.">
<img src="photos/thumbnails/05.jpg" alt="The red cliffs were beautiful. It was really hot in the desert but we did a lot of walking through the canyons.">
<img src="photos/thumbnails/06.jpg" alt="Fall is coming, I love when the leaves on the trees start to change color.">
</div>
<div class="col-3 images">
<img src="photos/thumbnails/07.jpg" alt="I drove past this plantation yesterday, everything is so green!">
<img src="photos/thumbnails/08.jpg" alt="My summer vacation to the Oregon Coast. I love the sandy dunes!">
<img src="photos/thumbnails/09.jpg" alt="We enjoyed a quiet stroll down this countryside lane. ">
</div>
<div class="col-3 images">
<img src="photos/thumbnails/10.jpg" alt="Sunset at the coast! The sky turned a lovely shade of orange.">
<img src="photos/thumbnails/11.jpg" alt="I did a tour of a cave today and the view of the landscape below was breathtaking.">
<img src="photos/thumbnails/12.jpg" alt="I walked through this meadow of bluebells and got a good view of the snow on the mountain before the fog came in.">
</div>
</div>
</div>
<script type="text/javascript" src="js/gallery.js"></script>
</body>
CSS
form {
text-align: center;
margin-top: 30px;
}
input[type=text] {
height: 32px;
width: 58%;
border: 2px solid lightgray;
border-radius: 4px;
}
input[type=text]:focus {
outline: none;
}
img {
display: block;
margin: 0 auto 30px auto;
}
.col-3 {
text-align: center;
}
.col-3:first-child {
margin-top: 30px;
}
#overlay {
background: rgba(0,0,0,0.7);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: none;
}
#overlay img {
width: 50%;
margin-top: 10%;
}
.imageContainer {
max-height: 100%
width: 600px;
margin: 0 auto;
position: relative;
}
#caption {
color: white;
margin: 0 auto;
text-align: center;
max-width: 600px;
}
a.leftArrow,
a.rightArrow {
padding: 15px;
}
.leftArrow,
.rightArrow {
color: white;
font-size: 56px;
position: absolute;
top: 22%;
}
.leftArrow {
left: 12%;
}
.rightArrow {
right: 12%;
}
#media only screen and (min-width: 820px ) {
.row {
margin-top: 40px;
}
.photos-container {
width: 100%;
margin: 0 auto;
}
.col-3 {
width: 25%;
float: left;
}
.col-3:first-child {
margin-top: 0;
}
input[type=text] {
width: 460px;
}
.leftArrow,
.rightArrow {
top: 35%;
}
.leftArrow {
left: 18%;
}
.rightArrow {
right: 18%;
}
#media only screen and (min-width: 960px) {
.photos-container {
width: 980px;
}
.leftArrow,
.rightArrow {
top: 40%;
}
.leftArrow {
left: 20%;
}
.rightArrow {
right: 20%;
}
}
jQuery
var $overlay = $('<div id="overlay"></div>');
var $imageContainer = $('<div class="imageContainer"></div>')
var $caption = $('<p id="caption"></p>');
var $image = $("<img>");
var $leftArrow = $('<a href="#" class="leftArrow" onclick="prev(); return false;"><i class="fa fa-angle-left" aria-hidden="true"></i>');
var $rightArrow = $('<a href="#" class="rightArrow" onclick="next(); return false;"><i class="fa fa-angle-right" aria-hidden="true"></i>');
//Add image container to overlay
$overlay.append($imageContainer);
//Add image to overlay
$imageContainer.append($image);
//Add navigation arrows to overlay
$imageContainer.append($leftArrow);
$imageContainer.append($rightArrow);
//Add caption to image
$overlay.append($caption);
//add overlay
$("body").append($overlay);
//capture click event on a link to an image
$(".images a").click(function(event){
event.preventDefault();
var imageLocation = $(this).attr("href");
$image.attr("src", imageLocation);
$overlay.show();
//get child's alt attribute and set caption
var $captionText = $(this).children("img").attr("alt");
$caption.text($captionText);
});
$overlay.click(function(){
$overlay.hide();
})
$(".leftArrow").bind("click", function(e){
e.stopPropagation();
});
$(".rightArrow").bind("click", function(e){
e.stopPropagation();
});
function next() {
$($image).each(function(){
$(this).hide();
$($caption).hide();
$($image).next();
})
}
I updated your script with a working version. Let me know if it does what you want.
I refactored your code a bit by removing next() and prev() onclick handlers. I also move all the code to render image with alt text in a helper function. The cycling logic is exactly like what you expected.
Cheers
var $overlay = $('<div id="overlay"></div>');
var $imageContainer = $('<div class="imageContainer"></div>')
var $caption = $('<p id="caption"></p>');
var $image = $("<img>");
var $leftArrow = $('<a href="#" class="leftArrow"><i class="fa fa-angle-left" aria-hidden="true"></i>');
var $rightArrow = $('<a href="#" class="rightArrow"><i class="fa fa-angle-right" aria-hidden="true"></i>');
var $links = $(".images a");
var current_index;
//Add image container to overlay
$overlay.append($imageContainer);
//Add image to overlay
$imageContainer.append($image);
//Add navigation arrows to overlay
$imageContainer.append($leftArrow);
$imageContainer.append($rightArrow);
//Add caption to image
$overlay.append($caption);
//add overlay
$("body").append($overlay);
//capture click event on a link to an image
$(".images a").click(function(event){
event.preventDefault();
current_index = $links.index($(this));
renderImage($(this));
$overlay.show();
});
$overlay.click(function(){
$overlay.hide();
})
$(".leftArrow").bind("click", function(e){
e.stopPropagation();
var image = $(".images a").eq(--current_index);
renderImage(image);
});
$(".rightArrow").bind("click", function(e){
e.stopPropagation();
var image = $(".images a").eq(++current_index);
renderImage(image);
});
function renderImage($link) {
var imageLocation = $link.attr("href");
var $captionText = $link.children("img").attr("alt");
$caption.text($captionText);
$image.attr("src", imageLocation);
// Hide next arrow if end of images array
if (current_index >= $links.length - 1) {
$rightArrow.hide();
} else {
$rightArrow.show();
}
// Hide prev arrow if beginning of images array
if (current_index <= 0) {
$leftArrow.hide();
} else {
$leftArrow.show();
}
}

Loop Carousel horizontaly javascript/jquery

I was wondering if somebody could help me write a loop for this carousel? at the moment the carousel just scrolls to the right every 3 seconds then scrolls back to the left afterwards and resets itself, I would just like it to contiuously loop infinitly so it looks cleaner, could somebody point me in the right direction or help me? i know its simpler but i'm not much of a js developer! (this is for google sites html box otherwise i would have used a jquery plugin)
<style>
.carousel {
width: 1080px;
height: 220px;
position: relative;
overflow: hidden;
background-color:white;
margin-bottom: 20px;
margin-top: 20px;
margin-left: 70px;
}
.items {
width: 1080px;
position: absolute;
}
.items > div {
font-size: 20px;
display: table-cell;
vertical-align: middle;
text-align: center;
}
.items > div > img {
padding: 10px;
}
.nav {
position: absolute;
bottom: 5px;
right: 15px;
}
.button {
cursor: pointer;
font-weight: bold;
color: #fff;
}
</style>
<div class="carousel" style="display:none;">
<div class="items">
<div>
<img src="http://i59.tinypic.com/etisye.png" border="0" alt="Alkamai Logo">
</div>
<div>
<img src="http://i59.tinypic.com/ouukxu.png" border="0" alt="AWS Logo">
</div>
<div>
<img src="http://i61.tinypic.com/16k3t43.png" border="0" alt="cover-it-live">
</div>
<div>
<img src="http://i60.tinypic.com/23wljxh.png" border="0" alt="escenic">
</div>
<div>
<img src="http://i58.tinypic.com/sbiqu1.png" border="0" alt="Livefire">
</div>
<div>
<img src="http://i58.tinypic.com/do9wep.jpg" border="0" alt="ooyala">
</div>
<div>
<img src="http://i61.tinypic.com/24werue.png" border="0" alt="varnish">
</div>
<div>
<img src="http://i60.tinypic.com/2ij14rd.png" border="0" alt="wordpress">
</div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"> </script>
<script>
var current_slide = 0; // zero-based
var slide_count = 4;
var slide_size = 1080;
var Direction = {
LEFT: -1,
RIGHT: 1
};
/**
* Moves to the next slide using the direction (dx) parameter.
*/
var nextSlide = function(dx) {
current_slide = (current_slide + slide_count + dx) % slide_count;
// Calculate the new value for css 'left' property and animate.
var left_offset = '-' + (current_slide * slide_size) + 'px';
$('.items').animate({'left': left_offset}, 1080);
};
$('.carousel').show();
setInterval(function(){
nextSlide(Direction.RIGHT);
}, 3000);
</script>
A slight modification to your current script can make it move forward continuously.
The changes are:
current_slide is always 1 (so as to always move forward only)
When we move .items X pixels to the left, we move the corresponding number of items to the end (the number that fits inside X pixels in width)
Updated Demo: http://jsfiddle.net/techfoobar/dWy9R/4/
Code:
var parent = $('.items');
var nextSlide = function (dx) {
// NOTE: always move forward only
current_slide = 1; //(current_slide + slide_count + dx) % slide_count;
// Calculate the new value for css 'left' property and animate.
var ileft_offset = current_slide * slide_size,
left_offset = '-' + ileft_offset + 'px',
iWidth = 0;
parent.animate({
'left': left_offset
}, 'slow', function() { // called when animation is done
iWidth = parent.find('> div:first').width();
while(ileft_offset > iWidth) {
parent.find('> div:first').appendTo(parent);
ileft_offset -= iWidth;
parent.css('left', '-' + ileft_offset + 'px');
}
});
};
A modified version that doesn't pause in between. Just goes on.
Demo: http://jsfiddle.net/techfoobar/dWy9R/5/
var nextSlide = function () {
parent.animate({
'left': '-' + slide_size + 'px'
}, 4000, 'linear', function() { // called when animation is done
var ileft_offset = slide_size,
iWidth = parent.find('> div:first').width();
while(ileft_offset > iWidth) {
parent.find('> div:first').appendTo(parent);
ileft_offset -= iWidth;
parent.css('left', '-' + ileft_offset + 'px');
iWidth = parent.find('> div:first').width();
}
nextSlide();
});
};
nextSlide(); // start it off!

Categories

Resources