I have website and now making a hybrid app for it.
I get all my blog post using Jquery get method.
However the issue is that <img src="/media/image.png"> is sometime relative url and sometime an absolute url.
Everytime an absolute url breaks the image showing 404 error.
How to write Jquery function to find if src is absolute and change it to
https://www.example.com/media/image.png
I will not be able to provide any code samples I have tried since I am not a front end developer and tried whole day solving it.
Note: I need to change images present only in <div id="details"> div.
You should always use same path for all the images, but as of your case you can loop through images and append the domain, as of the use case I have added the domain in variable you can change it as per your requirement.
You can use common function or image onload to rerender but I h
Note: image will rerender once its loaded.
var imageDomain = "https://homepages.cae.wisc.edu/~ece533/";
//javascript solution
// window.onload = function() {
// var images = document.getElementsByTagName('img');
// for (var i = 0; i < images.length; i++) {
// if (images[i].getAttribute('src').indexOf(imageDomain) === -1) {
// images[i].src = imageDomain + images[i].getAttribute('src');
// }
// }
// }
//jquery solution
var b = 'https://www.example.com';
$('img[src^="/media/"]').each(function(e) {
var c = b + $(this).attr('src');
$(this).attr('src', c);
});
//best approach you are using get request
//assuming you are getting this respone from api
var bArray = ["https://www.example.com/media/image.png", "/media/image.png"]
var imgaesCorrected = bArray.map(a => {
if (a.indexOf(b) === -1) {
a = b+a;
}
return a;
});
console.log(imgaesCorrected);
img {
width: 50px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img src="/media/image.png">
<img src="https://www.example.com/media/image.png">
document.querySelectorAll('#details img').forEach(img => {
const src = img.getAttribute('src');
// use regex, indexOf, includes or whatever to determine you want to replace the src
if (true) {
img.setAttribute('src', 'https://www.example.com' + src);
}
});
The best would be to do this with the response html from the ajax request before inserting into the main document so as to prevent needless 404 requests made while changing the src
Without seeing how you are making your requests or what you do with the response here's a basic example using $.get()
$.get(url, function(data){
var $data = $(data);
$data.find('img[src^="/media/"]').attr('src', function(_,existing){
return 'https://www.example.com' + existing
});
$('#someContainer').append($data)'
})
You can just get all the images from an object and find/change them if they don't have absolute url.
var images = $('img');
for (var i = 0 ; i < images.length ; i++)
{
var imgSrc = images[i].attributes[0].nodeValue;
if (!imgSrc.match('^http'))
{
imgSrc = images[i].currentSrc;
console.info(imgSrc);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img src="/media/test.jpg">
<img src="/media/test.jpg">
<img src="https://www.example.com/media/test.jpg">
Related
I am trying to write a JS script that will look through the page when it loads to see if any images had an error loading, and to change the src of that image to a default image. What I was trying to do was to loop through all the list of images returned from document.images, and to check every image to see if it finished loading using image[i].complete, and if it didn't, then change the src of that image to the default link. It did not work for me, and I can't think of the solution.
window.onload = function() {
var images = document.images;
for (var i = 0; i < images.length; i++) {
if (!image[i].complete) {
images[i].src = 'assets/default-avatar.jpg';
}
}
}
The solution is to use the error event on IMG tags:
<img src="..." onerror="this.src = 'default_image_url';">
Because complete returns true even if the image couldn't be loaded (at least in some browsers), you could use naturalWidth. If no image is loaded naturalWidth is 0.
window.onload = function() {
var images = document.images;
for (var i = 0; i < images.length; i++) {
if (image[i].naturalWidth === 0) {
images[i].src = 'assets/default-avatar.jpg';
}
}
}
I have an array of URIs that represent .png elements, e.g., "./img/diamond-red-solid-1.png".
I want to assign each element of the array "gameDeck[0], gameDeck[1], etc. to div ids in HTML. Do I need to identify the elements as = SRC.IMG?
var gameDeck[];
var gameBoardCards = function () {
for (let cardArr of cardsToLoad)
gameDeck.push("./img/" + cardArr + ".png");
}
gameBoardCards();
document.addEventListener('DOM Content Loaded', function () {
gameDeck[0] = document.getElementById("card1");
gameDeck[1] = document.getElementById("card2");
etc.
});
The way I'm understanding your question is that you would like to target the divs in your HTML with ids of card1, card2, card3... card12 etc.
You would like to insert an img tag into each of these divs with the src being the URIs of the gameDeck array.
The following code achieves this. I've tested it and it works fine. Hope it helps :)
document.addEventListener('DOMContentLoaded', function () {
//iterate through the gameDeck array.
for (let x = 0;x < gameDeck.length;x++){
//create an img tag for each gameDeck element
var imgElement = document.createElement("img");
//set the source of the img tag to be the current gameDeck element (which will be a URI of a png file)
imgElement.src = gameDeck[x];
//target the div with id "card(x + 1)"
var cardID = "card" + (x + 1);
var cardElement = document.getElementById(cardID);
//append the img tag to the card element
cardElement.appendChild(imgElement);
}
//log the HTML to the console to check it
console.log(document.getElementById('body').innerHTML);
});
Here is a way that you can either insert images as background images, or as <img /> elements into the divs you are referring to:
<div id="card0" style="width: 100px; height: 100px;"></div>
<div id="card1" style="width: 100px; height: 100px;"></div>
let loadedImage = [];
function preloadImages(urls, allImagesLoadedCallback) {
let loadedCounter = 0;
let toBeLoadedNumber = urls.length;
urls.forEach(function(url) {
preloadImage(url, function() {
loadedCounter++;
console.log(`Number of loaded images: ${loadedCounter}`);
if (loadedCounter == toBeLoadedNumber) {
allImagesLoadedCallback();
}
});
});
function preloadImage(url, anImageLoadedCallback) {
img = new Image();
img.src = url;
img.onload = anImageLoadedCallback;
loadedImage.push(img);
}
}
function gameBoardCards() {
for (let i = 0; i < loadedImage.length; i++) {
document.getElementById(`card${i}`).style.backgroundImage = `url('${loadedImage[i].src}')`;
// document.getElementById(`card${i}`).appendChild(loadedImage[i]);
}
}
preloadImages([
`https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Color_icon_green.svg/2000px-Color_icon_green.svg.png`, `https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Solid_blue.svg/225px-Solid_blue.svg.png`
], function() {
console.log(`all images were loaded`);
gameBoardCards();
// continue your code
});
It may seem like a bit much for what you are trying to accomplish, but I threw in a proper image-loading handler there. The preloadImages function will handle the loading of images, that way they are properly preloaded, and can render to the DOM. Often times, we try to use images before they are properly loaded, resulting in them sometimes not being displayed, despite no errors are being thrown.
The rest of the code is straight forward, in the for loop, it loops through the existing divs and you can either use the current active line document.getElementById(`card${i}`).style.backgroundImage = `url('${loadedImage[i].src}')`; to use the loadedImage[i] image src to load that as the divs's background image. Or you can use the commented-out line directly below that document.getElementById(`card${i}`).appendChild(loadedImage[i]); to insert an <img /> element into that div. Just use either one that works for you.
You can see the code in action in this JS Fiddle demo.
Hope this helps :)
There is an image element , how do I use this same img element without sending another request to the server. Its important to note, I don't want image1.jpg downloaded twice from the webserver. Any ideas?
function loadCarousels(carouselLoc, carouselId) {
$("li").find(carouselLoc).each(function (index) {
var img = this;
var outer = 0;
$(carouselId).find("ul").each(function (innerIndex) {
var liX = document.createElement("li");
$(this).append(liX);
var imgInner = document.createElement("img");
imgInner.src = img.src;
$(imgInner).appendTo(liX);
console.log($(this));
});
});
}
Is how I currently try but it doesn't work. it creates a separate image.
Browsers should be already pretty aggressive on caching images: Chrome often shows multiple requests, but if you check from the second on usually they're all satisfied using the cache.
In case you want to cache internally in your JS code, try to cache images by URL like the following:
// use this as JS cache
var images = {};
function loadCarousels(carouselLoc, carouselId) {
$("li").find(carouselLoc).each(function (index) {
var img = this;
var outer = 0;
// cache it
if(!images[img.src]){
images[img.src] = document.createElement("img");
// if the user disable the cache, this should prevent another request
images[img.src].src = img.src;
}
$(carouselId).find("ul").each(function (innerIndex) {
var liX = document.createElement("li");
$(this).append(liX);
// retrieve from the cache
var imgInner = images[img.src];
$(imgInner).appendTo(liX);
console.log($(this));
});
});
}
Any One Know Tell me the suggestion to do this. How can i check if the anchor href attribute contain image path or some other path.
For Example:
<img src="image.jpg"/>
<img src="image.jpg"/>
See the above example shows href attribute contain different path like first one is the image and second one is the some other site link. I still confuse with that how can i check if the href path contain the image path or some other path using jquery or javascript.
Any suggestion would be great.
For example (you may need to include other pic formats if needed):
$("a").each(function(i, el) {
var href_value = el.href;
if (/\.(jpg|png|gif)$/.test(href_value)) {
console.log(href_value + " is a pic");
} else {
console.log(href_value + " is not a pic");
}
});
Jquery:
$(document).ready( function() {
var checkhref = $('a').attr('href');
var image_check = checkhref.substr(checkhref.length - 4)
http_tag = "http";
image = [".png",".jpg",".bmp"]
if(checkhref.search("http_tag") >= 0){
alert('Http!');
//Do something
}
if($.inArray(image_check, image) > -1){
alert('Image!');
//Do something
}
});
you may check if image exists or not, without jQuery
Fiddle
var imagesrc = 'http://domain.com/image.jpg';
function checkImage(src) {
var img = new Image();
img.onload = function() {
document.getElementById("iddiv").innerHTML = src +" exists";
};
img.onerror = function() {
document.getElementById("iddiv").innerHTML = src +"does not exists";
};
img.src = src; // fires off loading of image
return src;
}
checkImage(imagesrc);
I am making an image slideshow using native JS.
I decided to make it myself because it needs to run at ~100ms intervals, and without any special transition effects (see it here), so I figured it was unnecessary to include a big library like JQuery just for just a simple application.
This is the code I am currently using [edit: original code - now modified]:
// JavaScript Document
function preloadimages(arr){ // the preloadimages() function is adapted from http://www.javascriptkit.com/javatutors/preloadimagesplus.shtml
var newimages = [], loadedimages = 0;
var postaction = function() {};
var arr = (typeof arr != "object") ? [arr] : arr;
function imageloadpost() {
loadedimages++;
if (loadedimages == arr.length) {
postaction(newimages); //call postaction and pass in newimages array as parameter
}
}
for (var i = 0; i < arr.length; i++) {
newimages[i] = new Image();
newimages[i].src = arr[i];
newimages[i].onload = function() {
imageloadpost();
}
newimages[i].onerror = function() {
imageloadpost();
}
}
return { //return blank object with done() method
done: function(f) {
postaction = f || postaction; //remember user defined callback functions to be called when images load
}
}
}
/* USAGE:
preloadimages(['ed.jpg', 'fei.jpg', 'budapest.gif', 'duck.jpg']).done(function(images) {
images.sort(function(a, b) {
return a.width - b.width; //sort images by each image's width property, ascending
});
alert(images[0].src); //alerts the src of the smallest image width wise
});
*/
function animateSlideshow() {
var num = window.imgNum + 1 ;
if (num >= d['imgs'].length) {
num = 0;
}
window.imgNum = num;
imgTag.src = d['imgs'][num];
var t = window.setTimeout(function(){animateSlideshow(imgNum, imgTag, d)}, 100);
}
var d;
var imgTag;
var imgNum = 0;
$.onDomReady (function () { // This is not JQuery, it's a simple cross-browser library which you can read here: http://assets.momo40k.ch/common/js/$.js
// data is an array that should be already defined on the calling page,
// containing all the necessary information to generate all the rotation slideshows on the page
for (i = 0; i < data.length; i++) {
d = data[i];
var div = document.getElementById(d['id']);
imgTag = $.Elements.getElementsByClassName('theImage', div)[0];
// preload the images...
preloadimages(d['imgs']).done(function(images) {
imgTag.src = d['imgs'][0];
animateSlideshow();
});
}
});
<!-- HTML calling JS Scripts -->
... HTML document ...
<script src="http://assets.momo40k.ch/common/js/$-min.js" language="javascript" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
var data = [];
// I would have an index for each slideshow on the page
data[0] = [];
data[0]['id'] = 'rotation2';// the ID of the tag the initial image is in
data[0]['imgs'] = ['http://www.momo40k.ch/images/pages/stefan_lehmann/bat/pic1.png',
'http://www.momo40k.ch/images/pages/stefan_lehmann/bat/pic2.png',
'http://www.momo40k.ch/images/pages/stefan_lehmann/bat/pic3.png',
'... all the images ... '];
</script>
<script src="js/rotation.js" language="javascript" type="text/javascript"></script>
</body>
</html>
This is what the tag the initial image is in looks like:
<div id="rotation2" class="rotation blackbg">
<img src="http://www.momo40k.ch/images/pages/stefan_lehmann/bat/pic1.png" width="300" title="" class="theImage" />
</div>
Now for the question:
this script only allows me to have one single 'slideshow' on the page - because in each iteration of the loop it overrides the imgNum variable. Is there an other, better way of doing this slideshow (if possible without JQuery, otherwise OK), even in a completely different way?
Thank you
EDIT: I have remade the script following Jared Farrish's answer and it's now working fine!
There were some issues I saw with your code or approach, so I decided to redo it with the approach I would take. For instance:
I would use document.images to get all images and, for ones that have the rotator-specific className, to identify (domElement.parentNode) and obtain the containing div, which will give me it's id.
I would use the parentNode.id of the class="rotation" images to create an object with sets (by container ids) I can use to store references to the img nodes.
Use closure scope to stay out of the global scope, as well as be able to share variables between the closure-scoped functions.
Use variable functions to setup the handler and callback functions.
Let me know if you have any questions or find something that doesn't work.
<div id="rotator1" class="rotation blackbg">
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/6/6e/Brandenburger_Tor_2004.jpg" />
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/a/ad/Cegonha_alsaciana.jpg" />
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/d/da/CrayonLogs.jpg" />
</div>
<div id="rotator2" class="rotation blackbg">
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/1/17/Bobbahn_ep.jpg" />
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/9/90/DS_Citro%C3%ABn.jpg" />
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/f/f0/DeutzFahr_Ladewagen_K_7.39.jpg" />
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/c/c7/DenglerSW-Peach-faced-Lovebird-20051026-1280x960.jpg" />
<img class="slides" src="http://upload.wikimedia.org/wikipedia/commons/4/4d/FA-18F_Breaking_SoundBarrier.jpg" />
</div>
var slideshows = function(){
var timeouts = {},
imgs;
function preloadImages(list){
var loading = list,
img,
loaded = {},
newimages = [];
var imageloaded = function(){
// this here is one of the new Image()s we created
// earlier; it's not the "real" image on the screen.
// So I put the reference to the actual image it represents
// on the screen in the rel attribute so I can use it's
// reference; I just have to use this.rel to get it.
var parent = this.rel.parentNode;
// Keeping track of the individual sets loaded.
loaded[parent.id]++;
// Here is where this/self gets it's context from, when
// we .call(parent, 0). It's the parentNode to the image
// we've referenced above. This should only run once,
// when the last image has loaded for the set.
if (loaded[parent.id] == loading[parent.id].length) {
animateSlideshow.call(parent, 0);
}
};
var imagenotloaded = function(){
// this.rel is the reference to the actual image we
// have in the DOM, so we'll set the error flag on it.
this.rel['imageerror'] = true;
imageloaded.call(this);
};
for (var load in loading) {
// loaded is equivalent to imgs.sets, so load is the
// id for the container.
loaded[load] = [];
// Now we're going to loop over every image in the
// current set, creating a Javascript image object
// to initiate the download of the file and tell us
// when it's finished. Not the newimages[i].rel = img
// part.
for (var i = 0, l = loading[load].length; i < l; i++) {
img = loading[load][i];
newimages[i] = new Image();
newimages[i].onload = imageloaded;
newimages[i].onerror = imagenotloaded;
newimages[i].rel = img;
newimages[i].src = img.src;
}
}
}
var animateSlideshow = function(current) {
// this could be used instead of self. I was doing
// something else at first, but making this copy
// of the context (this) is not necessary with this
// code. It doesn't hurt either.
var self = this;
// Our current context is the containing div, so
// this.id/self.id will give us the key to the correct
// group in imgs.sets, and the current argument will
// tell us with image in that list we're currently
// working with. First, we hide the last displayed
// image.
imgs.sets[self.id][current].style.display = 'none';
// Increment to get the next image.
current++;
// If we're at the end, let's move back to the
// beginning of the list.
if (current >= imgs.sets[self.id].length) {
current = 0;
}
// This skips images which had an error on load. The
// test for this in the markup above is the third image
// in rotator1, which is not an image url.
if (imgs.sets[self.id][current].imageerror == true) {
// See how I'm passing self using .call()? This sets
// the context for the next animateSlideshow() call,
// which allows this/self to work on the correct div
// container.
animateSlideshow.call(self, current);
return;
}
imgs.sets[self.id][current].style.display = 'inline';
// Everything is organized by the self.id key, event
// saving the references to the timeouts.
timeouts[self.id] = setTimeout(function(){
animateSlideshow.call(self, current);
}, 100);
};
function getImages(){
var list = document.images,
img,
data = {sets: {}, allimages: []},
parent;
// document.images gives me an array of references to all
// img elements on the page. Let's loop through and create
// an array of the relevant img elements, keying/grouping on the
// parent element's id attribute.
for (var i = 0, l = list.length; i < l; i++){
img = list[i];
parent = img.parentNode;
// parent should now be a reference to the containing div
// for the current img element. parent.id should give us
// rotator1 or rotator2 in the demo markup.
if (parent.className.indexOf('rotation') !== -1) {
if (!data.sets[parent.id]) {
data.sets[parent.id] = [];
}
// Let's put the img reference into the appropriate
// imgs.sets. I also put the img.src into an index
// container in data.allimages; this is also a remnant
// of a previous approach I took. It could probably be
// removed unless you need it.
data.sets[parent.id].push(img);
data.allimages.push(img.src);
}
}
return data;
}
function initializeSlideshows(){
imgs = getImages();
preloadImages(imgs.sets);
}
initializeSlideshows();
};
$.onDomReady(slideshows);
http://jsfiddle.net/DLz92/1