Changing img source onmouseover using only javascript and 'this' - javascript

Trying to change img src attribute to src matching another picture on site which user hovered over. I have 1 (main) picture and I have 3 below it (sub), acting as a gallery. When user hovers over one of those 3, I want src attribute of main to change to src of sub image.
All resolutions I found so far, use either 1 image whose source is changed in code or only specific sources declared but I don't want to add sources in code every time a new image is added, instead, using i.e. gallery(this) for each sub-image should resolve it but I'm having no luck so far.
Apologies if there is same question, I just couldn't find it. If this explanation is too complicated, feel free to ask, I'm looking forward resolving this, if possible.
Tried to use function name(this) to exploit source of image and add it to main picture.
I'm really just starting with all of this so this what I tried so far probably isn't even close enough, hope you will understand.
<img class="hover" src="imgs/mountain.jpg" id="hover" alt="">
<div class="imgs">
<img onmouseover="gallery(this)" src="imgs/castle.jpg" alt="">
<img onmouseover="gallery(this)" src="imgs/mountain.jpg" alt="">
<img onmouseover="gallery(this)" src="imgs/tree.jpg" alt="">
</div>
<script>
function gallery(element) {
x = document.getElementById('hover');
x.src.element;
}
</script>

You aren't actually changing the src. You can do so by setting x.src to element.src:
function gallery(element) {
x = document.getElementById('hover');
x.src = element.src;
}
<div class="imgs">
<img onmouseover="gallery(this)" src="https://picsum.photos/100?random=1" alt="">
<img onmouseover="gallery(this)" src="https://picsum.photos/100?random=2" alt="">
<img onmouseover="gallery(this)" src="https://picsum.photos/100?random=3" alt="">
</div>
<img id="hover" alt="hover">

As Kobe states in their answer, to set the src you can use img.src = {source}.
I would recommend that you add event listeners to each image, rather than using attributes to call the function. This provides a much cleaner solution. I have added the .gallery class to each image, then, it loops through these elements adding the event listener.
function displayImage() {
x.src = this.src;
}
// Pull this out of the function to avoid the lookup every time
var x = document.getElementById('hover');
// Loop through each element with the gallery class and add the event listener
document.querySelectorAll(".gallery").forEach(function(img) {
img.addEventListener("mouseover", displayImage);
});
<div class="imgs">
<img class="gallery" src="https://picsum.photos/100?random=1" alt="">
<img class="gallery" src="https://picsum.photos/100?random=2" alt="">
<img class="gallery" src="https://picsum.photos/100?random=3" alt="">
</div>
<img id="hover" alt="hover">

Related

How to change same images at multiple places using JS?

I want to know the solution that will help me change multiple same images using JS.
For example: There are 3 image tags below.
<img class="photo" src="myphoto.png">
<img class="photo" src="myphoto.png">
<img class="photo" src="myphoto.png">
And I want to change all the "myphoto.png" to "theirphoto.png" at once without change in every line.
You can get all of the elements with document.querySelectorAll and loop over them to change each src.
document.querySelectorAll('img.photo').forEach(img => img.src = 'theirphoto.png');

Is there a way to hide an "Image not found" error icon without "this.style.display = 'none'"

