将鼠标事件绑定和取消绑定到自定义元素的问题

问题描述 投票:2回答:1

我正在尝试通过以下简单功能将“通过鼠标移动”功能添加到我的CustomElement中,以使其能够通过鼠标拖动来移动。但是它有很多滞后,并且该事件在“ mouseup”或“ mousedown”事件上无法正确附加和分离。我找不到原因,因为它通常可以在简单的“ div”元素上使用。

拖动功能:

//drag-element.js
export default function dragElement(elm) {
  const header = elm.Cardheader;
  header.style.cursor = "all-scroll";
  let [initX, initY] = [0, 0];
  let mousedown = false;

  let mousemoveEventHandler = function(e) {
    if (mousedown) {
      elm.style.top = `${e.clientY - initY}px`;
      elm.style.left = `${e.clientX - initX}px`;
    }
  };

  let mousedownEventHandler = function(e) {
    mousedown = true;
    header.onmousemove = mousemoveEventHandler;
    initX = e.clientX - elm.offsetLeft;
    initY = e.clientY - elm.offsetTop;
  };

  let mouseupEventHandler = function(e) {
    mousedown = false;
    header.onmousemove = null;
  };

  document.addEventListener("mouseup", mouseupEventHandler);

  header.onmousedown = mousedownEventHandler;
}

自定义元素:

//content-card.js
export default class ContentCard extends HTMLElement {
  constructor() {
    super();
    let shadow = this.attachShadow({ mode: "open" });

    let style = document.createElement("style");
    style.textContent = `
            :host {
                position: absolute;
                background-color: #fff;
                width: 50%;
                margin: 20px auto;
                display: block;
                border: 1px solid #eee;
                box-shadow: 1px 1px 4px 1px #444;
                box-sizing: border-box;
            }
            .header {
                background-color: #eee;
                min-height: 20px;
                display: block;
                padding: 15px;
            }
            .body {
                min-height: 150px;
                display: block;
                padding: 15px;
            }
        `;

    this.Cardheader = document.createElement("div");
    this.Cardheader.setAttribute("class", "header");

    this.Cardbody = document.createElement("div");
    this.Cardbody.setAttribute("class", "body");

    this.Cardheader.textContent = this.getAttribute("subject");
    this.Cardbody.innerHTML = this.getAttribute("content");

    shadow.appendChild(this.Cardheader);
    shadow.appendChild(this.Cardbody);
    shadow.appendChild(style);

  }

  static get observedAttributes() {
    return ["subject", "content"];
  }

  get subject() {
    return this.Cardheader.textContent;
  }
  set subject(val) {
    this.Cardheader.textContent = val;
  }

  get content() {
    return this.Cardbody.innerHTML;
  }

  set content(val) {
    this.Cardbody.innerHTML = val;
  }

  connectedCallback() {}

  disconnectedCallback() {}

  attributeChangedCallback(name, oldValue, newValue) {
    if (newValue === oldValue) return;

    switch (name) {
      case "subject":
        this.subjetct = newValue;
        break;
      case "content":
        this.content = newValue;
        break;
      default:
        break;
    }
  }

  adoptedCallback() {}
}

主要Javascript:

//index.js
import ContentCard from "./content-card.js";
import ContentCard from "./drag-element.js";


customElements.define("content-card", ContentCard);

let cCard = new ContentCard();

document.body.appendChild(cCard);

dragElement(cCard);
<html>
    <head>
        <script defer type="module" src="./index.js"></script>
    </head>
    <body>
        <content-card subject="subject" content="Content"></content-card>
    </body>
</html>
javascript html es6-modules mousemove custom-element
1个回答
0
投票

确定,因此px修复了粘贴问题,并且可以通过在initY上添加标头的填充来抵消开始时的粘连和有趣的捕捉行为。这是由于标头具有填充和elm的偏移量无法解释这一点,并且header捕捉到了鼠标位置,因此15px捕捉到了很小的位置,这导致鼠标移出了标头并且删除元素。有人知道这里是正确的道具吗?这将回答您的问题,为什么有点奇怪...

关于松懈的地方,您可能需要看看也许跳过一些事件。

//drag-element.js
function dragElement(elm) {
  const header = elm.Cardheader;
  header.style.cursor = "all-scroll";
  let [initX, initY] = [0, 0];
  let mousedown = false;

  let mousemoveEventHandler = function(e) {
    if (mousedown) {
      elm.style.top = `${e.clientY - initY}px`;
      elm.style.left = `${e.clientX - initX}px`;
    }
  };

  let mousedownEventHandler = function(e) {
    mousedown = true;
    elm.onmousemove = mousemoveEventHandler;
    initX = e.clientX - elm.offsetLeft;
    initY = e.clientY - elm.offsetTop + 15;
  };

  let mouseupEventHandler = function(e) {
    mousedown = false;
    header.onmousemove = null;
  };

  document.addEventListener("mouseup", mouseupEventHandler);

  header.onmousedown = mousedownEventHandler;
}

//content-card.js
class ContentCard extends HTMLElement {
  constructor() {
    super();
    let shadow = this.attachShadow({ mode: "open" });

    let style = document.createElement("style");
    style.textContent = `
            :host {
                position: absolute;
                background-color: #fff;
                width: 50%;
                margin: 20px auto;
                display: block;
                border: 1px solid #eee;
                box-shadow: 1px 1px 4px 1px #444;
                box-sizing: border-box;
            }
            .header {
                background-color: #eee;
                min-height: 20px;
                display: block;
                padding: 15px;
            }
            .body {
                min-height: 150px;
                display: block;
                padding: 15px;
            }
        `;

    this.Cardheader = document.createElement("div");
    this.Cardheader.setAttribute("class", "header");

    this.Cardbody = document.createElement("div");
    this.Cardbody.setAttribute("class", "body");

    this.Cardheader.textContent = this.getAttribute("subject");
    this.Cardbody.innerHTML = this.getAttribute("content");

    shadow.appendChild(this.Cardheader);
    shadow.appendChild(this.Cardbody);
    shadow.appendChild(style);

  }

  static get observedAttributes() {
    return ["subject", "content"];
  }

  get subject() {
    return this.Cardheader.textContent;
  }
  set subject(val) {
    this.Cardheader.textContent = val;
  }

  get content() {
    return this.Cardbody.innerHTML;
  }

  set content(val) {
    this.Cardbody.innerHTML = val;
  }

  connectedCallback() {}

  disconnectedCallback() {}

  attributeChangedCallback(name, oldValue, newValue) {
    if (newValue === oldValue) return;

    switch (name) {
      case "subject":
        this.subjetct = newValue;
        break;
      case "content":
        this.content = newValue;
        break;
      default:
        break;
    }
  }

  adoptedCallback() {}
}

customElements.define("content-card", ContentCard);

let cCard = new ContentCard();

document.body.appendChild(cCard);

dragElement(cCard);
© www.soinside.com 2019 - 2024. All rights reserved.