Changing image onclick then changing it back in js - javascript

fiddle:
https://jsfiddle.net/0r7v923u/2/
<img src="https://dirask.com/static/bucket/1631898942509-VMYrnXyYZv--image.png" class="logo" alt="Banner" onclick="ratesD(this)" />
JS:
function ratesD(image) {
if (img.attr('src') == "https://dirask.com/static/bucket/1631898942509-VMYrnXyYZv--image.png") {
image.src = "https://dirask.com/static/bucket/1633375165831-yjQ7G6WQeL--image.png";
} else {
image.src = "https://dirask.com/static/bucket/1631898942509-VMYrnXyYZv--image.png"
}
}
I am simply trying to change the image back and forth on click. The function below changes it but it does not return to the previous image:
function ratesD(image) {
image.src = 'https://dirask.com/static/bucket/1633375165831-yjQ7G6WQeL--image.png';
}
I thought it only needs to change using img.attr('src') == what do I need to change for the if condition?

First you are trying to access the wrong property of the image object (attr instead of src) and the second function is not checking the current image source before changing it. To fix this, the function should check the current src of the image and change it to the other URL depending on its value. Try this.
function ratesD(image) {
if (image.src == "https://dirask.com/static/bucket/1631898942509-VMYrnXyYZv--image.png") {
image.src = "https://dirask.com/static/bucket/1633375165831-yjQ7G6WQeL--image.png";
} else {
image.src = "https://dirask.com/static/bucket/1631898942509-VMYrnXyYZv--image.png"
}
}
<img src="https://dirask.com/static/bucket/1631898942509-VMYrnXyYZv--image.png" class="logo" alt="Banner" onclick="ratesD(this)" />

It's a bad idea to force load/unload your images (even if they are in the system cache) every time you click on them.
Load them only once, and switch their display at each click.
const bannerImgs = document.querySelector('#banner-images');
bannerImgs.onclick =_=> bannerImgs.classList.toggle('seeOther');
#banner-images > img {
width : 100px;
height : 100px;
}
#banner-images.seeOther > img:first-of-type,
#banner-images:not(.seeOther) > img:last-of-type {
display : none;
}
<div id="banner-images" >
<img src="https://dirask.com/static/bucket/1631898942509-VMYrnXyYZv--image.png" alt="Banner" >
<img src="https://dirask.com/static/bucket/1633375165831-yjQ7G6WQeL--image.png" alt="Banner" >
</div>

Related

How i can switch between icons with javascript when clicked?

How can I switch between icons with javascript when clicked?
function mode() {
var moon = document.getElementById("mode");
moon.src = "https://img.icons8.com/sf-black-filled/35/fffffe/moon-symbol.png";
moon.id = "lightmode";
moon.onclick = lightmode();
}
function lightmode() {
var sun = document.getElementById("lightmode");
sun.src = "https://img.icons8.com/sf-black-filled/34/000000/sun.png";
sun.onclick = mode();
}
body { background-color:grey }
<div class="nav-icons">
<img id="mode" class="moon" onclick="mode()" src="https://img.icons8.com/sf-black-filled/35/fffffe/moon-symbol.png">
<img id="notification" src="https://img.icons8.com/ios-glyphs/34/fffffe/notification-center.png" alt="" srcset="">
</div>
You are setting up event listeners in an incorrect manner
Here is a toggle using classes and data attributes
const srcs = {
"dark": "https://img.icons8.com/sf-black-filled/35/fffffe/moon-symbol.png",
"light": "https://img.icons8.com/sf-black-filled/34/000000/sun.png"
};
const modeToggle = document.getElementById("modeToggle");
modeToggle.addEventListener("click", function() {
let mode = this.dataset.mode;
mode = mode === "dark" ? "light" : "dark"; // toggle
this.src = srcs[mode]; // image
this.dataset.mode = mode; // save in element
document.body.classList.toggle("dark",mode==="dark"); // toggle page too
})
document.body.classList.toggle("dark",modeToggle.dataset.mode==="dark"); // initialise the page, possibly from localStorage
body {
background-color: grey
}
body.dark {
background-color: black;
}
<div class="nav-icons">
<img id="modeToggle" data-mode="light" src="https://img.icons8.com/sf-black-filled/34/000000/sun.png">
<img id="notification" src="https://img.icons8.com/ios-glyphs/34/fffffe/notification-center.png" alt="" srcset="">
</div>
this may solve your problem, please use proper names for your functions, e.g instead of mode() use changeMode() as a name
javascript:
let isChanged = false;
let mode = document.querySelector('#mode');
function changeMode(){
isChanged = !isChanged;
if(isChanged) {
mode.src = "https://img.icon8.com/sf-black-filled/35/ffffffe/moon-symbol.png"
} else {
mode.src = "https://img.icon8.com/sf-black-filled/34/000000/sun.png"
}
}
Toggling between two different images/icons/styles is very simple in Javascript. You could, for instance, create a simple Object literal with name/value pairs for both icons as per the following. A simple ternary operator determines what the src should be based upon the current src
document.querySelector('.nav-icons > img.sunmoon').addEventListener('click',function(e){
let icons={
sun:'https://img.icons8.com/sf-black-filled/34/000000/sun.png',
moon:'https://img.icons8.com/sf-black-filled/35/fffffe/moon-symbol.png'
};
this.src = this.src==icons.moon ? icons.sun : icons.moon;
});
body {
background-color: grey
}
<div class="nav-icons">
<img class="sunmoon" src="https://img.icons8.com/sf-black-filled/35/fffffe/moon-symbol.png" />
<img id="notification" src="https://img.icons8.com/ios-glyphs/34/fffffe/notification-center.png" alt="" srcset="" />
</div>

