Page FPS Drop and Functions - javascript

I wrote some JS code that rendering DOM (It is my custom carousel). My carousel has 2 buttons and they have some functions. When I trigger these functions in repeatedly, the DOM has difficulty in rendering. So the FPS of the page dropping slowly -half fps per second but very fast at beginning: 2-3 fps per second-.
You can see at right top (writes ortalama 2.68 fps):
https://ibb.co/8YvyJwn
And my performace json file:
https://gofile.io/?c=LIHiLh
const hizmetler = [{/* some datas */}];
var index = 0;
var slaytCount = hizmetler.length;
showSlide(index);
function showSlide(i) {
index = i;
if (i < 0) {
index = slaytCount - 1;
}
if (i >= slaytCount) {
index = 0;
}
const baslik = document.querySelector(".carousel-baslik");
const metin = document.querySelector(".carousel-metin");
const image = document.querySelector(".carousel-lg-image");
const iconGround = document.querySelector(".icon-ground");
const counter = document.querySelector(".counter");
let iconImg = `<img src="${hizmetler[index].icon}" class="animated fadeInDown fast" alt="">`;
let lgImage = `<img src="${hizmetler[index].lgImage}" class="animated fadeIn fast" alt="">`;
baslik.innerHTML = hizmetler[index].baslik;
metin.innerHTML = hizmetler[index].metin;
image.innerHTML = lgImage;
counter.innerText = hizmetler[index].count;
iconGround.innerHTML = iconImg;
document.querySelector('.controller-left').addEventListener('click', function (e) {
index--;
showSlide(index);
iconImg = `<img src="${hizmetler[index].icon}" class="animated fadeInLeft faster" alt="">`;
document.querySelector(".icon-ground").innerHTML = iconImg;
});
document.querySelector('.controller-right').addEventListener('click', function (e) {
index++;
showSlide(index);
iconImg = `<img src="${hizmetler[index].icon}" class="animated fadeInRight faster" alt="">`;
document.querySelector(".icon-ground").innerHTML = iconImg;
});
}

I found to solution. When you run the click functions inside the showSlide function, something like an overload occurs and the page's FPS crashes. When I run the click functions independently, it does not cause any crash. \m/_

Related

How to make text and image change in JavaScript within a Slider?

I've have this code here: https://codepen.io/double_milkshake/pen/VwZJjgq
const nextBtn = document.querySelector('.nextBtn');
const prevBtn = document.querySelector('.prevBtn');
const container = document.querySelector('.images');
const textElement = document.querySelector(".text");
let counter = 0;
nextBtn.addEventListener('click',nextSlide);
prevBtn.addEventListener('click',prevSlide);
function nextSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:500, fill: 'forwards'});
if(counter === 4) {
counter = -1;
}
counter++;
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
function prevSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:1000, fill: 'forwards'});
if(counter === 0) {
counter = 5;
}
counter--;
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
It is a simple image slider. You can't see the images, because the code is made for images that are on your local drive. Every time you click the button, the counter changes and this way the image changes.
Now I would like to change the text, when clicking as well. But not sure How to start this, maybe you guys have any ideas?
Also any suggestions, what to do when I don't know How many images are in my folder. Currently they are hard coded to 5.
Thanks a lot!
HTML Markup:
<div class="text" id="caption">
This is image 1
</div>
Javascript
const nextBtn = document.querySelector('.nextBtn');
const prevBtn = document.querySelector('.prevBtn');
const container = document.querySelector('.images');
const textElement = document.querySelector(".text");
let counter = 0;
nextBtn.addEventListener('click',nextSlide);
prevBtn.addEventListener('click',prevSlide);
function nextSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:500, fill: 'forwards'});
if(counter==4)
counter=-1;
counter = setText(counter, "up");
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
function prevSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:1000, fill: 'forwards'});
if(counter==-0)
counter=5;
counter = setText(counter, "down");
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
function setText(cntr, direction){
if(direction=="up") {
cntr++;
} else {
cntr--;
}
if(cntr==0){
document.getElementById("caption").innerHTML = "This is image 1";
} else if(cntr==1){
document.getElementById("caption").innerHTML = "This is image 2";
} else if(cntr==2){
document.getElementById("caption").innerHTML = "This is image 3";
} else if(cntr==3){
document.getElementById("caption").innerHTML = "This is image 4";
} else if(cntr==4){
document.getElementById("caption").innerHTML = "This is image 5";
}
return cntr;
}

Why's my image fade behaving weirdly when fading into next & last image in the array?

I don't understand why the previous image's being shown for a split second before moving on to the next image upon clicking.
Also, when I reach the last image, it should redirect to indexTwo.html which it does successfully. However, 'image down' coming from the alt attribute in <img/> is being shown for like two seconds before it reaches indexTwo.html successfully.
I tried many many different attempts to rectify this, way too many to list!
How can I prevent this behavior from happening?
Here's my html:
<img id="the-image" class="img-responsive"
src="http://tech21info.com/admin/wp-content/uploads/2013/03/chrome-logo-200x200.png"
alt="image down"
onclick="clickedImage()"
/>
Here's my js:
let theImage = document.getElementById('the-image');
let index = [
"http://tech21info.com/admin/wp-content/uploads/2013/03/chrome-logo-200x200.png",
"https://cdn.tutsplus.com/net/uploads/legacy/155_drupal/200x200.png",
"https://townandcountryremovals.com/wp-content/uploads/2013/10/firefox-logo-200x200.png"
];
let op = 1;
let imageId = 0;
let clickedImage = () => {
// start animation opacity
if(op === 1) {
let timer = setInterval(() => {
if(op <= 0.1) {
// load the next image
imageId = imageId + 1;
console.log(imageId);
theImage.src = index[imageId];
if (imageId >= index.length) {
window.location = "indexTwo.html";
}
// reset the opacity
theImage.style.opacity = op = 1;
clearInterval(timer);
} else {
op -= 0.1;
theImage.style.opacity = op;
}
}, 100);
}
};
The issue is that you are overflowing the array.
When imageId == 3 then the following line:
theImage.src = index[imageId];
results in theImage.src being set to undefined.
An easy way to resolve this would be to rearrange your code so that the image only advances to the next image if the id is within the bounds of the array.
let clickedImage = () => {
// start animation opacity
if(op === 1) {
let timer = setInterval(() => {
if(op <= 0.1) {
// load the next image
imageId = imageId + 1;
console.log(imageId);
if (imageId >= index.length) {
window.location = "indexTwo.html";
} else {
theImage.src = index[imageId];
// reset the opacity
theImage.style.opacity = op = 1;
}
clearInterval(timer);
} else {
op -= 0.1;
theImage.style.opacity = op;
}
}, 100);
}
};

change css of element depending on current slide

I'm currently working on a slider for a website.
This slider has three components.
Game list
Team overview
Awards
I have all games displayed at the same time, but only want the one corresponding to the current team be highlighted. The amount of games displayed is equal to the amount of teams and game[0] belongs to team[0] and so on.
EDIT I've changed the slider a bit :)
var slides = document.getElementsByClassName('slider');
[].forEach.call(slides, function (s) {
var next = s.getElementsByClassName('next')[0],
prev = s.getElementsByClassName('prev')[0],
inner = s.getElementsByClassName('inner')[0],
slides = inner.getElementsByClassName('slide'),
currentTeamIndex = 0,
width = 1344;
var $gameList = $('#gameList'),
$gameContainer = $gameList.find('.slides'),
$game = $gameContainer.find('.slide');
function switchSlide() {
inner.style.left = -width * currentTeamIndex + 'px';
}
next.addEventListener('click', function () {
currentTeamIndex++;
if (currentTeamIndex >= slides.length) {
currentTeamIndex = 0;
}
switchSlide();
});
prev.addEventListener('click', function () {
currentTeamIndex--;
if (currentTeamIndex < 0) {
currentTeamIndex = slides.length - 1;
}
switchSlide();
});
});
How can I do that? I'm fairly new to javascript and jQuery.

Sequentially highlighting divs using javascript

I'm trying to create kind of runway of lights and here's what it looks like now
http://jsfiddle.net/7NQvq/
var divs = document.querySelectorAll('div');
var index = 0;
setInterval(function(){
if(index > divs.length+20){
index = 0;
}
if(divs[index-1]){
divs[index-1].className = '';
}
if(divs[index]){
divs[index].className = 'active';
}
index++;
}, 50);
What I don't like about it is that it's completely inflexible and hard to adjust. Furthermore it also runs additional 20 empty cycles which is wrong. Is there a better way to achieve it (preferrably pure JS)?
It seemes that there must be some combination of setInterval and setTimeout but I just can't make it work.
I've made some adjustments to use a CSS animation rather than messing around with transitions and class toggling.
Updated Fiddle
All the JavaScript does now is define the animation delay for each dot.
You can adjust:
The animation delay - I just have i/10, but you could make it i/5, i/20... experiment!
The animation duration - it's set to 1s in my Fiddle, but try shorter and longer to see what happens
The 50% that indicates when the light has faded out
How about
function cycle(selector, cssClass, interval) {
var elems = document.querySelectorAll(selector),
prev = elems[0],
index = 0,
cssClassRe = new RegExp("\\s*\\b" + cssClass + "\\b");
if (elems.length === 0) return;
return setInterval(function () {
if (prev) prev.className = prev.className.replace(cssClassRe, "");
index %= elems.length;
elems[index].className += " " + cssClass;
prev = elems[index++];
}, interval);
}
and
var runwayIntval = cycle("div", "active", 100);
and at some point
clearInterval(runwayIntval);
See: http://jsfiddle.net/arNY8/1/
Of course you could argue that toggling a CSS class is a little limited. You could work with two callback functions instead: one to switch on a freely definable effect, one to switch it off:
function cycle(elems, enable, disable, interval) {
var prev = elems[0], index = 0;
if (elems.length === 0) return;
return setInterval(function () {
index %= elems.length;
if (prev) disable.call(prev);
enable.call(elems[index]);
prev = elems[index++];
}, interval);
}
and
var cycleIntval = cycle(
document.querySelectorAll("div"),
function () {
this.className += " active";
},
function () {
this.className = this.className.replace(/\s*\bactive\b/, "");
},
100
);

JS slideshow works one way

My slideshow is suffering from erratic behaviour. it's driven by pagers which the user clicks. when the corresponding pager is clicked, the next image is made visible (opacity/filter) and set as z-index 5 so that it should sit beneath the present image (z-index 10). The current image is then faded-out and finally, the next image is set to current and the image that has faded out is set to z-index 0. However, this only works when clicking back to a previous image (in Chrome, ie is behaving even more strangely.) in the order of images. That is to say,
chrome:
"list_slide1" to "list_slide3" instant jump with no fade
"list_slide3" to "list_slide1" fade behaves correctly
then...
"list_slide1" to "list_slide3" instant jump no fade "list_slide3" to
"list_slide2" fade behaves correctly
or...
"list_slide1" to "list_slide6" instant jump no fade
"list_slide6" to any preceding list-slide1-5 fade behaves correctly
IE:
"list_slide1" to "list_slide3" instant jump with no fade
"list_slide3" to "list_slide1" a second pause then jump
The pagers and the images are dynamically generated from a database (hence the little piece of PHP at the bottom of the code). it contains as many items as are listed for the page in the database.
a few notes:
1) the fade function is my own take on
http://javascript.info/tutorial/animation and has worked just fine in
another slideshow elsewhere on the site.
2) getElementsByClass is from http://www.robertnyman.com and returns
parent and child elements of the requested class in an array (hence
why I call current[0] etc.)
thanks.
<script type="text/javascript">
var pager = document.getElementById('pager1');
var list_pagers = document.getElementById('pagers')
var i = 0;
var next_slide = function(next) {
if (next.className !== 'slide_current') {
if (getElementsByClassName('slide_pending').length === 0) {
var current = getElementsByClassName('slide_current');
next.className = 'slide_pending';
next.style.zIndex = 5;
next.style.opacity = 1;
next.style.filter = 'alpha(opacity = 100)';
next.style.display = 'block';
fade(current[0], linear, 1000);
var fadeSlide = switcher(next, current);
}
}
}
var switcher = function(now, then) {
setTimeout(function() {
now.className = 'slide_current';
now.style.zIndex = 10;
now.style.opacity = 1;
now.style.filter = 'alpha(opacity = 100)';
then[0].className = 'slide_hide';
then[0].style.zIndex = 0;
then[0].style.opacity = 0;
then[0].style.filter = 'alpha(opacity = 0)';
then[0].style.display = 'none';
}, 1001);
}
<?php
// dynamically build event for each pager/slide in the show.
for ($k = 1; $k <= $i; $k++) {
echo 'var next_slide' .$k. ' = document.getElementById("list_slide" +' .$k. '); ',
'addEvent(list_pagers.childNodes[' .($k - 1). '], "click", function () {next_slide(next_slide' .$k. ')}); ';
}
?>
Forgive me for not posting an answer to your exact problem, but I would steer away from writing Javascript plugins yourself for the following reasons:
Hundreds of them exist on the Web already, some of which are developed on GitHub as open source, preventing potential issues through collaborative development.
There is no need to reinvent the wheel; simply spend 20 minutes googling javascript sliders and find one that you can customise to your needs.
A couple I like using are 'caroufredsel', which is responsive and offers a few nice features (dynamically adding items, callbacks etc).
Another is 'flexslider'.
SOLUTION:
the problem was that the <div> tags i was trying to fade each contained an <img> and another <div>... the CSS being applied was either working inconsistently/erratically or - as is IE's wont - not-at-all.... The solution was - rather than animating the fade of the parent <div> - animating the respective child components separately. At first, it looked like the IE solution was completely unto itself; in fact, it was insightful to creating a neat, lightweight non-JQuery slideshow for all the browsers. One trade-off was that I had to incorporate all the styling into the element tags rather than a separate CSS. This seemed like the only viable option in this instance by virtue of the nature of the DOM requests being made...
Questions/feedback gratefully received:
<script type="text/javascript">
var list_pagers = document.getElementById('pagers')
var i = 0;
<?php
// dynamically build event for each pager/slide in the show.
for ($k = 1; $k <= $i; $k++) {
echo 'var next_slide' .$k. ' = document.getElementById("list_slide" +' .$k. '); ',
'addEvent(list_pagers.childNodes[' .($k - 1). '], "click", function () {next_slide(next_slide' .$k. ')}); ';
}
?>
var next_slide = function(next) {
if (next.className !== 'slide_current') {
if (navigator.appName === 'Microsoft Internet Explorer') {
//IE 7 & 8
if ((navigator.appVersion.search('MSIE 8.0') >= 1) || (navigator.appVersion.search('MSIE 7.0') >= 1)) {
var current = getElementsByClassName('slide_current')[0].childNodes[0];
var currentBar = getElementsByClassName('slide_current')[0].childNodes[1];
var nextBar = next.childNodes[1];
var nextSlide = next.childNodes[0];
} else {
//IE 9
var current = getElementsByClassName('slide_current')[0].childNodes[1];
var currentBar = getElementsByClassName('slide_current')[0].childNodes[2];
var nextBar = next.childNodes[2];
var nextSlide = next.childNodes[1];
}
// give the next slide and its header (nextBar) a temporary status of zIndex 5/6
nextSlide.style.zIndex = 5;
nextBar.style.zIndex = 6;
nextSlide.style.filter = "alpha(opacity=100)";
nextBar.style.filter = "alpha(opacity=85)";
fade(currentBar, linear, 500); // fade currentBar out
fade(current, linear, 500); // fade current out
//once we've faded out current slides, it's time to replace them with th
setTimeout(function() {
getElementsByClassName('slide_current')[0].className = 'slide_hide';
next.className = 'slide_current';
nextSlide.style.opacity = 1; // IE 9 includes opacity...
nextBar.style.opacity = 1; // IE 9 includes opacity...
nextSlide.style.filter = "alpha(opacity=100)";
nextBar.style.filter = "alpha(opacity=85)";
nextSlide.style.zIndex = 10;
nextBar.style.zIndex = 11;
}, 500);
} else {
// NON IE TAGS
var current = getElementsByClassName('slide_current')[0];
current.childNodes[1].style.zIndex = 10; // [1] the child <img> tag
current.childNodes[2].style.zIndex = 11; // [2] the child <div> tag
current.childNodes[1].style.opacity = 1;
current.childNodes[2].style.opacity = 0.85;
next.childNodes[1].style.zIndex = 5;
next.childNodes[2].style.zIndex = 6;
next.childNodes[1].style.opacity = 1;
next.childNodes[2].style.opacity = 0.85;
fade(current.childNodes[1], linear, 600); // fade current out
fade(current.childNodes[2], linear, 600); // fade current out
var fadeSlide = setTimeout(function() {switcher(next, current)}, 500);
var switcher = function(now, then, nowBar, thenBar) {
then.className = 'slide_hide';
then.childNodes[1].style.opacity = 0;
then.childNodes[2].style.opacity = 0;
now.className = 'slide_current';
now.childNodes[1].style.opacity = 1;
now.childNodes[2].style.opacity = 0.85;
now.style.opacity = 1;
}
}
}
}
</script>

Categories