Home > Mobile >  How can I change img src from list of (non-image) items?
How can I change img src from list of (non-image) items?

Time:11-22

What I'm trying to do feels like it should be very simple, but I haven't found the right thing.

Say I have something like this:

.list {
  float: left;
  width: 200px;
  height: 500px;
  overflow-y: auto;
}

.show {
  float: right;
  width: 500px;
  height: 500px;
}

.display {
  max-width: 500px;
  max-height: 500px;
  width: auto;
  height: auto;
}
<div class="container" style="width: 700px;">
  <div class="list">
    <li>img1.jpg</li>
    <li>img2.jpg</li>
    <li>img3.gif</li>
    <li>img4.png</li>
  </div>
  <div class="show">
    <img src="img1.jpg" class="display" id="display">
  </div>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

When clicking on the list item on the left, I want the img src on the right to change to the displayed text in the list item (or some equivalent). Bonus points if there are previous and next arrows on the image on the right to continue scrolling through the available images.

Sort of like a lightbox gallery, but instead of using thumbnails, it's clicking on text or a link that creates the full size element, and instead of popping up a lightbox it just changes the existing image on the page.

Ideally I'd like to use vanilla JavaScript, but using jQuery or something isn't out of the question.

CodePudding user response:

Here's a starting point, roughing out the basic idea in vanilla JS:

const list = document.querySelector('.list');
const img = document.querySelector('#display');
const onclick = e => {
  if (e.target.nodeName !== 'LI') return;
  img.src = e.target.textContent;
};

list.addEventListener('click', onclick);

And a working example (I'm also setting the alt text, since the image srces are all broken links)

Show code snippet

const list = document.querySelector('.list');
const img = document.querySelector('#display');
const onclick = e=> {
  if(e.target.nodeName!=='LI') return;
  img.src = e.target.textContent;
  img.alt = e.target.textContent;
};

list.addEventListener('click', onclick)
.list {
  float: left;
  width: 200px;
  height: 500px;
  overflow-y: auto;
}

.show {
  float: right;
  width: 500px;
  height: 500px;
}

.display {
  max-width: 500px;
  max-height: 500px;
  width: auto;
  height: auto;
}
<div class="container" style="width: 700px;">
  <div class="list">
    <li>img1.jpg</li>
    <li>img2.jpg</li>
    <li>img3.gif</li>
    <li>img4.png</li>
  </div>
  <div class="show">
    <img src="img1.jpg" class="display" id="display">
  </div>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You can add JavaScript code on each li element, and sending in the li element itself with "this" in updateImage(this). I'm using a site with placeholder images, so it will look a little bit different.

Show code snippet

function updateImage(liElement) {
  const imgElement = document.querySelector('.show > img');

  // Your code should be something like: "https://www.yourdomain.com/images/"   liElement.textContent
  const imageSrc = `https://picsum.photos/id/${liElement.textContent}/200/200`;
  
  imgElement.src = imageSrc;
}
.container {
  display: flex;
}

.list {
  width: 200px;
  cursor: pointer;
  padding: 0.25rem;
}

.display {
  max-width: 500px;
  max-height: 500px;
}
<div class="container">
  <div class="list">
    <li onclick="updateImage(this)">237</li>
    <li onclick="updateImage(this)">240</li>
    <li onclick="updateImage(this)">100</li>
    <li onclick="updateImage(this)">301</li>
  </div>
  <div class="show">
    <img src="https://picsum.photos/id/237/200/200" class="display" id="display">
  </div>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

You can also add a single click listener on your ul tag, and use event.target to get which li that is clicked upon.

It's a more dynamic approach, because you don't need to add onclick="updateImage(this)" on every single li tag, and it creates cleaner HTML code.

Show code snippet

const listElement = document.querySelector('.list');

listElement.addEventListener('click', updateImage);

function updateImage(event) {
  const imgElement = document.querySelector('.show > img');
  const liElement = event.target;
  
  // Your code should be something like: "https://www.yourdomain.com/images/"   liElement.textContent
  const imageSrc = `https://picsum.photos/id/${liElement.textContent}/200/200`;
  
  imgElement.src = imageSrc;
}
.container {
  display: flex;
}

.list {
  width: 200px;
  cursor: pointer;
  padding: 0.25rem;
}

list > li * {
  /* so only the li tag can be event.target, and none of it's children */
  pointer-events: none;
}

.display {
  max-width: 500px;
  max-height: 500px;
}
<div class="container">
  <div class="list">
    <li>237</li>
    <li>240</li>
    <li>100</li>
    <li>301</li>
  </div>
  <div class="show">
    <img src="https://picsum.photos/id/237/200/200" class="display" id="display">
  </div>
</div>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related