Trying to switch images using a toggle button in vanilla JS

I'm not quite sure why my code isn't working at this point. I am trying to make an Instagram like button. I have an image of a black heart and when double clicked on I want to switch it to another image of a red heart. I've dug around here and there but couldn't quite pin point the problem. The code snippet works but it does not work when I run it in my project.
const button = document.querySelector('#like');
document.querySelector('button').addEventListener('dblclick', (e) => {
if (button.src == "https://www.w3schools.com/html/img_chania.jpg") {
button.src = "https://www.w3schools.com/html/pic_trulli.jpg";
} else {
button.src = "https://www.w3schools.com/html/img_chania.jpg";
}
});
.under-image-nav button {
border: none;
width: 30px;
}
<nav class="under-image-nav">
<button><img id="like" src="https://www.w3schools.com/html/img_chania.jpg" alt="like button"> </button>
</nav>
I got rid of the button and simply allowed javascript to control the source of the image.
To shorten the code, I used a ternary operator
let heartEl = document.querySelector(".heart");
const fullHeart = 'https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Ffrogermcs.github.io%2Fimages%2F6%2Fheart_red.png&f=1&nofb=1"'
const emptyHeart = 'https://freeiconshop.com/wp-content/uploads/edd/heart-outline.png'
heartEl.addEventListener("dblclick", () => {
heartEl.src == emptyHeart ? heartEl.src = fullHeart : heartEl.src = emptyHeart
});
<img class='heart' src='https://freeiconshop.com/wp-content/uploads/edd/heart-outline.png'>
You should attach the event listener to the button instead.
const img = document.querySelector('#like');
document.querySelector('button').addEventListener('dblclick', (e) => {
if (img.src == "https://www.w3schools.com/html/pic_trulli.jpg") {
img.src = "https://www.w3schools.com/html/img_chania.jpg";
} else {
img.src = "https://www.w3schools.com/html/pic_trulli.jpg";
}
});
<button><img id="like" src="https://www.w3schools.com/html/pic_trulli.jpg" alt="like button" width="100" height="100"></button>

How to hide image when dynamically change src attribute in angular

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;
}

Execute code after rendering all images in vuejs

I want to do some code execution after all images are loaded (need the set scroll in a specific position). I use nextTik() but Codes are processed before loading images . We also can't use mounted and created and methods like this because codes should be executed after clicking on a button.
is there any method or trick?
thanks
You can use the load event on each image to check if all images have been loaded.
example: https://jsfiddle.net/jacobgoh101/e5bd86k6/1/
<div id="app">
<img #load="handleLoad" #error="handleLoad" v-for="i in 10" :src="`https://picsum.photos/${Math.random()*300}/700/?random`"/>
</div>
Javascript
new Vue({
el: "#app",
data: {
imgLoaded: 0
},
methods: {
handleLoad: function(todo){
this.imgLoaded++;
if(this.imgLoaded === 10) {
alert('all image loaded')
}
}
}
})
Based on ( https://stackoverflow.com/a/50481269 enter link description here) answer I did something like this:
<img class="card-img-top" :src=" 'images/' + (data.src || 'image-default.png') "
:alt="data.alt" #load="handleImagesLoad" #error="handleImagesLoad">
(#load and #error on each image on my page) and
handleImagesLoad: function($event){
var images = $('img:not([loaded])');
var target = $($event.target);
$(target).attr('loaded', true);
if(images.length <= 1){
$('#preloader').fadeOut();
}
},
Here is my approach for a component having both "static" images and an an arbitray number of images fetched from database :
Append two items to the component data: 'imgsLength' and 'loadedImgsLength'
Append a 'load' event handler to every img element, that increments 'loadedImgsLength'
After all fetched data are loaded, set 'imgsLength' to the number of all img elements
So, you know that all images are loaded when 'loadedImgsLength' > 0 and 'loadedImgsLength' == 'imgsLength'
In this exemple, my component won't be visible until all images are loaded:
<template>
<div v-show="ready" ref="myComponent">
...
<img src="..." #load="loadedImgsLength++" /> (static image)
...
<img v-for="img in fetchedImg" #load="loadedImgsLength++" /> (dynamic images)
</div>
</template>
<script>
...
data(){
return {
...,
imgsLength : 0,
loadedImgsLength: 0,
...,
}
},
computed: {
ready(){
return (this.loadedImgsLength > 0 && this.loadedImgsLength == this.imgsLength)
}
},
async created(){
... fetch all data
this.$nextTick(() => this.$nextTick(this.imgsLength = this.$refs.myComponent.getElementsByTagName("img").length))
}

Vue js - Set alt image when image source not found

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 ''
}
}
},

Categories

Resources