Add previous and next functions for slideshow with window.onload JavaScript - javascript

I want to create a JavaScript program who allow the user to switch between
image by using previous and next button. But i can't use window.onload to load the next image cause window.onload overwrite the previous window.onload. I want to know if their exist any solution to make window.onload work with two functions in the same time. If window.onload can't be usable for this kind of program you can suggest me another solution.
Thank you.
var i =0;
var image = [];
image[0]= 'image.jpg';
image[1]= 'image2.jpg';
image[2]= 'panther.jpg'
function next(){
document.slide.src = image[i];
if(i<image.length-1){
i++;
}
else{
i=0;
}
document.getElementById('bouton1').addEventListener('click',next);
}
function previous(){
document.slide.src = image[i];
if(i>0){
i--;
}
else{
i=image.length-1;
}
document.getElementById('bouton2').addEventListener('click',previous);
}
window.onload = next;
window.onload = previous;

Needed a couple of changes, can you test it like this. Note we changed the onload to attach listeners. See comment.
var i =0;
var image = [];
image[0]= 'image.jpg';
image[1]= 'image2.jpg';
image[2]= 'panther.jpg'
function next(){
document.slide.src = image[i];
if(i<image.length-1){
i++;
}
else{
i=0;
}
}
function previous(){
document.slide.src = image[i];
if(i>0){
i--;
}
else{
i=image.length-1;
}
}
// This is window.onload
(function(){
// Move calls to attach event listeners here
document.getElementById('bouton2').addEventListener('click',previous);
document.getElementById('bouton1').addEventListener('click',next);
})();

addEventListener is a better method for adding an event handler without replacing an existing one.
window.addEventListener('load', e => { /* ... */ });
As a rule of thumb, any on(blah) attributes in the DOM can be replaced with addEventListener(blah, ...).

I'm not exactly sure about your idea behind window.onload, if you want to preload images (so the user does not have to wait for the image to load on buttons click...) than you could use new Image() and something like:
const EL_slide = document.getElementById("slide");
const EL_prev = document.getElementById('prev');
const EL_next = document.getElementById('next');
const image = [
'//placehold.it/800x600/0bf?text=1',
'//placehold.it/800x600/f0b?text=2',
'//placehold.it/800x600/0fb?text=3'
];
const n = image.length;
let i = 0;
// Preload images
image.forEach(src => {
var img = new Image();
img.src = src;
});
// Animation logic
function anim() {
if((/prev|next/).test(this.id)) i = this.id === "next" ? ++i : --i;
i = i<0 ? n-1 : i%n; // Index fixer (prevents out of bound index)
EL_slide.style.backgroundImage = `url('${image[i]}')`
}
// Events
[EL_prev, EL_next].forEach(EL => EL.addEventListener('click', anim));
// Load first!
anim();
#slide {
height: 70vh;
transition: 0.3s;
background: none 50% 50% / cover no-repeat;
}
<button id="prev">←</button>
<button id="next">→</button>
<div id="slide"></div>
and just make sure to place your Javascript right before the closing </body> tag.

Related

Fade effect refresh on lost focus mutiple times

I am new to web development and I love it.
But I've have encountered a problem and I can't figure it out.
When i lose my focus on my browser tab, my fade effect ,made for my images when they are change, is turns on multiple times. .
Another problem, i really want my images inside of my div element to be like : http://jsfiddle.net/eb51hxj1/ when i resize the browser.
<div class="divImage">
<img id="image"> </div>
<div>
My code is :
https://jsfiddle.net/a2bsarfb/
Make a new var that checks for the window focus. When the window focus is gone then just skip the rest of the code.
At the very top add a new var:
var lostFocus = false;
In the Caller function add:
if(lostFocus){ return false; }
So it will look like:
function Caller() {
var imag = ["https://i.ytimg.com/vi/tq0H6nQMdNk/maxresdefault.jpg", "https://i.ytimg.com/vi/4qVMnkF7W60/maxresdefault.jpg", "https://s-media-cache-ak0.pinimg.com/originals/52/1d/e6/521de6a52e774664745132156448f43b.jpg"];
var numarImagini = imag.length - 1;
var i = Math.floor((Math.random() * imag.length));
Rotate(imag[i], i);
i++;
setInterval(function() {
if(lostFocus){ return false; }
if (i > imag.length - 1) {
i = 0;
Rotate(imag[i], i);
i++;
} else {
Rotate(imag[i], i);
i++;
}
}, 2000)
}
And at the bottom add the event listeners:
window.onblur = function() { lostFocus = true; };
window.onfocus = function() { lostFocus = false; };

div with an id wont accept any event handlers JavaScript. No Jquery

Im trying to pause a timed slideshow when you're hovering over a div
<div id="play_slide" onMouseOver="clearTimeout(playTime)"></div>
If i put onMouseOver="clearTimeout(playTime)" inside an li on the page, it'll pause, so I know my code is correct, it just wont work on the div! Also if i get rid of the id, it will alert when i put an alert function into an event handler
This is the js.
var playTime;
function playSlide()
{
var slideshow = document.getElementById("play_slide").style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if(indexPlay > images.length - 1)
{
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/"+images[indexPlay]+".png')";
playTime = setTimeout("playSlide()", 2500);
}
you can see this here: www.nicktaylordesigns.com/work.html
I would do it like this:
( and no inline script... just <div id="play_slide">Something</div> )
var playTime;
var indexPlay = 0;
var slideElement;
window.onload = function () {
slideElement = document.getElementById("play_slide");
slideElement.addEventListener('mouseenter', function () {
console.log('stop');
clearTimeout(playTime);
});
slideElement.addEventListener('mouseleave', function () {
console.log('continue');
playTime = setTimeout(playSlide, 2500);
});
playSlide();
}
function playSlide() {
var slideshow = slideElement.style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if (indexPlay > images.length - 1) {
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/" + images[indexPlay] + ".png')";
playTime = setTimeout(playSlide, 2500);
}
Fiddle
This issue is related to the script loading. Your script gets loaded after the DOM is processed so function doesn't get attached to the event.
If you are using jQuery then you can use below code.
$(function () {
$("#play_slide").mouseover(function(){
var playTime = 33;
clearTimeout(playTime);
});
});
If you don't want to use JQuery then you can do the same thing in JavaScript as below.
window.onload = function(){
document.getElementById("play_slide").onmouseover = function(){
var playTime = 33;
clearTimeout(playTime);
};
}
I got it! the div tag was somehow broken, I coded a div around it and gave it the event handlers and a class. That worked, then i simply changed the class to an id and got rid of the original div. Idk what was going on but it works now. Thanks for your suggestions!
Can you try this,
<div id="play_slide" onmouseover="StopSlide();">Stop</div>
<script>
var playTime;
var indexPlay;
function playSlide()
{
var slideshow = document.getElementById("play_slide").style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if(indexPlay > images.length - 1)
{
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/"+images[indexPlay]+".png')";
playTime = setTimeout("playSlide()", 2500);
}
function StopSlide(){
window.clearTimeout(playTime);
}
playSlide();
</script>

JS function that stops another JS function

I have two JS functions: a load() function that displays a progress bar and a kill () function that stops the execution of the load once the page is loaded.
Now when another page is loaded the progress bar is not displayed, knowing that the load function is called on every page.
Any hints on where the problem might be and if there is a way to fix it.
Here is my code:
<script type="text/javascript">
var count=0;
function load(i) {
j = parseInt(i);
document.getElementById("progressBar").style.display = "block";
count=count+1;
if (document.all) {
document.all.btn1.value=count+'%';
document.all.progressbar.pic1.width=2*count;
}
else {
document.getElementById("pic1").width=2*count;
document.getElementById("bar").width=count+'%';
}
if (count<100) {
setTimeout('load(j)',j);
}
if(count==100) {
document.getElementById("progressBar").style.display = "none";
count=0;
}
}
function kill(){
if (document.applets[0].isActive()) {
document.getElementById("progressBar").style.visibility = "hidden";
}
}
</script>
Thank you in advance !
In load() you're changing display to block, but in kill() you set visibility to hidden; you should set display to none instead, so it can properly be set to block again next time. Read about visibility.
Optimized code:
<script type="text/javascript">
var count = 0,
win = window,
doc = document,
progressBar = doc.getElementById("progressBar"),
t, j;
function load(i) {
j = parseInt(i);
progressBar.style.display = "block";
count++;
// no actual need to check if doc.all is available
// just select through id
doc.getElementById("pic1").style.width = 2*count;
doc.getElementById("bar").style.width = count+'%';
if (count < 100) {
t = win.setTimeout('load(j)',j);
} else {
progressBar.style.display = "none";
win.clearTimeout(t);
count = 0;
}
}
function kill(){
if (doc.applets[0].isActive()) {
progressBar.style.display = "none";
}
}
</script>
If you assign setTimeout to a variable, you can use clearTimeout on it to stop it.
E.g.
set the timeout with
t = setTimeout('load(j)',j);
then stop it with
clearTimeout(t); Let me know if that helps, and makes sense :)

Running text: Pause, Stop

I have <p> element:
<p id="news_title">Text goes here</p>
Which I have made to run text with help this JavaScript:
(function(){
var j = 0;
var el = document.getElementById("news_title");
var interval;
function runEngine(){
interval = setInterval(function(){
if (j===200){
j=-200;
}
el.style.left = j + "px";
j++;
},20);
}
window.onload = function(){
runEngine();
};
})();
Marked script working nicely, but I want to pause the text onmouseover and onmouseout let it continue running. Also, onclick I want to stop it for good.
el.onmouseover = function(){
clearInterval(interval);
}; // pausing , working nicely
el.onmouseout = function(){
runEngine();
}; // also working
The onclick is not working however. Even though I clear the interval, the onmouseout handler causes the text to run again. How can I prevent this?
On click, set a flag. Then check the flag in the onmouseout handler:
var clicked = false;
el.onclick = function() {
clicked = true;
};
el.onmouseout = function() {
if (!clicked) {
runEngine();
}
};

Checking for multiple images loaded

I'm using the canvas feature of html5. I've got some images to draw on the canvas and I need to check that they have all loaded before I can use them.
I have declared them inside an array, I need a way of checking if they have all loaded at the same time but I am not sure how to do this.
Here is my code:
var color = new Array();
color[0] = new Image();
color[0].src = "green.png";
color[1] = new Image();
color[1].src = "blue.png";
Currently to check if the images have loaded, I would have to do it one by one like so:
color[0].onload = function(){
//code here
}
color[1].onload = function(){
//code here
}
If I had a lot more images, Which I will later in in development, This would be a really inefficient way of checking them all.
How would I check them all at the same time?
If you want to call a function when all the images are loaded, You can try following, it worked for me
var imageCount = images.length;
var imagesLoaded = 0;
for(var i=0; i<imageCount; i++){
images[i].onload = function(){
imagesLoaded++;
if(imagesLoaded == imageCount){
allLoaded();
}
}
}
function allLoaded(){
drawImages();
}
Can't you simply use a loop and assign the same function to all onloads?
var myImages = ["green.png", "blue.png"];
(function() {
var imageCount = myImages.length;
var loadedCount = 0, errorCount = 0;
var checkAllLoaded = function() {
if (loadedCount + errorCount == imageCount ) {
// do what you need to do.
}
};
var onload = function() {
loadedCount++;
checkAllLoaded();
}, onerror = function() {
errorCount++;
checkAllLoaded();
};
for (var i = 0; i < imageCount; i++) {
var img = new Image();
img.onload = onload;
img.onerror = onerror;
img.src = myImages[i];
}
})();
Use the window.onload which fires when all images/frames and external resources are loaded:
window.onload = function(){
// your code here........
};
So, you can safely put your image-related code in window.onload because by the time all images have already loaded.
More information here.
A hackish way to do it is add the JS command in another file and place it in the footer. This way it loads last.
However, using jQuery(document).ready also works better than the native window.onload.
You are using Chrome aren't you?
The solution with Promise would be:
const images = [new Image(), new Image()]
for (const image of images) {
image.src = 'https://picsum.photos/200'
}
function imageIsLoaded(image) {
return new Promise(resolve => {
image.onload = () => resolve()
image.onerror = () => resolve()
})
}
Promise.all(images.map(imageIsLoaded)).then(() => {
alert('All images are loaded')
})
Just onload method in for loop does not solve this task, since onload method is executing asynchronously in the loop. So that larger images in the middle of a loop may be skipped in case if you have some sort of callback just for the last image in the loop.
You can use Async Await to chain the loop to track image loading synchronously.
function loadEachImage(value) {
return new Promise((resolve) => {
var thumb_img = new Image();
thumb_img.src = value;
thumb_img.onload = function () {
console.log(value);
resolve(value); // Can be image width or height values here
}
});
}
function loadImages() {
let i;
let promises = [];
$('.article-thumb img').each(function(i) {
promises.push(loadEachImage( $(this).attr('src') ));
});
Promise.all(promises)
.then((results) => {
console.log("images loaded:", results); // As a `results` you can get values of all images and process it
})
.catch((e) => {
// Handle errors here
});
}
loadImages();
But the disadvantage of this method that it increases loading time since all images are loading synchronously.
Also you can use simple for loop and run callback after each iteration to update/process latest loaded image value. So that you do not have to wait when smaller images are loaded only after the largest.
var article_thumb_h = [];
var article_thumb_min_h = 0;
$('.article-thumb img').each(function(i) {
var thumb_img = new Image();
thumb_img.src = $(this).attr('src');
thumb_img.onload = function () {
article_thumb_h.push( this.height ); // Push height of image whatever is loaded
article_thumb_min_h = Math.min.apply(null, article_thumb_h); // Get min height from array
$('.article-thumb img').height( article_thumb_min_h ); // Update height for all images asynchronously
}
});
Or just use this approach to make a callback after all images are loaded.
It all depends on what you want to do. Hope it will help to somebody.
try this code:
<div class="image-wrap" data-id="2">
<img src="https://www.hd-wallpapersdownload.com/script/bulk-upload/desktop-free-peacock-feather-images-dowload.jpg" class="img-load" data-id="1">
<i class="fa fa-spinner fa-spin loader-2" style="font-size:24px"></i>
</div>
<div class="image-wrap" data-id="3">
<img src="http://diagramcenter.org/wp-content/uploads/2016/03/image.png" class="img-load" data-id="1">
<i class="fa fa-spinner fa-spin loader-3" style="font-size:24px"></i>
</div>
<script type="text/javascript">
jQuery(document).ready(function(){
var allImages = jQuery(".img-load").length;
jQuery(".img-load").each(function(){
var image = jQuery(this);
jQuery('<img />').attr('src', image.attr('src')).one("load",function(){
var dataid = image.parent().attr('data-id');
console.log(dataid);
console.log('load');
});
});
});
</script>

Categories

Resources