最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

this - Get image src then use it for div background javascript - Stack Overflow

programmeradmin3浏览0评论

When someone clicks on one of these images I would like that image to appear as the background image of div "slides", and am not sure what is going wrong. Maybe I am not using "this" properly.

function showslide() {
  y = document.getElementById("slides");
  y.style.display = "block";
  z = this.src;
  y.backgroundImage = 'url(' + z + ')';
}
<div id="slides">Div</div>
<div id="slidermenu">
  <img class="slidermenuimage" src="" onclick="showslide()"/><br>
  <img class="slidermenuimage" src="" onclick="showslide()"/><br>
  <img class="slidermenuimage" src="" onclick="showslide()"/><br>
</div>

When someone clicks on one of these images I would like that image to appear as the background image of div "slides", and am not sure what is going wrong. Maybe I am not using "this" properly.

function showslide() {
  y = document.getElementById("slides");
  y.style.display = "block";
  z = this.src;
  y.backgroundImage = 'url(' + z + ')';
}
<div id="slides">Div</div>
<div id="slidermenu">
  <img class="slidermenuimage" src="https://placehold.co/600x400/red/white" onclick="showslide()"/><br>
  <img class="slidermenuimage" src="https://placehold.co/600x400/orange/white" onclick="showslide()"/><br>
  <img class="slidermenuimage" src="https://placehold.co/600x400/yellow/white" onclick="showslide()"/><br>
</div>

Share Improve this question edited Jan 19 at 6:44 mplungjan 178k28 gold badges180 silver badges240 bronze badges asked Jan 19 at 3:27 googoo 171 silver badge2 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 0

Instead of using this, pass event into your functions. Then use event.target

You also need to use y.style.backgroundImage You left out the .style

By default the slides div has 0px height, so you need to set a height to see the background image.

See my EDIT comments in the code snippet for specific edits.

// EDIT add event as a parameter
// function showslide() {
function showslide(event) {
  y = document.getElementById("slides");
  y.style.display = "block";

  // EDIT Use event.target instead of this
  // z = this.src;
  z = event.target.src;

  // EDIT You need .style
  // y.backgroundImage = 'url('+z+')';
  y.style.backgroundImage = 'url('+z+')';
}
/* EDIT slides needs a height so you can see the background image */
#slides {
  height: 100px;
}

/* EDIT For the demo */
.slidermenuimage {
  margin: 1rem;
  width: 64px;
}
<div id="slides"></div>

<div id="slidermenu">
  <img class="slidermenuimage" src="https://placebear.com/400/400.jpg" onclick="showslide(event)"/><br>
  <img class="slidermenuimage" src="https://placebear.com/401/400.jpg" onclick="showslide(event)"/><br>
  <img class="slidermenuimage" src="https://placebear.com/402/400.jpg" onclick="showslide(event)"/><br>
</div>

Yes you are using this wrong, because you use inline event handlers which is not recommended. See the other answer for the inline handling

Also the assignment of backgroundImage is missing style.

Instead use addEventListener on the container so you can delegate

window.addEventListener('load', () => { // when the elements are available
  const slides = document.getElementById("slides");
  document.getElementById('slidermenu').addEventListener('click', (event) => {
    const tgt = event.target;
    if (!tgt.matches('.slidermenuimage')) return; // not an image
    slides.style.backgroundImage = `url(${tgt.src})`;
  });
});
#slides {
  width: 600px;
  height: 400px;
  border: 1px solid black;
}

.slidermenuimage {
  border: 1px solid white;
}
<div id="slides">Div</div>
<div id="slidermenu">
  <img class="slidermenuimage" src="https://placehold.co/600x400/red/white" /><br>
  <img class="slidermenuimage" src="https://placehold.co/600x400/orange/white" /><br>
  <img class="slidermenuimage" src="https://placehold.co/600x400/yellow/white" /><br>
</div>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Image Click Example</title>
  <style>
    #slides {
      width: 600px;
      height: 400px;
      background-color: lightgray;
      background-size: cover;
      background-position: center;
    }
    #slidermenu {
      margin-top: 20px;
    }
    .slidermenuimage {
      cursor: pointer;
      margin-bottom: 10px;
      width: 100px;
    }
  </style>
