dexteryao 发表于 2021-10-28 09:46:57

SpreadJS接收拖拽行为

本帖最后由 dexteryao 于 2021-10-28 10:08 编辑 <br /><br />SpreadJS 提供了hitTest接口,可以获取指定坐标位置的元素信息,比如单元格的行列号。在线表格编辑器提供的拖拽向单元格设置绑定信息也是在响应drag事件时获取到松手时刻单元格信息,设置bindingPath。
下面Demo展示了具体实现方式。


<iframe src="https://jscodemine.grapecity.com/share/TGpK7VqVW0mcxRD4jdry7g/?isEmbed=true&isEditorShow=false&isExplorerShow=false&isConsoleShow=false" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"></iframe>

主要代码

spread.getHost().style.position = "relative"
let dragElement = new DragElement("dragContent", spread)

dragElement.js
function DragElement(elementId, spread){
    this.element = document.getElementById(elementId);
    this.spread = spread;
    this._init();
}

DragElement.prototype._init = function(){
    if(this.element && this.spread){
      this.element.addEventListener("dragstart", (evt) => {
            if (evt.dataTransfer) {
                evt.dataTransfer.setData("text/plain", "Data")
            }

            this.spread.getHost().ondragover = (evt) => this._onDocumentMouseMove(evt);
            this.spread.getHost().ondrop = (evt) => this._onDocumentMouseUp(evt);

            // this.spread.getHost().addEventListener("dragover", this._onDocumentMouseMove.bind(this));
            // this.spread.getHost().addEventListener("drop", this._onDocumentMouseUp.bind(this));
      });
      this.element.addEventListener("dragend", (evt) => {
            this.spread.getHost().ondragover = undefined;
            this.spread.getHost().ondrop = undefined;

            // this.spread.getHost().removeEventListener("dragover", this._onDocumentMouseMove.bind(this));
            // this.spread.getHost().removeEventListener("drop", this._onDocumentMouseUp.bind(this));

            this._removeBlock();
      });
      
    }
}

DragElement.prototype._onDocumentMouseMove = function(evt){
    evt.preventDefault();
    let hitInfo = this._getHitTestInfo(evt);
    if (!hitInfo) {
      return;
    }
    if (hitInfo.row === undefined || hitInfo.col === undefined) {
      return;
    }
    if (isNaN(hitInfo.row) || isNaN(hitInfo.col)) {
      return;
    }
    evt.stopPropagation()
    if(hitInfo.rowViewportIndex !== 1 || hitInfo.colViewportIndex !== 1){
      return;
    }
    let activeSheet = this.spread.getActiveSheet();
    let rect = activeSheet.getCellRect(hitInfo.row, hitInfo.col);
    this._highlightBlock(rect);
}
DragElement.prototype._onDocumentMouseUp = function(evt){
    evt.preventDefault();
    let hitInfo = this._getHitTestInfo(evt);
    if (!hitInfo) {
      return;
    }
    if (hitInfo.row === undefined || hitInfo.col === undefined) {
      return;
    }
    if (isNaN(hitInfo.row) || isNaN(hitInfo.col)) {
      return;
    }
    evt.stopPropagation()
    if(hitInfo.rowViewportIndex !== 1 || hitInfo.colViewportIndex !== 1){
      return;
    }
    let activeSheet = this.spread.getActiveSheet();
    activeSheet.setValue(hitInfo.row, hitInfo.col, evt.dataTransfer.getData("text/plain"))

}
DragElement.prototype._highlightBlock = function(rect){
    if(!this.decoration){
      this.decoration = document.createElement("div");
      this.decoration.style.position = "absolute"
      this.decoration.style.border = "1px solid blue"
      this.decoration.style.boxShadow = "0px 0px 4px 0px #007eff"
      this.decoration.style.zIndex = "1000"
      this.spread.getHost().appendChild(this.decoration);
    }
    this.decoration.style.width = (rect.width - 1) + "px";
    this.decoration.style.height = (rect.height - 1) + "px";
    this.decoration.style.left = rect.x + "px";
    this.decoration.style.top = rect.y + "px";
}
DragElement.prototype._removeBlock = function(){
    if(this.decoration){
      this.decoration.remove();
      this.decoration = undefined;
    }
}

DragElement.prototype._getHitTestInfo = function(event) {
    if(!this.spread){
      return;
    }
    let activeSheet = this.spread.getActiveSheet();
    if (!activeSheet) {
      return;
    }
    let canvas = this.spread.getHost().querySelector("canvas");;
    let t = this._getOffset(canvas);
    return activeSheet.hitTest(event.pageX - t.left, event.pageY - t.top);
}

DragElement.prototype._getOffset = function(element) {
    let left = 0;
    let top = 0;
    while (element) {
      left += element.offsetLeft;
      top += element.offsetTop;
      element = element.offsetParent;
    }
    return {
      left: left,
      top: top
    };
}

export {DragElement};
页: [1]
查看完整版本: SpreadJS接收拖拽行为