Implementing multiple carousels on a single page - javascript

So, I'm building myself a webpage which will need to contain multiple carousels. I've been successful in creating the first carousel, but haven't been able to crack creating any others.
I've been following Christian Heilmann's Javascript carousel guide and all was going well until I tried to place 2 carousels on the same page.
As the js is affecting classes I assumed that the existing js would affect the copies too. Here's how the working carousel looks and here is how the broken carousel looks.
Any advice about the best way to go about this would be great, I'd love to keep it in vanilla js if possible. Thanks for your help!
And here's the updated js:
carousel = function(id) {
var box = document.querySelector(id + ' .project-pictures');
var next = box.querySelector(id + ' .next');
var prev = box.querySelector(id + ' .prev');
var items = box.querySelectorAll(id + ' .content li');
var counter = 0;
var amount = items.length;
var current = items[0];
box.classList.add('active');
function navigate(direction) {
current.classList.remove('current');
counter = counter + direction;
if (direction === -1 &&
counter < 0) {
counter = amount - 1;
}
if (direction === 1 &&
!items[counter]) {
counter = 0;
}
current = items[counter];
current.classList.add('current');
}
next.addEventListener('click', function(ev) {
navigate(1);
});
prev.addEventListener('click', function(ev) {
navigate(-1);
});
navigate(0);
}();
carouselA = carousel('#carousel-a');
carouselB = carousel('#carousel-b');
note: The div being affected is .project-pictures.
Thanks for your response! Im still not getting the carousel to work - it appears the same in the not working screenshot above, I feel I'm missing something pretty basic here, here's the html for reference and I've updated the js above to reflect your advice:
<div id="carousel-a">
<div class="project-pictures">
<ol class="content">
<li><img src="images/portfolio_img/design_museum/cropped/1.png">
</li>
</ol>
<div class="buttons">
<button class="prev">
</button>
<button class="next">
<span class="offscreen">Next</span> ▶
</button>
</div>
</div></div>

You are on the right track saying that the javascript affecting css class which applied to both carousels.
What you need to do is to differentiate between the two carousels. One way to do it is to create a unique id for each carousel.
For example
carousel = function(id) {
var box = document.querySelector(id + ' .project-pictures');
var next = box.querySelector(id + ' .next');
var prev = box.querySelector(id + ' .prev');
var items = box.querySelectorAll(id + ' .content li');
// ...
};
carouselA = carousel('#carousel-a');
carouselB = carousel('#carousel-b');
And in your HTML code, insert the appropriate ID for the two carousel elements.

Related

Get .textContent clonned on some div. Show with mouseOver/out function

Good morning community, I would like to know if someone can help me with this problem.
My idea is the following: Each image in the homepage section (8 images), has associated:
<div id="project__caption" class="relative -z-10 hidden">
<p>Your description image here</p>
</div>
Which I pass to clone and store into a new div created as #cursor-outer.
I have done this code to achieve the above explained:
cursorText: function () {
if (!isMobile() || !isTouchDevice()) {
const projectCap = document.querySelectorAll("#project__caption");
const cursorText = document.getElementById("cursor-outer");
for (let i = 0; i < projectCap.length; i++) {
const element = projectCap[i];
const clonned = cursorText.appendChild(element.cloneNode(true));
clonned.classList.add("is-inactive");
}
}
},
Every time I use the mouseOver / mouseOut function I need to get this new and display it only above this image, and then hide it when i move cursor out image.
So i need now to make 2 functions like : mouseOver / mouseOut,
Can anyone help me to get this code transform to vanilla js (actually working with jquery)
function mouseOver() {
var hoveredProject = $(this).find(".project__caption").text();
var hoveredProjectActive = $(
"#cursor-outer .project__caption:contains('" + hoveredProject + "')"
);
$(hoveredProjectActive).filter(function () {
if ($(this).text() === hoveredProject) {
$(this).removeClass("is-inactive").addClass("is-active");
}
});
function mouseOut() {
var hoveredProject = $(this).find(".project__caption").text();
var hoveredProjectActive = $(
".project__caption:contains('" + hoveredProject + "')"
);
hoveredProjectActive.removeClass("is-active").addClass("is-inactive");
}
Thanks to anyone in advance, appreciate any help :)

Trouble Initializing a dynamically built materialize carousel