I'm trying to have multiple image boxes in a span, with no pre-determined src. This is for a basic game of blackjack as a task I have set myself to do in JavaScript.
Currently, here is my HTML code for the span of image boxes.
This site is not being hosted, I'm running it via my browser; no JQuery
<span> <!-- Players Cards -->
<img class='imagebox' id='imagebox1' src=''></img>
<img class='imagebox' id='imagebox2' src=''></img>
<img class='imagebox' id='imagebox3' src=''></img>
<img class='imagebox' id='imagebox4' src=''></img>
</span>
In my JavaScript file, after a card has been selected, I use interpolation to get an image. It will be dealt by changing image.src as shown:
function deal(box) {
let card = randomcard()
const image = document.getElementById(`imagebox${box}`)
if (image.src !== card) {
image.src = `cardpng/${card}`
}else {
redeal()
}
}
My issue is that, since no src has been defined for each image box, until it has been assigned a src, it will have an "image not found" icon, which for aesthetic purposes I'd like to remove.
I tried:
<img class='imagebox' id='imagebox1' onerror='this.style.display = "none"' src=''></img>
However, in doing so, this.style.display remains as "none", even after a src is defined and there should be no error.
I understand I could just write a function once a card has been dealt to change it back, however I'm looking for something prettier which will be easier and less communication between HTML and JS.
Thanks in advance for replies.
Use CSS
img[src=""] {
display: none;
}
Like this -
setTimeout(() => document.getElementById('imagebox1').src = "image.jpg", 2000)
img[src=""] {
display: none;
}
<span> <!-- Players Cards -->
<img class='imagebox' id='imagebox1' src=''/>
<img class='imagebox' id='imagebox2' src=''/>
<img class='imagebox' id='imagebox3' src=''/>
<img class='imagebox' id='imagebox4' src=''/>
</span>
However - are you sure you're seeing an image not found icon?? I don't see any here
<span> <!-- Players Cards -->
<img class='imagebox' id='imagebox1' src=''/>
<img class='imagebox' id='imagebox2' src=''/>
<img class='imagebox' id='imagebox3' src=''/>
<img class='imagebox' id='imagebox4' src=''/>
</span>
note: img does not have a closing tag - it's either <img ...../> or <img .....> with no </img>
A solution that would work even for actually broken images, and not just for the ones you haven't set their src yet, is to set the alt attribute to the empty string:
<section>
<p>With <code>alt=""</code></p>
<img alt="">
<img alt="" src="">
<img alt="" src="https://example.com/broken-image.jpg">
<img alt="" src="https://www.fillmurray.com/50/50">
</section>
<section>
<p>Without</p>
<img>
<img src="">
<img src="https://example.com/broken-image.jpg">
<img src="https://www.fillmurray.com/50/50">
</section>
However beware that with this solution your images are converted to empty text nodes for the renderer, which don't take any space, but which make the neighbor white spaces get rendered. So for instance in the above example, the new lines between each <img> tags are visible as a single space text node in the rendered page, just like they are when the images are rendered.
However this is an issue only when the images are presented inline like here.

Array of img.click() functions

