javascript to load image source keeps the page blinking - javascript

I am new to Javascript,
I try to make a simple program which changes image source on button click.
the image is being loaded but immediately deleted.
it works only if I call the image source loading function from the onload event of the body.
but than the result is wromg:
it loads all the page with the wrong image source and than call the onload function -> resulted in page that blinks twice until fully loaded.
My final goal is to allow one initial images loading and than change images on button click from javascript (not calling the server). Thanks in advance
function load() {
document.getElementById("mainImg").src = 'Koala.jpg';
}
<button type="submit" name="btn0101" value="btn" onclick="load()" >
<img src="iconUnavail.png" id="mainImg" />
</button>

I assume you are trying to preload images. This is how you do that.
var myImage = new Image(100, 100)
myImage.src = "mainImg"
Then when you are ready (button click), just swap out the src and the image will appear immediately.
That said, a better way would be to use sprites.

What you can do is bind your event to the onclick event in the button itself like so
jsFiddle https://jsfiddle.net/a3pv8j71/1/
Html
<img id="mainImg" src="http://www.squirrelsandmore.com/media/wysiwyg/feline_cat_img.jpg">
<button type="submit" onclick="changeImage()">Change img
</button>
Javascript
function changeImage() {
document.getElementById("mainImg").src = 'http://photos.jibble.org/Experimental/Flying%20Cat/IMG_4821%20Flying%20cat%20.JPG';
}

The "submit" call in your <button> will force the page reload - try removing that.

Related

Why does onload cause my image switch to flicker?

For some reason, when I use the attribute onload on my img tag, it causes my images to flicker. Ideally, when I load the page, an image is displayed and when I refresh the page, the image is changed.
Here's my tag as well as the function for it:
HTML
<img id="randomimage" onload="randomImg()" src="images/carmainpic.jpg" alt="main pic of car"/>
JavasScript
function randomImg(){
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
}
Because the function you're calling changes the image's src to a random pick from the array, triggering a new load event, which changes the src randomly again, etc. On at least some browsers the cycle probably stops when you happen to assign the URL the image already has, too.
If your goal is to just show one of those images, at random, you can do that by leaving src off the img entirely and then adding it (once) with script (either immediately following the img in order to avoid your layout having to be adjusted when you add it, or in script at the end of the page if you prefer; no need to wait for any event):
<img id="randomimage" alt="main pic of car"/>
<script>
(function() {
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random() * images.length); // <== Note change, so adding images to the array Just Works
document.getElementById("randomimage").src=images[num];
})();
</script>
Even if you put the script immediately after the <img ...> tag, the img element will be available to the script. So your choice whether to do it inline or with the other scripts at the end of the page.
The randomImg function is called every time the image loads. You can use a flag variable to make sure that you only change the image once:
var changed = false;
function randomImg(){
if (!changed) {
changed = true;
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
}
}
The problem is that you are listening to the load event on the image, instead of the page.
onload="randomImg()"
So, as soon as the first image loads, it triggers the function randomImg which causes change of src attribute on the image. So the browser will attempt to assign a new image to the element, and yet another load event is triggered, which repeats the entire cycle.
Instead, if you want to choose a random image when the page loads, you can listen to DOMContentLoaded event on the document, and choose a random image.
document.addEventListener("DOMContentLoaded", function() {
var images=["images/carmainpic.jpg","images/carmainpic2.jpg","images/carmainpic3.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
console.log("Showing: " + images[num]);
});
<img id="randomimage" src="images/carmainpic.jpg" alt="main pic of car"/>
Note: Since you are selecting a random image, it is not guaranteed that you will always get a different image when the page is refreshed. Instead, if you must get a different image on refreshing the page, you can perhaps persist the image identifier in localStorage, and use that to determine the next image to display.
Well you can use $(document).ready(function(){}) to do that. Because you want when charge the page that function execute it.
$(document).ready(function(){
function randomImg(){
var images=["https://www.bensound.com/bensound-img/romantic.jpg","https://www.psdstack.com/wp-content/uploads/2016/10/featured-copyright-free-mages.jpg","http://shaebaxter.com/wp-content/uploads/2015/04/Life-of-Pix-free-stock-photos-sea-peaople-water-waves-back-Sunset-Joshua-earle-1024x682.jpg"];
var num=Math.floor(Math.random()*3);
document.getElementById("randomimage").src=images[num];
}
randomImg();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="randomimage" src="" alt="main pic of car"/>

HTML multiple onclick events not occurring when I want

When the user clicks read more, I want the page to change to the new page (News.html) and then scroll down a specific amount so that it lines up with the article, but what's happening is that when you click read more, the page lowers a specific amount and then changes to the top of the news.html page
<article>
<h3>Is Joe Hart right for Torino?</h3>
<img src = "News_Images/Joe_Hart_Torino.jpg" alt = "Joe" width="225" height="150">
<button class = "btn btn-block btn-primary" onclick ="Change(); scrollWin();">
<p>Read</p>
</button>
</article>
<script>
function Change(){
document.location.href = "News.html";
}
</script>
<script>
function scrollWin() {
window.scrollBy(100, 175);
}
</script>
You can use fragment for instance #content. Put in appropriate place on the
News.html page and update your function to something like
function Change(){
document.location.href = "News.html#content";
}
Btw when you click only one onclick event occurs it's not supposed to occur multiple events and in your case both functions are executed, just moving takes time and you see scrolling first. Using scroll with hardcoded value is not good idea, you'll need to update it every time you update content of News.html
**UPDATE**
procrastinator is right, see comment below, just use anchor if it's applicable for you.
When you move to another page, javascript reloads and does not continue execution from where you left off.
A solution to your problem could be using a request parameter.
Change your function to this:
function Change(){
document.location.href = "News.html?scroll=yes";
}
And in your News.html page, add this code to the page's onload event:
var url = new URL(window.location.href);
var param = url.searchParams.get("scroll");
if (param == "yes")
window.scrollBy(100, 175);

JS load image on click

I need to load an image, js need to get link url and print this image on screen.
But it is not working.
What is wrong with my script? what can I do to make it work and improve it?
html
<div id=img></div>
<div id=loading></div>
<a href=http://png-5.findicons.com/files/icons/1580/devine_icons_part_2/128/my_computer.png class=postmini>Open image 1</a>
<br>
<a href=http://www.iconshock.com/img_jpg/BETA/communications/jpg/256/smile_icon.jpg class=postmini>Open image 2</a>
js
$(function() {
$(".postmini").click(function(){
var element = $(this);
var I = element.attr("href");
$("#loading").html('<img src="loader.gif" align="absmiddle"> loading...');
$("#loading").ajaxComplete(function(){}).slideUp();
$("#img").append(I);
});
});
https://jsfiddle.net/u6j2udzb/
and this loading div, what I need to do to make it work properly?
You are missing a lot and have a lot you don't need. I have commented out where you don't need items. In particular you don't need a loading because the image will be there before they see that. However, if you do want it still, you should be loading it underneath the image you are loading. So it gets covered by the image. I can update it with that if you'd like.
What you are missing is actual code to turn the href into an image source and you are not removing the default action of the anchor tag so it doesn't try loading a new page when clicked.
$(".postmini").click(function(event){
event.preventDefault();
var element = $(this);
var I = element.attr("href");
//$("#loading").html('loading...');
//$("#loading").ajaxComplete(function(){}).slideUp();
// remove old image if it is already there.
$("#img").empty();
// create variable holding the image src from the href link
var img = $("<img/>").attr("src", I)
$("#img").append(img);
});
https://jsfiddle.net/3g8ujLvd/
You just have to insert an img tag into your "display div" on click on the link... to load the image... (btw your syntax errors are terrible... you have to use quotes for attributes^^)
like this for example :
$('.postmini').on('click',function(){
//do something
});
Check this : https://jsfiddle.net/u6j2udzb/8/
(done quickly for example)
Hope it helps
You are not running an ajax script. ajaxComplete is only fired after an ajax script completed.
Whenever an Ajax request completes, jQuery triggers the ajaxComplete
event. Any and all handlers that have been registered with the
.ajaxComplete() method are executed at this time.
You should ad an ajax script and than ajaxComplete will run if you registered the ajaxComplete method.
At the moment you're just placing the text from the "href" attribute on the link into the div. You need to either create an image or use the link provided as a background.
The quickest way to see this is to change make this change:
var element = $(this);
var I = element.attr("href");
$("#loading").html('<img src="loader.gif" align="absmiddle"> loading...');
$("#loading").ajaxComplete(function(){}).slideUp();
// $("#img").append(I);
$("#img").html("<img src='"+I+"' />");
$('.postmini').on('click',function(e){
e.preventDefault();
$('#loading').html('<img src="'+this.href+'">').children('img').one('load',function(){$(this).parent().slideUp('slow');});
});
Noticed I used on instead of click this allows you to use this.href rather than a more lengthy $(this).attr('href'). I also used .one on a child image element to find out if the image has loaded.
But I've just realised that this is useless because you want to have a loader. Ma bad.
$('.postmini').on('click',function(e){
e.preventDefault();
//best have the loader.gif showing on default before the load is complete.
var img=$('<img class="loadedImage">');
img.src=this.href;
//img.css({display:none;});//remove this if you've enter CSS .loadedImage{display:none;}
$('#loading').append(img).slideDown('slow',function(){$(this).children('.loadedImage').one('load',function(){$(this).fadeIn('slow');$(this).siblings('img[src="loader.gif"]').hide();});});
});
This method is what you're looking for. Basically you want to click the link, stop the default action of going to the link, make a new image element and set the src, make sure it's hidden before load, add the new image element to loading, slide up parent loading, check for load and fade in :)
Try and run this simple snippet
$('#myButton').click(()=>{
let imgUrl = $('#imgUrl').val();
$.get(imgUrl)
.done(() => {
$('img').attr('src', imgUrl);
$('#imgText').text('');
})
.fail(() => {
$('#imgText').text('Image does not exist');
$('img').attr('src', '');
})
})
img {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Image url: <input type="text" id="imgUrl" value="https://upload.wikimedia.org/wikipedia/commons/7/75/Woman_mechanic_working_on_engine_%28cropped%29.jpeg"><br>
<button id="myButton" type="button">click here to load image</button>
<div id="imgText"></div>
<img>

Show preloader image when clicked on <a> tag?

I would like all HTML link (<a href=...) tag to show an image (GIF preloader) center of the screen when clicked. Currently, I have a code that shows a loading progress bar but it only shows when that page is loaded. I want the GIF preloader to show immediately after user clicked on a link.
What code and where do I need to add?
Try this,
$(function(){
$('a').on('click',function(e){
$('<img src="image-pat/img.gif" class="image-loader"/>').appendTo('body');
// ....
// your code
// ....
if($('.image-loader').length) { // check length to remove image-loader again
$('.image-loader').remove();// use, if you want to remove the loader again
}
return true;
});
});
You have to preload the image.
To do that, either create an image element and hide the image, only show on click.
OR
You can call createElement on the document ready function and set its source like below:
var elem = document.createElement("img");
elem.setAttribute("src", "images/my_image.jpg");
Then, when you use that source elsewhere, it would show the image immediately as its already loaded by browser.
use jquery .imageloader()
<img class="img" src="image.png" />
<script>
$(function() {
$('.img').imageloader();
});
</script>
add the function to a button
Hope this helps.
Visit here for loads of examples.
.imageloader()
try this out

execute code AFTER Recaptcha.reload() is finished

I have a function below which is called to reload a recaptcha image. It works, reloads the image but won't do anything after that. Basically the form is small that has this recaptcha on it so I've shrunk it and allowed for clicking to enlarge and all that. If the person presses "get another captcha" which calls reloadCAP() it checks to see if it has the class of being the larger image. if it does i need it to add that class and css back to the elements AFTER the new image has loaded but I can't seem to get it to work. Any ideas?
function reloadCAP() {
if($("#recaptcha_widget img").hasClass('largecap')) {
Recaptcha.reload();
$("#recaptcha_widget img").addClass('largecap');
$('#recaptcha_image').css('height', '62px');
} else {
Recaptcha.reload();
}
}
here's the html for this:
<div id="recaptcha_widget" class="formRow" style="display:none;">
<span class="f_label">Enter Words Below:</span>
<input type="text" class="setWidth" id="recaptcha_response_field" name="recaptcha_response_field" />
<div class="cantread">
<strong>Can't read this?</strong><br />
Get another CAPTCHA
</div>
<div id="recaptcha_image"></div> <!-- image loaded into this div -->
<div class="clear"></div>
<span class="smalltext">(click to enlarge)</span>
<br clear="all" />
</div>
<script type="text/javascript" src="http://api.recaptcha.net/challenge?k=6LfzMMwSAAAAADV6D04jDE6fKwrJ57dXwOEW-vY3&lang=en"></script>
$("#recaptcha_widget img").one('load',function(){
$("#recaptcha_widget img").addClass('largecap');
$('#recaptcha_image').css('height', '62px');
});
This will put a one time only listener on the load event of the image that you are reloading and then executes the folowing code.
I used .one() instead of .load() here because you don't want to attach a new listener every time you call reloadCAP()
Edit
Ok, so here's what I believe the issue is. When you call Recaptcha.reload() it is removing the <img /> and replacing it with a new one. So when we are trying to attach the event it is getting removed as the image gets removed.
What you need to do is place the class largecap on the recaptcha_image div and modify your css style to look like
.largecap img {
height: whatever;
width: whatever;
}
Not the ideal solution, but you could put the addClass code above Recaptcha.reload() and just delay it by a second or two.
Hope that helps.
It sounds like what you actually need is custom theming such that you can style the captcha/image/etc exactly as needed: https://developers.google.com/recaptcha/docs/customization
If you do want to stick to your current implementation, you can hook into Recaptcha's built in (and undocumented) callback functions prior to calling Recaptcha.create().
//Called after Recaptcha.reload() is finished loading
Recaptcha._alias_finish_reload = Recaptcha.finish_reload;
Recaptcha.finish_reload = function (challenge, b, c) {
//Call original function that creates the new img
Recaptcha._alias_finish_reload(challenge, b, c);
$("#recaptcha_widget img").toggleClass('largecap', true);
}
//Called when the initial challenge is received on page load
Recaptcha._alias_challenge_callback = Recaptcha.challenge_callback;
Recaptcha.challenge_callback= function () {
//Call original function that creates the new img
Recaptcha._alias_challenge_callback();
$("#recaptcha_widget img").toggleClass('largecap', true);
}
The reason you're even having this problem is because Recaptcha destroys and creates a new img everytime it reloads, so the styling you added manually will be lost.

Categories