I am attempting to dynamically build a Materialize carousel (NOT a slider) from Flickr pictures, but I haven't been able to get the pictures to change. The picture that shows is always the last picture taken from Flickr, so I feel like something is scrolling, but it just isn't continuing to rotate the way a carousel should.
I've looked on SO and Google for answers, but 99% of the info is Bootstrap specific. I've added an active class to the first item and tried initializing the carousel both from inside the html as well as from the javascript, but neither seemed to help. Here is the html code:
<div class="carousel initialized" id="flickrPic"></div>
and the JS:
$.ajax({
type: "GET",
url: flickrApiUrl + $.param(flickrApiParams),
success: function(response) {
var flickrPetPics = response.photos.photo
for(i=0; i<flickrPetPics.length; i++) {
var newSlide = makeFlickrCarousel(flickrPetPics[i]);
$('.carousel-item').first().addClass('active');
$('#flickrPic').carousel();
$("#flickrPic").append(newSlide);
}
}
});
function makeFlickrCarousel(photoInfo) {
var flickPicUrl = "https://farm" + photoInfo.farm +".staticflickr.com/";
flickPicUrl += photoInfo.server + "/" + photoInfo.id + "_" + photoInfo.secret;
flickPicUrl += "_q.jpg";
//Build carousel pieces
var newItem = $("<a>").addClass("carousel-item");
var flickrImg = $("<img>").attr("src", flickPicUrl);
newItem.append(flickrImg);
return newItem;
}
Thanks for the help!
You should remove the .initialized class from the carousel div container and move the $('#flickrPic').carousel() initialization after the for loop like this:
...
for(i=0; i<flickrPetPics.length; i++) {
var newSlide = makeFlickrCarousel(flickrPetPics[i]);
$('.carousel-item').first().addClass('active');
$("#flickrPic").append(newSlide);
}
$('#flickrPic').carousel(); // <-- Initialize the carousel after the loop has created the carousel markup
...

Fadeout Div Content - Empty Div Content - Fadein New Content

I am using onClick functionality for my buttons. My button code looks like this:
<a onClick="fadeNext('#myDIV1',500);">Button 1</a>
<a onClick="fadeNext('#myDIV2',500);">Button 2</a>
My JS Function looks like this:
function fadeNext(selectedId, speed) {
var containerID = '#imageSwap';
var vis = ($(containerID + ' div:visible').length > 0) ? $(containerID + ' div:visible').eq(0) : $(containerID + ' div').eq(0);
var next = $(selectedId);
vis.fadeOut(speed);
next.fadeIn(speed);
}
This fades the content correctly and works great, but Video content (Vimeo) still plays when its not visible. Tried this JS, but still no luck:
function fadeNext(selectedId, speed) {
var containerID = '#imageSwap';
var vis = ($(containerID + ' div:visible').length > 0) ? $(containerID + ' div:visible').eq(0) : $(containerID + ' div').eq(0);
var next = $(selectedId);
vis.fadeOut(speed, function() {
$(this).empty().show();
});
next.fadeIn(speed);
}
With this JS, the content no longer fades out or empties.
I'm a JS rookie and having trouble getting the empty() code to work. The main reason for this is that my DIV will be containing videos (Vimeo). When the user clicks to change content, I'd like for the videos to be unloaded, so the video/sound no longer plays.
Any help / advice would be appreciated!
Checkout my fork of your fiddle: http://jsfiddle.net/tutanramen/umJQ9/16/
I added a link to an external resource: https://raw.github.com/vimeo/player-api/master/javascript/froogaloop.js
I then gave each iframe an id (v1 and v2 but they are not used in this fiddle) and a class of player.
And then added this to fadeNext:
$(".player").each(function() {
$f($(this)[0]).api("pause");
});
Now when you click to select the other video it actually pauses all the videos.

Add Next and Prev Buttons To Rotating Banner

