Switch out image sources with jQuery when clicked

I'm in the process of designing a basic product page for my website.

HTML:

<div class="product-image">
    <div class="product-large-image">
        <img src="http://demo4coder.com/gosmart/pub/media/catalog/product/cache/image/600x600/e9c3970ab036de70892d86c6d221abfe/v/e/venus100_shoes3.jpg" alt="Product Title" id="large-image"></div>
    <div class="product-small-image">
        <img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008769.jpg" alt="Product Title" id="small-image"></div>
    <div class="product-small-image">
        <img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008754.jpg" alt="Product Title" id="small-image"></div>
    <div class="product-small-image">
        <img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008769.jpg" alt="Product Title" id="small-image"></div>
    <div class="product-small-image">
        <img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008754.jpg" alt="Product Title" id="small-image"></div>
</div>

CSS:

.product-large-image {
    width: 100%;
    border: 2px solid #ffac00;
    text-align: center;
    display: inline-block;
}
.product-large-image img {
    width: 90%;
}
.product-small-image {
    width: 19.38%;
    border: 2px solid #ffac00;
    margin-bottom: 5px;
    display: inline-block;
    text-align: center;
    cursor: pointer;
}
.product-small-image img{
    width: 90%;
}

I am looking to update the src attribute of the main image with the src attribute of the clicked small image.

JS (jquery):

$('#small-image').click(function(){
    var imgsrc= $(this).attr('src');
    $('#large-image').attr('src', imgsrc);
});

Currently, this only works when clicking on the first small image. I want it to work with any of the small images that are clicked.

You can view a live example of my code here:
https://jsfiddle.net/MohamedMehanny/dsahrLvn/2/

Answer №1

the functionality currently only works on the first image, but I want it to work on any clicked image, not just the first one.

Recommendation: Use classes instead of IDs

<img src="#" class="small-image" />

$('.small-image').click(function(){
  var imgsrc=$(this).attr('src');
  $('#large-image').attr('src',imgsrc);
});

Answer №2

It is essential that the id attribute remains unique:

The id attribute, a global attribute, serves to uniquely identify an element within the entire document. This unique identifier is crucial for purposes such as linking (using fragment identifiers), scripting, or styling with CSS.1

An alternative method involves using a class attribute in place of the id for smaller images.

For example, instead of an image tag like this:

<img id="small-image" src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008754.jpg" alt="Product Title">

You would use a class attribute as follows:

<img class="small-image" src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008754.jpg" alt="Product Title">

To select these images and set up a click handler, utilize the css class selector:

$('.small-image').click(function(){...});

Below is a demonstration:

$('.small-image').click(function() {
  var imgsrc = $(this).attr('src');
  $('#large-image').attr('src', imgsrc);
});
.product-large-image {
  width: 100%;
  border: 2px solid #ffac00;
  text-align: center;
  display: inline-block;
  margin-bottom: 5px;
}

.product-large-image img {
  width: 90%;
}

.product-small-image {
  width: 19.38%;
  border: 2px solid #ffac00;
  margin-bottom: 5px;
  display: inline-block;
  text-align: center;
  cursor: pointer;
}

