I am trying to build pure javascript slider following the tutorial here with minor customisation.
The problem I had was: if I add more than 7 slides, 7th and onwards won't display correctly. Only dark grey screen is shown instead of the picture I selected.
I tried debugging for hours and still can't figure it out. Hopefully, some experts can shine some light on this problem.
JSFIddle by the author of the code: https://jsfiddle.net/solodev/yokph2nh/
Snippet of code:
function changeSlides(instant) {
if (!instant) {
animating = true;
manageControls();
$slider.addClass("animating");
$('#slide-content').addClass("animating");
$slider.css("top");
$(".slide").removeClass("active");
$(".slide-" + curSlide).addClass("active");
setTimeout(function() {
$slider.removeClass("animating");
$('#slide-content').removeClass("animating");
// Update content
let currentContent = $(".slide-" + curSlide + " .slide__content").html();
$('#slide-content').html(currentContent);
animating = false;
}, animTime);
}
window.clearTimeout(autoSlideTimeout);
$(".slider-pagi__elem").removeClass("active");
$(".slider-pagi__elem-" + curSlide).addClass("active");
$(".slider-tab__elem").removeClass("active");
$(".slider-tab__elem-" + curSlide).addClass("active");
$slider.css("transform", "translate3d(" + -curSlide * 100 + "%,0,0)");
$slideBGs.css("transform", "translate3d(" + curSlide * 50 + "%,0,0)");
diff = 0;
autoSlide();
}
Here is an altered fiddle of the one you posted, with more images.
https://jsfiddle.net/5xhtq4hL/
Seems to work ok.
Maybe you didn't update the css values for left on the
.slide:nthchild() selector?
This code doesn't seem very DRY though. So much copy pasting.
Related
I'm new to this community and first of all, I take this opportunity to thank all of you for the wonderful work you do every day.
I'm trying to create an infinite manual carousel, in the Netflix style, this is the link to the codepen of everything I have done so far:
https://codepen.io/A12584r/pen/OjvWYp?fref=gc
Here is the relevant javascript:
let prendiContenitoreGalleria = document.querySelector('.contenitore-galleria'),
prendiArticle = Array.prototype.slice.apply(document.querySelectorAll('.contenitore-galleria__article')),
contaArticle = prendiArticle.length,
prendiImmagini = Array.prototype.slice.apply(document.querySelectorAll('.contenitori__img')),
prendiFrecciaSinistra = document.querySelector('.freccia-sinistra'),
prendiFrecciaDestra = document.querySelector('.freccia-destra');
prendiContenitoreGalleria.style.width = 100 * contaArticle + '%';
for (let numeroImmagini = 0; numeroImmagini < prendiImmagini.length; numeroImmagini++) {
prendiImmagini[numeroImmagini].style.width = 100 / contaArticle + '%';
}
prendiContenitoreGalleria.insertBefore(prendiArticle[contaArticle - 1], prendiArticle[0]);
prendiContenitoreGalleria.style.marginLeft = '-' + 100 + '%';
function andareADestra () {
prendiContenitoreGalleria.style.marginLeft = '-' + 200 + '%';
prendiContenitoreGalleria.style.transitionDuration = '.7s';
prendiContenitoreGalleria.addEventListener('transitionend', function(e) {
prendiContenitoreGalleria.appendChild(prendiArticle[0]);
prendiContenitoreGalleria.style.marginLeft = '-' + 100 + '%';
}, false);
}
function andareASinistra () {
prendiContenitoreGalleria.style.marginLeft = 0;
prendiContenitoreGalleria.style.transitionDuration = '.7s';
prendiContenitoreGalleria.addEventListener('transitionend', function(e) {
prendiContenitoreGalleria.insertBefore(prendiArticle[contaArticle - 1], prendiArticle[0]);
prendiContenitoreGalleria.style.marginLeft = '-' + 100 + '%';
}, false);
}
prendiFrecciaSinistra.addEventListener('click', function () {
andareASinistra();
});
prendiFrecciaDestra.addEventListener('click', function () {
andareADestra();
});
I have tried to use the vanilla Javascript transitionend events and what I want to achieve is that when clicking on the right arrow of the carousel the first article is put in place of the third and vice versa, when clicking on the left arrow of the carousel the last article is put in place of the first one.
For this purpose I use marginLeft to move between the articles in my carousel which are 3 and the divs that contains them (these are 3 too) has a width of 300% set via JavaScript.
My problem is that when I click on the carousel arrows, the transition is done but it does a strange effect coming back to its original location immediately.
Any one of you could help me to figure out where I'm wrong and how can I fix it?
In your two functions to move left and right, andareASinistra and andareADestra you are adding an event listener for the transitionend event.
The handler for this is removing the margin-left offset by resetting it to -100% after each move left or right.
You can confirm this is the problem by editing the inline style of the id="contenitore-galleria" element, if you set style="margin-left: 0" then the carousel is moved, then returned to the -100% position.
So the reason it is happening is because that is what you are explicitly telling it to! Delete the lines from both andareASinistra and andareADestra
rendiContenitoreGalleria.style.marginLeft = '-' + 100 + '%';
I have a problem with javascript that I don't know how to solve. First of all I am a total newb in this. I found a code that loads random images in div element and tweaked it a little bit (original code loaded images in order - I inserted a type of algorithm for randomness (pretty clumsy but it somehow works and rarely repeats the same image one after another).
Now the code works just fine, but when I scroll for e.g. to the bottom of my page the instant moment that script loads a new image into div element browser jumps to the top of the page.
How to stop this from happening? Please help me with a 'child language'(because as I told, I'm a total newb in js).
Thank you all in advance for your time!
<script src="js_vrt/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function() {
var images = ['img_vrt/pozadine/1p.jpg', 'img_vrt/pozadine/2p.jpg', 'img_vrt/pozadine/3p.jpg', 'img_vrt/pozadine/4p.jpg'];
var image = $('#pozad');
var i = Math.floor((Math.random() * images.length) + 0);
var ist;
//Initial Background image setup
image.css('background-image', 'url(' + images[i++] + ')');
//Change image at regular intervals
setInterval(function() {
image.fadeOut(1500, function() {
image.css('background-image', 'url(' + images[i++] + ')');
image.fadeIn(1500);
});
if (i == images.length)
i = Math.floor((Math.random() * (images.length - 1)) + 0);
else i = Math.floor((Math.random() * (images.length)) + 0);
}, 5000);
});
</script>
Solution I figured out:
Problem is not in the js code. It is in HTML structure.
If someone has the same problem where screen jumps to top of the page while loading images do the following:
The div element that has the changing background MUST be contained in another wrapping div (which has the same height).
<div id="wrap_element">
<div id="div_that_loads_the_images"></div>
</div>
I'm currently using ScrollReveal.js to make a bunch of tiny pixelated boxes do random things when scrolled upon, with the following code:
var index=0;
$(document).ready(function(){
jQuery('.pixel-box').each(function() { //each tiny box has class pixel-box
var directions =[ 'left', 'right', 'top', 'bottom']
index += 1
var currentElement = $(this);
var randEffect = getRandomInt(0,1);
var randTime = getRandomArbitrary(1, 3.5);
var randDirection = getRandomInt(0,3);
if(randEffect == 0){
var rand = getRandomInt(-360, 360);
$(this).attr('data-sr', 'wait .5s, enter ' + directions[randDirection] + ', flip ' + rand + 'deg, over '+ randTime +'s');
}
else if(randEffect == 1){
// move 24px
var rand = getRandomInt(10, 120);
$(this).attr('data-sr', 'wait .5s, enter ' + directions[randDirection] +', move '+ rand + 'px, over '+ randTime +'s');
}
if(index == 81){
window.sr = new scrollReveal();
}
});
});
It's working perfectly on Chrome, but on Safari, the behavior is extremely clunky and not what I want. Would you or anyone else have any insights as to why this is happening?
To illustrate, here's what it looks like on Chrome:
https://gyazo.com/4f51ff8279cf5a76ad3ab38a680ae2af
Here's what it looks like on Safari:
https://gyazo.com/8c30e489a2470ac415da3dde1d95d4ef
For reference, one of these boxes is being rendered using the HTML code:
<rect class="pixel-box" id="Rectangle-167-Copy-7" fill="#FDD93D" filter="url(#filter-35)" x="823.65422" y="188.994877" width="16.675" height="19.0983607"></rect>
I suspect that the problem may be due to inconsistencies with CSS transformations and SVG elements like <rect> and <path> across different browsers, but I haven't been coming up with much.
Looks like a browser issue with Safari animating opacity and transforms at the same time.
...we came across a particularly frustrating bug in Safari involving
animation of SVG elements using CSS3 transforms and opacity
simultaneously.
Safari will not animate both attributes at the same time, instead
choosing to animate the opacity with the correct timings and when that
animation is complete the transform jumps to its correct position, or
the translation is just ignored completely.
Reference: https://www.theparticlelab.com/safari-svg-animation-bug/
Looks like others have had similar problems in the past, but the browser bug appears fixed.
I am trying to write a javascript app which sorts dynamically created divs on a webpage, everything works and it sorts it all as it should, however I want it to animate the divs as they change position due to being sorted, I have code to do this but it moves way too fast, the only way I can see the divs move is if I put an alert in the animation code which looks like this :
function moveAnimation(to,from){
mover1.style.backgroundColor = "rgba(255,100,175,0.8)";
mover2.style.backgroundColor = "rgba(255,100,175,0.8)";
mover1.style.top = parseInt(mover1.style.top) + 10 + 'px';
mover2.style.top = parseInt(mover2.style.top) - 10 + 'px';
from = parseInt(mover1.style.top);
if(from != to && from < to)
{
//alert("TO : " + to + " From : " + from); //This makes it pause so that I can see the divs move
animate = setTimeout(moveAnimation(to,from),1000)
}
else
{
//alert("RET");
return;
}
}
And i call it simply like this :
mover1 = document.getElementById(moving1.id);
mover2 = document.getElementById(moving2.id);
var from = parseInt(in1.style.top);
var to = parseInt(in2.style.top);
moveAnimation(to,from);
When the alert is in place I can see them move frame by frame and it's doing exactly what I want, however it all happens in the blink of an eye with the divs suddenly being sorted, I would like to see them slowly move, any ideas on why my code isn't doing that?
after exaclty six attempts begging the original auhtor of an image popup javascript code to make his script compatible with the newer JQuery libraries, all six in vain, I decided its time for me to fix it without him the seventh attempt, and salvage this otherwise perfectly working (after numerous customisations by me) image popup script.
Problem: works when JQuery 1.3.2 ~ 1.4.2 is loaded, but NOT when JQuery 1.4.3 ~ 1.5.1 is loaded. On new builds, images don't enlarge after click on the thumbnails, whereas on the old builds, the do!
Any suggesion/help is kindly welcome and appreciated by me highly. Thanks!
The problem lies somehwere here:
//display content
var displayContent = function(img) {
if (visible) {
var newImg = jQuery.extend(true, {}, img);
resizeImg(newImg);
var imgWidth = newImg.width;
var imgHeight = newImg.height;
var outerWidth = imgWidth + hBound;
var outerHeight = imgHeight + vBound;
$lightbox.stop(true).animate({width:imgWidth, height:(imgHeight + cpHeight),
left: Math.round(($(window).width() - outerWidth)/2),
top:Math.round(($(window).height() - outerHeight)/2)},
tranSpeed,
function() {
enableCtrl();
$innerBox.height(imgHeight);
$info.html(langArrows + " " + langImage + " " + (currIndex+1) + "/" + numItems);
$cpanel.css({top:imgHeight, display:"block"});
$mainImg.css({width:imgWidth, height:imgHeight})
.attr("src", newImg.src).animate({opacity:1}, tranSpeed, startTimer);
showDesc();
}
);
}
}
On line 336 add .show() to the end of the chain. While LekisS was on to the right answer, if you add it there, its not properly hidden so the next time you click the image you will see the image display as its thumbnail size for a brief second.