I'm not knowledgeable in JS and Jquery so I'm really hoping someone here could help me out.
I want my banner to change image on page load or refresh and I found this code:
<script type="text/javascript">
window.onload = function () {
var random = document.getElementById('random');
var pictures = new Array('images/icn_slide-1.jpg','images/icn_slide-2.jpg','images/icn_slide-1.jpg','images/icn_slide-2.jpg');
var numPics = pictures.length;
if (document.images) {
var chosenPic = Math.floor((Math.random() * numPics));
random.style.background = 'url(' + pictures[chosenPic] + ')';
}
}
The script above works pretty well(background image changes every refresh) but now I want to add a previous and next button(actually I already did) so that when viewers click on next/previous it would display another image. Is there a simple way to do this? How do I make my next and previous button work? Any help would be greatly appreciated. Thanks!
This is the only content inside the of my html:
<div id="random" style="width: 1399px; height:515px; margin:auto;">
<div id="slide_control" class="clearfix">
<span id="prev"><img alt="" title="" src="images/icn_nav-arrow2.png" /></span>
<span id="next"><img alt="" title="" src="images/icn_nav-arrow.png" /></span>
</div>
</div>
It's the #random div that changes background image on refresh as of now and I want it just like that. I added the "slide_control" which contained the "prev" and "next" button and what I want them to do is to also change the background-image of #random when they're clicked.
Most JS/JQquery slider and plugins comes with buttons and controllers but they auto-play images and if I disable the autoplay, they don't change banner/background on refresh.
I only want the images/background to randomly change on refresh or change when prev/next buttons are clicked but I don't know how to achieve this.
Here's a basic example of what you are asking for:
<script type="text/javascript">
function rotateImage(idx) {
var random = document.getElementById('random');
if (document.images) {
random.style.background = 'url(' + pictures[idx] + ')';
selectedImage = idx;
}
}
function getNext() {
var nextImage = selectedImage + 1;
if (selectedImage >= numPics) {
nextImage = 0;
}
rotateImage(nextImage);
}
function getPrev() {
var prevImage = selectedImage - 1;
if (selectedImage < 0) {
selectedImage = numPics -1;
}
rotateImage(prevImage);
}
var pictures = new Array('images/icn_slide-1.jpg','images/icn_slide-2.jpg','images/icn_slide-1.jpg','images/icn_slide-2.jpg');
var numPics = pictures.length;
var selectedImage = null;
window.onload = function () {
var chosenPic = Math.floor((Math.random() * numPics));
rotateImage(chosenPic);
document.getElementById('next').onclick = getNext;
document.getElementById('prev').onclick = getPrev;
}
</script>

Javascript jquery fade-in/fadeout loop, how to use timer?

New to javascript and such, trying to create a loop for fading logos using jquery.
I've got it cycling through them just fine. But i tried to make the loop continuous; so that when it reached the last logo it went back to the beginning, by resetting my for-counter to 0 every time it reached the last logo. This resulted in an infinite loop i think that crashed my browser. So i did a quick google and discovered the window.setInterval(...) timer function.
My problem is, now that firing the looping code relies on timing, i can't figure out how to calculate the interval time. For reference here's the code that fades the logos in and out (before trying to loop it):
$(document).ready(function (){
var fadeDuration = 1000;
var timeBetweenFade = 2000;
var totalTimePerChange = fadeDuration + timeBetweenFade;
var totalLogos = $('.logo').length;
var currentLogo;
var i;
for(i = 0; i < totalLogos; i++)
{
currentLogo = "#img" + i;
if(i == 0){
$(currentLogo).fadeIn(fadeDuration).delay(timeBetweenFade).fadeOut(fadeDuration);
}
else{ //general case
$(currentLogo).delay(totalTimePerChange * i).fadeIn(fadeDuration).delay(timeBetweenFade).fadeOut(fadeDuration);
}
}
});
I tried to get the time a complete loop took in a couple of ways:
$(document).ready(function (){
//..declarations..
window.setInterval( function() {
//..FOR LOOP HERE..
}, i*(fadeDuration + timeBetweenFade + fadeDuration));
});
//I also tried..
$(document).ready(function (){
//..declarations..
var timeTakenToLoop;
var startLoopTime;
window.setInterval( function() {
startLoopTime = new Date().getTime();
//...FOR LOOP HERE..
timeTakenToLoop = new Date().getTime() - startLoopTime;
}, timeTakenToLoop);
});
But in both cases I get logos starting to overlap as the function calls timing is wrong. Could someone with a bit more experience suggest what the best approach would be?
Oh and just in case anyone needs it to understand the javascript, here's the html to match..
<div id="img0" class="logo">
<img src="{% static "CSS/Images/phone_icon.gif" %}"/>
</div>
<div id="img1" class="logo">
<img src="{% static "CSS/Images/email_icon.gif" %}"/>
</div>
<div id="img2" class="logo">I can fade too</div>
Simple jQuery approach, no setTimeout and no setInterval.
var loop = function(idx, totalLogos) {
var currentLogo = "#img" + idx;
$(currentLogo)
.delay(currentLogo)
.fadeIn(fadeDuration)
.delay(currentLogo)
.fadeOut(fadeDuration, function(){
loop( (idx + 1) % totalLogos, totalLogos);
});
}
loop(0, $('.logo').length);​
See it here.

Categories

Resources