</head>
<body>
  <div id="slides"></div>
  <div id="slidermenu">
    <img class="slidermenuimage" src="https://placehold.co/600x400/red/white" alt="Red Image" /><br>
    <img class="slidermenuimage" src="https://placehold.co/600x400/orange/white" alt="Orange Image" /><br>
    <img class="slidermenuimage" src="https://placehold.co/600x400/yellow/white" alt="Yellow Image" /><br>
  </div>

  <script>
    // Wait for the DOM to load
    document.addEventListener("DOMContentLoaded", function () {
      // Select all images with the class "slidermenuimage"
      const images = document.querySelectorAll(".slidermenuimage");

      // Add a click event listener to each image
      images.forEach(function (image) {
        image.addEventListener("click", function () {
          // Get the source of the clicked image
          const imgSrc = this.getAttribute("src");

          // Set the background of the #slides div
          const slides = document.getElementById("slides");
          slides.style.backgroundImage = `url(${imgSrc})`;
        });
      });
    });
  </script>
</body>
</html>

Event Delegation

  • Although it's big in React, inline event handlers (or on-event handlers) are still discouraged. Use addEventListener() method.

  • If you have multiple elements needing an event handler, add the event handler (via addEventListener() to an ancestor element they all have in common. That could be window, document, body, etc. but it's better if you choose the closest one to the elements you intend to interact with. In your particular layout that would be #slidermenu (in Demo it's renamed #image-menu). See Example 1 below.

    Example 1

    <div id="ancestor"> <!-- Add event handler here... -->
      <img ...> <!-- if you want to control all of 
                     the children -->
      <img ...>
      <img ...>
    </div>
    

    ❇ event handler is a function that's used to handle an event via .eventListener(), on-property, or on-event.
    ✳ on-property looks like this:
    element.onclick = eventHandler;

  • When you write your event handler, you determine which elements will react to the event and exclude all other elements simply by not even mentioning them. To help you sort out the specific element the user interacted with (eg. "clicked"), use the event.target property. See Example 2 below.

    Example 2

    // Event object is passed by default
    const eventHandler = (event) => {
      // Find out which element user clicked
      const clk = event.target;
      // Specify which elements you want
      if (clk.matches("img")) {
        // Define what happens here
      }
      /**
       * You don't need to do anything else unless there
       * are other elements you wish to have react.
       */
    };
    // Reference ancestor element   
    const parent = document.getElementById("ancestor");
    // Register ancestor to "click" event
    parent.addEventListener("click", eventHandler);
    
  • The advantages of event delegation are:

    • Unlimited amount of elements you can control.
    • Control over any elements dynamically added later on.
    • You only need one event handler/listener for each event.type.
  • The disadvantage would be that there's more planning?

Other Concerns

  1. Remember to use let or const when defining variables. There were no let or const for y and z so they became global.

  2. style property wasn't used when assigning a value for backgroundImage.

  3. You don't need to assign display: block to a <div>, they already are by default.

  4. It's a fair assumption that display: block was used because the image never appeared. If there wasn't an error (see #2), the image would still not be visible. Because background-image is just a style and not content like an element or text. An element's height depends on it's content unless it's explicitly defined. In Demo min-height: 100px was added to #slides.

  5. Note: cssText property was used to add multiple styles. Using just style.CSSProperty = CSSValue will be overwritten if used again. So using cssText to define multiple styles all at once is better. If at sometime later you wish to add additional styles you can use += operand if you don't want to overwrite what's already there.

  6. this can be used if each <img> was assigned a named function handler by either addEventListener() or an on-property. When using this in an inline event handler it points to the window object.

Demo

Details are commented in demo.

/**
 * Handles "click" events. It assigns the
 * src of the <img> the user clicked to 
 * div#slides.
 * @param {object} event - Event object
 */
function showSlide(event) {
  // This is the element the user clicked
  const x = event.target;
  // If the user clicked an <img>...
  if (x.matches("img")) {
    // reference div#slides...
    const y = document.getElementById("slides");
    // get the url of the clicked <img>
    const z = event.target.src;
    // assign the styles to div#slides
    y.style.cssText = `
      min-height: 100px; 
      background-image: url("${z}");`;
  }
}

/**
 * Register div#image-menu to listen for the
 * "click" event when triggered on itself
 * and it's children (eg. all <img>s).
 */
document.getElementById("image-menu")
  .addEventListener("click", showSlide);
<div id="slides"></div>
<div id="image-menu">
  <img id="x" src="https://placehold.co/100x100/red/white"/>
  <img src="https://placehold.co/100x100/blue/yellow">
  <img src="https://placehold.co/100x100/yellow/blue">
</div>

发布评论

评论列表(0)

  1. 暂无评论