.product-small-image img {
  width: 90%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product-image">
  <div class="product-large-image"><img src="http://demo4coder.com/gosmart/pub/media/catalog/product/cache/image/600x600/e9c3970ab036de70892d86c6d221abfe/v/e/venus100_shoes3.jpg" alt="Product Title" id="large-image"></div>
  <div class="product-small-image"><img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008769.jpg" alt="Product Title" class="small-image"></div>
  <div class="product-small-image"><img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008754.jpg" alt="Product Title" class="small-image"></div>
  <div class="product-small-image"><img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008769.jpg" alt="Product Title" class="small-image"></div>
  <div class="product-small-image"><img src="https://cf2.s3.souqcdn.com/item/2015/10/13/92/68/92/8/item_XL_9268928_10008754.jpg" alt="Product Title" class="small-image"></div>
</div>


1https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id

Answer №3

The problem lies in the way you are selecting elements. By using IDs, you are restricting each element to appear only once on a page.

To follow best practices, consider using JS-prefixed classes to better separate concerns. For example, you could use .js-small-img or .js-lg-img in your case.

If you continue to experience difficulties, please feel free to reach out!

Answer №4

$('.image-thumbnail').click(function() {
  var imgsrc = $(this).attr('src');
  $('#main-image').attr('src', imgsrc);
});
.large-image-container {
  width: 100%;
  border: 2px solid #ffac00;
  text-align: center;
  display: inline-block;
  margin-bottom: 5px;
}

.large-image-container img {
  width: 90%;
}

.image-thumbnail {
  width: 19.38%;
  border: 2px solid #ffac00;
  margin-bottom: 5px;
  display: inline-block;
  text-align: center;
  cursor: pointer;
}

.image-thumbnail img {
  width: 90%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-gallery">
  <div class="large-image-container"><img src="http://example.com/large_image.jpg" alt="Product Title" id="main-image"></div>
  <div class="image-thumbnail"><img src="http://example.com/thumbnail1.jpg" alt="Product Title" class="image-thumbnail"></div>
  <div class="image-thumbnail"><img src="http://example.com/thumbnail2.jpg" alt="Product Title" class="image-thumbnail"></div>
  <div class="image-thumbnail"><img src="http://example.com/thumbnail3.jpg" alt="Product Title" class="image-thumbnail"></div>
  <div class="image-thumbnail"><img src="http://example.com/thumbnail4.jpg" alt="Product Title" class="image-thumbnail"></div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Google Earth or Cesium to display moving shapes on a map

I'm feeling quite puzzled at the moment and could really use some advice. My goal right now is to achieve a Satellite view of a random building, complete with the typical RoadMap/3D effect found on Google Maps: I also want to incorporate three.js to ...

What are the reasons for my HTML page not appearing on the local host within Google App Engine?

Below is the main.py file along with the html file intended to be rendered by the Jinja2 template being utilized: main.py import os import webapp2 import jinja2 from google.appengine.ext import db template_dir = os.path.join(os.path.dirname(__file__), & ...

Perform a string comparison in JavaScript

I'm a bit confused about why this is not working as expected. Below you'll find an example of the .ajaxComplete method that seems to be causing issues. My goal is to compare the URL from which the action originates with the URL where I want the c ...

Printing reports in Angular 9

I have a requirement in my Angular 9 application to generate and print reports. 1. I am looking for suggestions on how to handle printing reports where a user triggers the action by clicking a button, and the report data needs to be fetched from the datab ...

Utilizing TypeScript to Populate an observableArray in KnockoutJS

Is there a way to populate an observableArray in KnockoutJS using TypeScript? My ViewModel is defined as a class. In the absence of TypeScript, I would typically load the data using $.getJSON(); and then map it accordingly. function ViewModel() { var ...

Retrieving information from Controller for Shared View / Layout

With ASP.NET MVC4, I'm building a website that utilizes PartialViews and jQuery to load content. Here's the structure of my main page: <ul> <li id="recent">Recent</li> <li id="home">Home</li> <li id=" ...

Tips for optimizing your animation using ReactCSSTransitionGroup

I'm currently working on integrating the "bounce" animation feature from animate.css into a React component. Here's the CSS I've set up so far: // Animation Bounce @-webkit-keyframes bounce { from, 20%, 53%, 80%, to { -webkit-animat ...

Tips for arranging Radio buttons in multiple columns within the same Radio group in Material UI

As a newcomer in the world of React.js, I am feeling a bit anxious about posting my question on Stack Overflow. I hope everyone can overlook my lack of experience and forgive me for any mistakes. I have been struggling to find the right solution to my prob ...

React build completion reveals a blank canvas of pure white

When I run npm start, my React app works perfectly fine. However, when I run npm run build, it just displays a white screen. I've tried troubleshooting it without any success. Even though there are similar questions out there, none of the solutions se ...

Axios continues to encounter the issue of downloading a faulty PDF file

Every time I attempt to download a PDF file to the client side using axios, it ends up corrupted. In my MERN stack webapp, a user can click a button to initiate the download of a PDF file. This button triggers an axios GET request to the Node.js web server ...

How can I efficiently create a suffix using this JavaScript code?

Take note that the code displayed below showcases the array in the console, rather than in the snippet output var names = ["maria", "mary", "marks", "michael"]; function add_suffix(names) { var suffixes = []; for (var i = 0; i < names.length; i+ ...

Looping to run an async process (sequilize.authenticate) multiple times until successful

I need my microservice to wait for the database to become available before proceeding. There is a sidecar Cloud SQL proxy involved that requires some time for the database connection. My current approach involves a for loop that retries connecting after a ...

Tips for updating the value within a textfield in HTML

I am looking to dynamically update the value displayed in my Revenue textfield by subtracting the Cost of Goods from the Sales Price. I have included an image of the current layout for reference, but I want the Revenue field to reflect the updated value af ...

I am having trouble styling a pre-existing class in bootstrap using my custom CSS file

html <section id="title"> <div class="container-fluid"> <!-- Nav Bar --> <nav class="navbar navbar-expand-lg navbar-dark"> <a class=" navbar-brand">tindog</a> ...

Can the URL of a static HTML be altered without modifying the file name?

Is there a method to modify the URL of an HTML file without altering its filename? For example, if my website has a page named 1.html, is it possible to show it as mypagename.html to both visitors and search engine crawlers? ...

Adding new elements to a key in MongoDB ($addToSet)

In my mongoose schema, I have defined a structure like this: var listingSchema = new Schema({ street : String, buildingNumber : Number, apartmentNumber : Number, UsersAndQuestions: [{ userID: { type: ...

Using JQuery-AJAX to add information to the database seamlessly without the need to reload the page

I am working with a dropdown list that contains numbers representing votes. I have successfully implemented functionality to manage these votes using a controller's function along with route-action-template. My query here is, how can I achieve the sam ...

What is the best method for retrieving unique property values from an array?

Help needed with this array manipulation task: var arr = [{id:"1",Name:"Tom"}, {id:"2",Name:"Jon"}, {id:"3",Name:"Tom"}, {id:"4",Name:"Jack"}] I want to extract unique Names from the above array. var result = getUniqueNa ...

Ways to conceal a React component when route transitions occur

I am currently utilizing the location prop from react router dom to set my state to false and only render a component if it's true. Below is an example of how I achieve this in React: const [ showFilter, setShowFilter ] = useState(false); const locati ...

This TypeScript error occurs when the props are not compatible and cannot be assigned to

Hello fellow Internet dwellers! I am a novice in the world of coding and TypeScript, seeking some assistance here. I am attempting to extract an array of objects from props, transform it into a new object with specific information, and then return it - ho ...