I have two images, image_0 and image_1, and when each is clicked, I want it to display an alert saying the id of that image. To do this, I have created an array to store these functions (this was necessary because of my previous issue: https://stackoverflow.com/questions/41003122/looping-in-jquery-only-remembers-last-iteration?noredirect=1#comment69215730_41003122).
The code below shows my attempt. However, nothing happens when I click either image. Why?
HTML:
<img id="image_0" src="http://placehold.it/350x150" width="300">
<img id="image_1" src="http://placehold.it/350x150" width="300">
Javascript:
$(document).ready(function()
{
// The number of images shown
num_images = 2
// List of functions for each thumbnail click.
var image_click_functions = new Array(num_images);
// Define the function for when the thumbnail is clicked
function CreateImageClickFunction(image_id)
{
return function() { alert(image_id) };
}
// Loop through all images, and define the click functions
for (i = 0; i < num_images; i++)
{
image_click_functions[i] = CreateImageClickFunction(i);
image_id = "#image_" + i;
$(image_id).click(function()
{
image_click_functions[i];
});
}
});
Add a common class, create one handler, and use an instance of this
<img class="image" id="image_0" src="http://placehold.it/350x150" width="300">
<img class="image" id="image_1" src="http://placehold.it/350x150" width="300">
JS:
$(".image").click(function() { alert(this.id) });
Why do you need to write it so complex?
you could very easily do:
$('img').click(function(){
alert($(this).attr('id'));
}
(this actually creates a different listener for each one)
or you could use on like this:
$(document).on('click','img',function(){
alert($(this).attr('id'));
})
that has the advantages of:
a. using only one event listener
b. works on dynamically created content (if you add more images using ajax for example, this event listener will still work on the new images)
I think you over-complicate this.
Have a look on this example:
html:
$("#container").on("click", "img", function(e){
console.log($(this).attr("id"));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<img id="image_0" src="http://placehold.it/350x150" width="300">
<img id="image_1" src="http://placehold.it/350x150" width="300">
</div>
example:
http://codepen.io/xszaboj/pen/PbeypX?editors=1010
As CreateImageClickFunction(image_id) is returning a function, You just need to pass the function as event handler.
$(image_id).click(image_click_functions[i]);
Alternatively. as per existing HTML you can use Attribute Starts With Selector [name^=”value”] to bind event
$('[id^image_]').click(function(){
//Extract number from ID
var idNum = this.id.match(/\d+$/)[0];
})
If you need to store some arbitrary data I would recommend you to use data-* prefixed custom attribute, which can be fetched using $.fn.data() method or HTMLElement.dataset property
<img class="image" data-id="0" src="http://placehold.it/350x150" width="300">
<img class="image" data-id="1" src="http://placehold.it/350x150" width="300">
Script
$(parentContainerSelector).on('click','.image',function(){
console.log(this.dataset.id);
})
I think you've overcomplicated by not understanding Closures in your original question. This is a more advanced "feature" in JS, but worth taking time to research and understand.
However, a much simpler way to do this in jQuery, is to use the images as a selector, and iterate over them that way. Then you can access this as the image. Here's example code.

JS : Getting image id using onmouseover

i have 4 images in my document , 1 at the top and three at the bottom now what i want when i hover over any of the bottom 3 images i get its id and replace the above image with this image using onmouseover , like this
<script >
function chanageimg(id)// here i want to pass hovered image src
{
document.getElementById("top_image").src=id;
}
</script>
<div id="top" >
<img src="top.jpg" id="top_image" />
</div>
//here is the bottom image ,
<div class ="floats one">
<img src="img1.jpg" id="img1" onmouseover="changeimg()" />
</div>
how do i get its src to be passed in aboce function . i dont want to use Jquery . here as its for learning purpose
One small change to your HTML:
<img src="img1.jpg" id="img1" onmouseover="changeimg(this.id)" />
this is the image being moused over, and this.id is the parameter you want to pass to your function.
Inside the function changeimg(e), use e.target.id to get the id. If you do this, you don't need to add this.id to every onmouseover="" in your images. Just use onmouseover="changeimg".
To change the image you have to change the src
<img id="img-top" src="">
<img src="img1.jpg" onmouseover="changeimg(this.src)">
function changeimg(src){
document.getElementById("top_image").src = src;
}
EXAMPLE

Highslide gallery with two different thumbnails

I'm trying to make a gallery with highslide.
I have two thumbnails, a larger but cropped one listed on the page opening the large image if clicked on, and a smaller one with varying aspect ratio for the thumbstrip.
How do I configure highslide to actually use different images for the thumbstrip?
For example this is a part of the markup:
<a href="highslide/sample-images/picture12.jpg" class="highslide"
title="Caption from the anchor's title attribute"
onclick="return hs.expand(this, config1 )">
<img src="highslide/sample-images/picture12.thumb.jpg" alt=""/>
</a>
The link is pointing to the large picture, the img is showing the cropped thumbnail.
Can I override a function for example to use two thumbnails like:
<a href="highslide/sample-images/picture12.jpg" class="highslide"
title="Caption from the anchor's title attribute"
onclick="return hs.expand(this, config1 )">
<img class="thumb" src="highslide/sample-images/picture12.thumb.jpg" alt=""/>
<img class="strip" src="highslide/sample-images/picture12.strip.jpg" style="display: none" alt="" />
</a>
Actually I found a solution to this some time ago:
On the highslide api reference http://highslide.com/ref/ there is a function stripItemFormatter. The parameter of the function is the element you expand (the element).
the string returned by this function will be parsed as html, and used as an item of the thumbstrip.
If you check this example: http://highslide.com/ref/hs.stripItemFormatter you can see how it's done.

Categories