I am trying to Exchange the src of an Image tag on a click Event, the Image src is a png file, but if I click on the Image the source shall Change to a give file.
<img src="images/eye.png" alt="Logo"
id="sidebar-collapse img-logo-main-page"
width="80">
And this is the JavaScript, I get the console Output in the console but Nothing changes:
const gifEgg = {
elements: {
logo: $('#img-logo-main-page'),
logoOverlay: $('#sidebar-image-collapse')
},
addGif () {
this.elements.logoOverlay.click(() => {
console.log("clicked");
this.elements.logo.attr('src', '../images/eyes_move.gif');
});
}
};
gifEgg.addGif();
The problem is that you are treating an id like a class. You gave the image an id of sidebar-collapse img-logo-main-page, but are trying to refer to it with #img-logo-main-page. An element can only have one id, but can have many classes. If you gave it a class name of sidebar-collapse img-logo-main-page, you could refer to it with .img-logo-main-page (any one or more of its classes), but an id must be unique and each element can only have one id.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg?auto=compress&cs=tinysrgb&h=350" alt="Logo"
id="img-logo-main-page"
width="80">
<button id="sidebar-image-collapse">
Change Image Source
</button>
<script>
const gifEgg = {
elements: {
logo: $('#img-logo-main-page'),
logoOverlay: $('#sidebar-image-collapse')
},
addGif () {
this.elements.logoOverlay.click(() => {
console.log("clicked");
this.elements.logo.prop('src', 'http://2.bp.blogspot.com/-3jbHdEj7o2k/Uk6zNIfJkqI/AAAAAAAAB5s/zf7UzbSkp80/s200/zrikh+ajig.gif');
});
}
};
gifEgg.addGif();
</script>
Related
I have this simple app where I am showing images and also can add more. So when I add an image I show a spinner while it loads and then hide the spinner when its done loading. But the issue is when I'm adding the second image, the spinner doesn't show up. This is because of the boolean I'm using and I think it is being used globally.
Please note that I add an image through image url and rendering it with img html tag of course. I'm using RactiveJS and I feel like there is something I can do with an unique identifier but just dont know how. All the images have unique id attached to its data.
Here's the Ractive code:
let isImageLoaded = false;
const ractive = new Ractive({
el: '#container',
template: `
{{#each images}}
<div class="container">
{{#if !isImageLoaded}}
<span class="spinner"></span>
{{/if}}
<img
alt=""
src="{{url}}"
on-load="imageLoaded"
style="display: {{isImageLoaded ? 'block' : 'none'}};"
/>
</div>
{{/each}}
`,
data: {
images: [
{ id: 1, url: 'https://www.some-image.com/image1.jpg' },
],
isImageLoaded : isImageLoaded
}
});
ractive.on('imageLoaded', function(e) {
ractive.set('isImageLoaded', true);
});
function addImage(image) {
const allImages = ractive.get('images');
allImages.push(images);
ractive.set('isImageLoaded', false);
ractive.set('images', allImages);
}
If I set isImageLoaded to false in addImage function then adding a new image makes all the other spinners to show up.
How can I use ids to make each image and spinner unique and show spinner only when adding a new image?
I recycled a lot of code from an old JS project I made back in the very beginning of my learning process, and back then I knew nothing about DOM events. Specifically in this case, onload. What I am looking for is someway to only let the website begin to run once all images have loaded, without putting everything into one big onload function, or rewriting all my code. Is there anyway to do this?
<img src="placeholder.png" onload="continue()" width="100" height="100">
<script>
function continue() {
//This is where I am stuck
}
</script>
The simplest solution would be to set the display property of the body to none when the page is loading, and then have continue() make it visible.
CSS:
body {
display: none;
}
JS:
function continue() {
document.body.style.display = "";
}
If the images aren't going to be dynamically added to DOM you can simply just do the followingaIf the images aren't going to be dynamically added to DOM you can simply just do the following
<html>
<body style="display: none;">
<img src="https://via.placeholder.com/100" alt="">
<img src="https://via.placeholder.com/200" alt="">
<img src="https://via.placeholder.com/300" alt="">
<script>
const imageCollection = Array.from(document.getElementsByTagName('img'));
const promisifier = (imageNode) => {
return new Promise((resolve, reject) => {
imageNode.addEventListener("load", () => {
console.log('image loaded', imageNode);
resolve('Loaded')
});
})
}
Promise.all(imageCollection.map(img => promisifier(img))).then((resp)=>{
document.body.style.display = 'block';
console.log('All images completed Loading');
})
</script>
</body>
</html>
If images are going to be dynamically added you could go for Mutation Observer, let me know if thats the case will add that too.
Is there a way to hide or remove image while loading a new one, when changing src tag value.
Example code:
<img [src]="dynamicPath">
<button (click)="changeSrc()">Change Image Src</button>
In component:
dynamicPath = 'somePath.jpg';
changeSrc(){
this.dynamicPath = 'newPath.jpg';
}
The problem with this code is that after clicking the button, old image is still showing until new image has completely loaded, which is undesired.
Is there a way to remove it or show a hint that new image is being loaded?
Note that: my case doesn't allow solution of preloading many images at once.
You can remove the image from the DOM using *ngIf as below,
<img *ngIf="dynamicPath!=''" [src]="dynamicPath">
<button (click)="changeSrc()">Change Image Src</button>
you can set the variable to empty string ' ' as below
dynamicPath = 'somePath.jpg';
changeSrc(){
this.dynamicPath ='';
this.dynamicPath = 'newPath.jpg';
}
Just hookup the load event of the image.
html
<img [src]="dynamicPath" (load)="onload()" *ngIf="loadingImg">
<button (click)="changeSrc()">Change Image Src</button>
ts
loadingImg = true;
dynamicPath = 'somePath.jpg';
changeSrc(){
this.loadingImg = true;
this.dynamicPath = 'newPath.jpg';
}
onload() {
this.loadingImg = false;
}
you can use *ngIf in the img tag.
<img *ngIf="!loading" [src]="Path">
<button (click)="changeSrc()">Change Image Src</button>
Then you can make decision in the component.
Path = 'somePath.jpg';
loading=false;
changeSrc(){
this.loading =true;
this.Path = 'newPath.jpg';
this.loading =false;
}
I am working on a site which has a list of products. Each product has a corresponding image. I am binding the image url to the source attribute like below.
<img :src="product.ImageUrl"/>
If the image is not found, I want to show a default image.
I do as below in cshtml razor syntax (for reference only)
onerror='this.onerror = null;this.src = "#Url.Content("~/images/photo-not-available.jpg")";'
How do I achieve the same in Vue?
You can set an onerror handler function with #error in Vue:
<img :src="" #error="aVueFunctionThatChangesTheSrc">
Since in pure js put onerror inline like this
<img :src="ImgUrl" onerror="this.src='http://example.com/default.jpg'"/>
for vue.js we can replace it
<img :src="ImgUrl" #error="$event.target.src='http://example.com/default.jpg'"/>
I found that changing the src in the #error function kicked off a horrible endless loop of updates, causing a flickering screen etc. My solution so far is:
<span v-if="props.column.field === 'avatar'">
<span v-if="props.row.avatar">
<img alt="avatar" class="round-32" :src="`${props.row.avatar}`" #error="(() => props.row.avatar = null)"/>
</span>
<span v-else>
<img alt="avatar" class="round-32" src="../../../assets/images/avatar-2.jpg"/>
</span>
</span>
I have try to using #error but it doesn't work because in my case, the image was not found, so I try this one, and its work.
<img :src="getImgUrl(filename)">
methods: {
getImgUrl(filename){
try{
return require(`#/assets/${filename}`)
}catch(_){
return require(`#/assets/default.png`)
}
},
}
I ended up with a directive to set a fallback image and prevent the loop:
image-src-fallback.js
const setSrc = (evt) => {
const el = evt.currentTarget;
el.setAttribute("src", el.fallback);
el.fallback = "";
el.removeEventListener("error", _listener);
};
const _listener = (evt) => setSrc(evt);
export default {
bind(el, binding) {
el.fallback = binding.value;
el.addEventListener("error", _listener);
},
unbind(el) {
el.removeEventListener("error", _listener);
},
};
Global import
import imageSrcFallback from "./directives/image-src-fallback.js";
Vue.directive("src-fallback", imageSrcFallback);
Use
<img
v-src-fallback="user.avatar_fallback_url"
:src="user.avatar_url"
/>
Sometimes you can create a method, for example in my case some images are not found because clients have not uploaded images, then you can create a method for it: you can return any value as an image or simple '' for any image.
<div class="flex-shrink-0">
<img
class="h-72 w-full object-cover"
:src="showFirstImageGallery(p.project_images)"
/>
</div>
methods: {
showFirstImageGallery(v){
if (v.length > 1) {
return v[1].img_url
} else {
return ''
}
}
},
I'm trying to add a mute/un-mute button to my website. I created a panoramic tour using a program called Panotour by Kolor. Thing is I exported it as HTML but can't seem to find the audio tags or anything. I found the file which contains the audio files, I just need a way to mute the music.
.
Here's what I'v done so far.
<div>
<img class="img-responsive" src="Images/muteon.png" id="mute" onclick="toggleSound(this);">
</div>
<script>
function toggleSound(img)
{
if(img.src.match(/blank/))
{
console.log('black');
img.src = "Images/muteon.png";
}
else
{
console.log('blank');
img.src = "Images/muteoff.png";
}
}
</script>