簡體   English   中英

無法在嵌套 shadowdom 中使 div/element 移動

[英]Can not make div/element movable in nested shadowdom

我不能讓我的 div 移動。 它是一個自定義元素,由事件偵聽器創建。 這兩個自定義元素都有自己的 shadowdom。

樹狀結構 樹狀結構

第一個自定義元素是<web-desktop> / WebDesktop.js 第二個元素是<app-window> / AppWindow.js

<app-window>在單擊事件偵聽器后創建。 現在,我試圖通過單擊按鈕使該“窗口”(div)在創建后可移動。

但是,我這樣做了幾個小時都沒有成功。

我包括了這兩個部分,我堅信問題出在 AppWindow 中。

AppWindow 自定義元素

const template = document.createElement('template')
template.innerHTML = `
<style>
#mydiv {
  position: absolute;
  z-index: 9;
  background-color: #f1f1f1;
  border: 1px solid #d3d3d3;
  text-align: center;
}
#mydivheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}
</style>
<div id="mydiv">
  <div id="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>
`

class AppWindow extends window.HTMLElement {
  constructor() {
    super()

    this.attachShadow({ mode: 'open' })
    this.shadowRoot.appendChild(template.content.cloneNode(true))
    this.appWindowHeader = this.shadowRoot.querySelector('#mydivheader')
    this.appWindow = this.shadowRoot.querySelector('#mydiv')

    this.prevX = undefined
    this.prevY = undefined
    this.newX = undefined
    this.newY = undefined
  }

  static get observedAttributes() {
    return []
  }

  attributesChangedCallback(name, oldValue, newValue) {
  }

  connectedCallback() {
    this.appWindow.addEventListener('mousedown', this.mousedown)
  }

  mousedown(event) {
    window.addEventListener('mousemove', this.mousemove)
    window.addEventListener('mouseup', this.mouseup)
    this.prevX = event.clientX
    this.prevY = event.clientY
  }

  mousemove(event) {
    this.newX = event.clientX
    this.newY = event.clientY
    const rect = this.appWindow.getBoundingClientRect()

    this.appWindow.style.left = rect.left - this.newX + 'px'
    this.appWindow.style.right = rect.top - this.newY + 'px'

    this.prevX = event.clientX
    this.prevY = event.clientY
  }

  mouseup() {

  }

}

window.customElements.define('app-window', AppWindow)

export { AppWindow }

WebDesktop 自定義元素

import { AppWindow } from './AppWindow.js'
const template = document.createElement('template')
template.innerHTML = `
<style>
.resizer {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 5px;
  background-color: black;
  z-index: 2;
}
#appImg1 {
  cursor:pointer;
}
#menuDiv {
  background-color: rgb(23, 23, 23);
  position: fixed;
  bottom: 0;
  width: 100%;
  padding: 0px;
  margin: 0px;
}
#menuDiv img {
  margin-left: 25px;
}
hr {
  border: 1px solid black;
  border-radius: 0px;
  margin:0;
  margin-bottom:5px;
}
</style>

<div id="webDesktopDiv">

  <div id="menuDiv">
  <hr>
  <img src="../image/icon.png" id="appImg1">
  </div>

</div>
`
class WebDesktop extends window.HTMLElement {
  constructor() {
    super()

    this.attachShadow({ mode: 'open' })
    this.shadowRoot.appendChild(template.content.cloneNode(true))

    this.menuDiv = this.shadowRoot.querySelector('#menuDiv')
    this.webDesktopDiv = this.shadowRoot.querySelector('#webDesktopDiv')
    this.appImg1 = this.shadowRoot.querySelector('#appImg1')

  }

  static get observedAttributes() {
    return []
  }

  attributesChangedCallback(name, oldValue, newValue) {
  }

  connectedCallback() {
    this.appImg1.addEventListener('click', event => {
      this.createWindow()
    })
  }

  createWindow() {
    let appWindow = document.createElement('app-window')
    appWindow.classList = 'item'
    appWindow.setAttribute('draggable', 'true')
    this.webDesktopDiv.appendChild(appWindow)
  }
}

window.customElements.define('web-desktop', WebDesktop)
export { WebDesktop }

<app-window> ,您應該使用dragstart事件處理程序並記錄您在DragEvent.dataTransfer屬性中單擊的位置:

應用程序窗口.js

const template = `
<style>
:host {
    position: absolute
}
#mydiv {
    z-index: 9;
    background-color: #f1f1f1;
    border: 1px solid #d3d3d3;
    text-align: center;
}
#mydivheader {
    padding: 10px;
    cursor: move;
    z-index: 10;
    background-color: #2196F3;
    color: #fff;
}
</style>
<div id="mydiv">
  <div id="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>
`
var count = 0 
class AppWindow extends window.HTMLElement {
    constructor() {
        super()
        this.attachShadow({ mode: 'open' }).innerHTML = template
    }

    connectedCallback() {
        this.setAttribute( 'draggable', 'true' )
        this.id = count++
        this.ondragstart = ev => ev.dataTransfer.setData( 'text', JSON.stringify( {
            id: ev.target.id,
            x: ev.clientX,
            y: ev.clientY
        } ) )
    }
}

window.customElements.define('app-window', AppWindow)

export { AppWindow }

<web-desktop>的容器,你應該避免的默認行為dragover事件,然后定義一個drop的事件處理程序來設置新的<app-window>從上下點擊差計算位置:

webdesktop.js

import { AppWindow } from './AppWindow.js'
const template = `
<style>
:host {
    height: 100% ;
    display: block ;
}

button {
  position: fixed;
  bottom: 10px; left: 10px;
}
</style>

  <button>Add</buton>
`
var count = 0

class WebDesktop extends window.HTMLElement {
  constructor() {
    super()
    this.attachShadow( { mode: 'open' } ).innerHTML = template
  }

  connectedCallback() {
    this.shadowRoot.querySelector( 'button' ).onclick = () => this.shadowRoot.appendChild( new AppWindow )
    this.ondragover = ev => ev.preventDefault()
    this.ondrop = ev => {
        let origin = JSON.parse( ev.dataTransfer.getData( 'text' ) )
        console.log( origin )
        let app = this.shadowRoot.getElementById( origin.id )
        let childPos = app.getBoundingClientRect()
        app.style.left = childPos.left + ( ev.clientX - origin.x ) + 'px'
        app.style.top = childPos.top + ( ev.clientY - origin.y ) + 'px'
    } 
  }
}

window.customElements.define('web-desktop', WebDesktop)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM