I'm looking to dynamically load in an image:
<img data-src="test01">
And then use jQuery to take the data-src and then load in the image associated with that name, PLUS the extension. If THAT extension fails, then move onto the next extension, so on and so on until we get to the bottom when I just load in a default image. But I don't know how to check if there's an error AFTER I've set the image's attr once. Here's the loop I have so far, and I'm getting ".error not a function"
$("img").each(function(){
var newSource = $(this).data('src').toString();
$(this).attr('src', 'images/'+newSource+'.gif').error(function(){
$(this).attr('src', 'images/'+newSource+'.jpg').error(function(){
$(this).attr('src', 'images/'+newSource+'.png').error(function(){
$(this).attr('src', 'images/default.jpg');
});
});
});
});
The reason I'm doing this is because we have a database that holds the title of the image only, yet, over the years, different people have uploaded different image formats to the site, and we want to be able to load all of them on the page, sans extension, and then loop through each extension until we find a file that exists, and if not, default to a pre-set hard coded image URL
One alternative would be to do a HEAD request for the urls. A benefit of a HEAD request is that it just tries to get headers for the endpoint, without trying to return data, so it can be super fast. In your case, it could be a quick check to see if an image url is valid or not.
function changeTheSrcIfTheUrlIsValid ( element, url ) {
return $.ajax({
url: url,
type: 'HEAD',
success: function(){
//got a success response, set the src
element.src = url;
}
});
}
$("img").each(function(){
var img = this;
var newSource = img.getAttribute('src');
//check for a gif
changeTheSrcIfTheUrlIsValid( img, 'images/'+ newSource +'.gif' )
.then(null, function(){
//error handler, try jpg next
changeTheSrcIfTheUrlIsValid( img, 'images/'+ newSource +'.jpg' )
.then(null, function(){
//error handler, try png next
changeTheSrcIfTheUrlIsValid( img, 'images/'+ newSource +'.png' )
.then(null, function(){
//error handler, use default
img.src = 'images/default.jpg';
});
});
});
});
Can use a Promise and a new Image() each time. The promise gets resolved or rejected in the onload or onerror of the new Image.
Then there is a chain of catch() to try various extensions and finally set a default noImageUrl if all else fail
Something like:
function setImageSrc(src, ext, el){
return new Promise(resolve, reject){
var url = 'images/'+src+ ext;
var img = new Image()
img.src = url
img.onerror = reject;
img.onload = function(){
el.src = url; // set src of current element in dom
resolve(url)
}
}
}
$("img").each(function(){
var newSource = $(this).data('src').toString();
var self = this
setImageSrc(newSource, '.jpg', self)
.catch(setImageSrc(newSource, '.png', self))
.catch(setImageSrc(newSource, '.gif', self))
.catch(function(){
self.src = 'noImageUrl';
});
});
Related
$(document).on('change', '#id_edit_profile_photo', e => {
uploadPhoto(avatarElem, previewPPContainer, avatarUploadElem)
});
function uploadPhoto(elem, preview, uploadElem) {
elem.addClass('d-none');
preview.removeClass('d-none');
preview.find('img').attr('src', '');
let blobUrl = URL.createObjectURL(uploadElem.files[0]);
preview.find('img').attr('src', blobUrl);
// call this fuunction after completing the above task
ImageLoaded();
}
function ImageLoaded() {
_IMAGE_WIDTH = $("#drag-image").width();
_IMAGE_HEIGHT = $("#drag-image").height();
_IMAGE_LOADED = 1;
alert('Image Loaded');
}
The uploadPhoto function runs when value of the file input tag #id_edit_profile_photo changes. Inside the uploadPhoto blobUrl variable stores the url of the loaded file. The url is then set to an img tag. How do I allow the ImageLoaded function to run only after the img tag has loaded the image.
Any help is appreciated.
Thank you.
I'm appending the text and images of a php-page via Ajax to a container and showing it after all the images have been loaded. This works perfectly If I'm using only src, but not if I'm using srcset.
So far, I'm using this snippet of code, to check if all the ajaxed src-tagged images have been loaded. But of course, it's not actually working because it's checking the src and not the srcset.
$.fn.imagesLoaded = function () {
var $imgs = this.find('img[src!=""]');
if (!$imgs.length) {
return $.Deferred().resolve().promise();
}
var dfds = [];
$imgs.each(function(){
var dfd = $.Deferred();
dfds.push(dfd);
var img = new Image();
img.onload = function(){
dfd.resolve();
}
img.onerror = function(){
dfd.resolve();
}
img.src = this.src;
});
return $.when.apply($,dfds);
}
This is my Ajax code:
$.ajax({
cache: false,
url: "somefile.php",
success: function(data) {
$("body").prepend(data).imagesLoaded().then(function(){
// show the images etc.
})
)}
The expected result should be, that the checking if all images have been loaded should also work with srcset not only with src. The actual result is, that it's just not respecting the imagesLoaded().
I have the following code snippet which is called on the success of the image uploading procedure.
success(data){
$avatar.attr('src', "/images/common/loading.gif");
$avatar.attr('src', data.url);
}
Here $avatar is the container for an image tag. The idea is to load this image with loading.gif until data.url is loaded successfully. Here data.url may contain a large size image which takes long time to load.
The problem is loading.gif is never loaded to the image container until I use setTimeOut as:
success(data){
$avatar.attr('src', "/images/common/loading.gif");
setTimeOut(function(){
$avatar.attr('src', data.url);
},100);
}
Can anyone suggest me some different approach rather than to use setTimeOut?
Showing uploaded image is more important than showing loader image But if you are doing it your way, go with the onload-event.
Also listen onerror event if loader image fails, or else avatar image will never get loaded!
success(data) {
var loader = new Image();
var loadMainImage = function() {
var mainImage = new Image();
mainImage.onload = function() { //avatar is loaded!
$avatar.attr('src', this.src);
}
mainImage.src = data.url;
}
loader.onload = function() { //loader is loaded!
$avatar.attr('src', this.src);
loadMainImage();
};
loader.onerror = mainImage; //loader is failed!
loader.src = "/images/common/loading.gif";
}
I think you can use beforeSend to handle async promises
I'm trying to use the following code to play a song in JPlayer using the Getsong.php, that plays fine, the problem I'm having is with the song image(or album photo), I need to check a directory to see if that image file exists, and if it does, show it, otherwise show the "no_img_file.jpg file.
I do this by checking the domain path / user_id folder / and the song_filename .jpg
But I can't get it to work.
Please HELP
$(document).ready(function(){
$("#jquery_jplayer_1").jPlayer({
ready: function () {
var data = $.ajax({
url: "getsong.php",
async: false
}).responseText;
var string = data.split('|');
$(this).jPlayer("setMedia", {
mp3: string[0]
}).jPlayer("play");
$('ol#artist').html(string[1]);
$('ol#songname').html(string[2]);
$('ol#filename').html(string[3]);
},
ended: function (event) {
var data = $.ajax({
url: "getsong.php",
async: false
}).responseText;
var string = data.split('|');
$(this).jPlayer("setMedia", {
mp3: string[0]
}).jPlayer("play");
$('ol#artist').html(string[1]);
$('ol#songname').html(string[2]);
$('ol#filename').html(string[3]);
},
swfPath: "js",
supplied: "mp3"
});
});
/////////////////////////////
function checkImage(src) {
var img = new Image();
img.onload = function() {
// code to set the src on success
$('#image-test').css('background', 'url(' + src + ') no-repeat 50% 100%');
};
img.onerror = function() {
// doesn't exist or error loading
//alert('no image');
checkImage('http://mydomain.com/images/no_img_file.jpg');
};
img.src = src; // fires off loading of image
}
//checkImage('http://www.google.com/images/logo_sm.gif');
// uncomment to test error function
checkImage('http://mydomain.com/mp3/'<?php echo $user_id; ?>'/'.string[3]);
Instead of trying to perform this check on the client, I would perdonally recommend recommend handling it at the server end and save yourself (and USERS!) that extra request.
The simplest means (add your own interpretational logic and validation later) would be to have a file called something like "coverart.php" and when you try to get the cover art make a request to coverart.php?name=MY_COVER_ART_FILE
Then within coverart.php:
$strCoverName = $_GET['name'];
$strArtDir = 'YOUR_COVER_ART_DIRECTORY';
$strCommonExtenstion = '.jpg';
$strFile = $strArtDir.$strCoverName.$strCommonExtension;
header('Content-Type: image/jpeg');
if(is_file($strFile)) {
readfile($strFile);
} else {
readfile($strArtDir.'no_img_file'.$strCommonExtension);
}
This is a KISS way of achieving what you want, I'd recommend you look further in to the various ways of achieving this however but along similar lines
I want to create an alert box after an image is loaded, but if the image is saved in the browser cache, the .onload event will not be fired.
How do I trigger an alert when an image has been loaded regardless of whether the image has been cached or not?
var img = new Image();
img.src = "img.jpg";
img.onload = function () {
alert("image is loaded");
}
As you're generating the image dynamically, set the onload property before the src.
var img = new Image();
img.onload = function () {
alert("image is loaded");
}
img.src = "img.jpg";
Fiddle - tested on latest Firefox and Chrome releases.
You can also use the answer in this post, which I adapted for a single dynamically generated image:
var img = new Image();
// 'load' event
$(img).on('load', function() {
alert("image is loaded");
});
img.src = "img.jpg";
Fiddle
If the src is already set then the event is firing in the cached case before you even get the event handler bound. So, you should trigger the event based off .complete also.
code sample:
$("img").one("load", function() {
//do stuff
}).each(function() {
if(this.complete || /*for IE 10-*/ $(this).height() > 0)
$(this).load();
});
There are two possible solutions for these kind of situations:
Use the solution suggested on this post
Add a unique suffix to the image src to force browser downloading it again, like this:
var img = new Image();
img.src = "img.jpg?_="+(new Date().getTime());
img.onload = function () {
alert("image is loaded");
}
In this code every time adding current timestamp to the end of the image URL you make it unique and browser will download the image again
I have met the same issue today. After trying various method, I realize that just put the code of sizing inside $(window).load(function() {}) instead of document.ready would solve part of issue (if you are not ajaxing the page).
I found that you can just do this in Chrome:
$('.onload-fadein').each(function (k, v) {
v.onload = function () {
$(this).animate({opacity: 1}, 2000);
};
v.src = v.src;
});
Setting the .src to itself will trigger the onload event.