简体   繁体   中英

Lit Web Component - Trying to select element

I am trying to transform this element into a standard web component using Lit. ( https://www.w3schools.com/howto/howto_js_image_comparison.asp )

I totally new to Lit and to web components and am struggling to select elements from the shadow DOM. Right now, I am stuck with the var x inside the initComparisons() function. I am aware that the document object does not exist in the shadow dom and must be replaced by renderRoot , however, I am not sure either If I am selecting the elements the right way or what does replace the window object... Do you notice something wrong with this code? I am stuck at the first lines of the initComparisons() function as x always returns null no matter what I do....

Any help will be appreciated.

Thank you very much.

import {
  LitElement,
  css,
  html,
} from "https://cdn.jsdelivr.net/gh/lit/dist@2/all/lit-all.min.js";

export class Comparator extends LitElement {
  static properties = {
    baseImage: "",
    imageWidth: "",
    imageHeight: "",
    altImage: "",
  };

  // Define scoped styles right with your component, in plain CSS
  static styles = css`
    * {
      box-sizing: border-box;
    }

    .img-comp-container {
      position: relative;
      height: 200px; /*should be the same height as the images*/
    }

    .img-comp-img {
      position: absolute;
      width: auto;
      height: auto;
      overflow: hidden;
    }

    .img-comp-img img {
      display: block;
      vertical-align: middle;
    }

    .img-comp-slider {
      position: absolute;
      z-index: 11;
      cursor: ew-resize;
      /*set the appearance of the slider:*/
      width: 40px;
      height: 40px;
      background-color: #2196f3;
      opacity: 0.7;
      border-radius: 50%;
    }

    .border-slider {
      position: absolute;
      z-index: 10;
      cursor: ew-resize;
      /*set the appearance of the slider:*/
      width: 5px;
      height: 130%;
      background-color: red;
      opacity: 1;
    }

    .border-slider::after {
      content: url("./separator.svg");
      position: absolute;
      width: 30px;
      height: 30px;
      background: red;
      top: calc(50% - 15px);
      left: calc(50% - 15px);
    }
  `;

  constructor() {
    super();
    // Declare reactive defaults
    this.baseImage = "https://api.lorem.space/image/house?w=800&h=600";
    this.altImage = "https://api.lorem.space/image/house?w=800&h=600";
    this.imageWidth = "800px";
    this.imageHeight = "600px";
  }

  connectedCallback() {
    super.connectedCallback();
    this.initComparisons();
  }

  // Render the UI as a function of component state
  render() {
    return html`
      <div class="img-comp-container">
        <div class="img-comp-img">
          <img
            src="${this.baseImage}"
            width="${this.imageWidth}"
            height="${this.imageHeight}"
          />
        </div>
        <div id="img-comp-overlay" class="img-comp-img">
          <img
            src="${this.altImage}"
            width="${this.imageWidth}"
            height="${this.imageHeight}"
          />
        </div>
      </div>
    `;
  }

  //HELPER FUCTIONS GO HERE
  initComparisons() {
    var x, i;
    /*find all elements with an "overlay" class:*/
    x = this.renderRoot.querySelector("#img-comp-overlay");
    for (i = 0; i < x.length; i++) {
      /*once for each "overlay" element:
      pass the "overlay" element as a parameter when executing the compareImages function:*/
      compareImages(x[i]);
    }

    function compareImages(img) {
      var slider,
        img,
        clicked = 0,
        w,
        h;
      /*get the width and height of the img element*/
      w = img.offsetWidth;
      h = img.offsetHeight;
      /*set the width of the img element to 50%:*/
      img.style.width = w / 2 + "px";
      /*create slider:*/
      slider = this.renderRoot.createElement("DIV");
      slider.setAttribute("class", "border-slider");
      /*insert slider*/
      img.parentElement.insertBefore(slider, img);
      /*position the slider in the middle:*/
      slider.style.top = h / 2 - slider.offsetHeight / 2 + "px";
      slider.style.left = w / 2 - slider.offsetWidth / 2 + "px";
      /*execute a function when the mouse button is pressed:*/
      slider.addEventListener("mousedown", slideReady);
      /*and another function when the mouse button is released:*/
      this.renderRoot.addEventListener("mouseup", slideFinish);
      /*or touched (for touch screens:*/
      slider.addEventListener("touchstart", slideReady);
      /*and released (for touch screens:*/
      window.addEventListener("touchend", slideFinish);
      function slideReady(e) {
        /*prevent any other actions that may occur when moving over the image:*/
        e.preventDefault();
        /*the slider is now clicked and ready to move:*/
        clicked = 1;
        /*execute a function when the slider is moved:*/
        window.addEventListener("mousemove", slideMove);
        window.addEventListener("touchmove", slideMove);
      }
      function slideFinish() {
        /*the slider is no longer clicked:*/
        clicked = 0;
      }
      function slideMove(e) {
        var pos;
        /*if the slider is no longer clicked, exit this function:*/
        if (clicked == 0) return false;
        /*get the cursor's x position:*/
        pos = getCursorPos(e);
        /*prevent the slider from being positioned outside the image:*/
        if (pos < 0) pos = 0;
        if (pos > w) pos = w;
        /*execute a function that will resize the overlay image according to the cursor:*/
        slide(pos);
      }
      function getCursorPos(e) {
        var a,
          x = 0;
        e = e.changedTouches ? e.changedTouches[0] : e;
        /*get the x positions of the image:*/
        a = img.getBoundingClientRect();
        /*calculate the cursor's x coordinate, relative to the image:*/
        x = e.pageX - a.left;
        /*consider any page scrolling:*/
        x = x - window.pageXOffset;
        return x;
      }
      function slide(x) {
        /*resize the image:*/
        img.style.width = x + "px";
        /*position the slider:*/
        slider.style.left = img.offsetWidth - slider.offsetWidth / 2 + "px";
      }
    }
  }
}

customElements.define("image-compare", Comparator);

connectedCallback() is likely too early to call this.initComparison() as the elements might not have been populated within the shadowroot. That happens on first render so you can grab those elements in firstUpdated() instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM