本帖最后由 Joestar.Xu 于 2024-11-25 11:35 编辑
当表格中有许多需要引用的参数时,我们会倾向于将其作为一个外部的表格引入来使用,但是在SpreadJS中想要给单元格的指定位置插入引用却不是那么的简单。
在点击外部表格时会由于焦点的变化,会导致单元格退出编辑状态,进而无法顺利将我们想要插入的引用插入到单元格的指定位置。
如下图:
进入编辑状态后,点击右侧的加号,打开外部表格进行引入操作。
在点击了外部的表格后,编辑状态就会退出。
此时,如果我们还想要实现插入的效果,就只能使用浏览器原生的光标API来实现这个需求。
整体的实现思路是:记录下插入的索引位置=》弹出外部表格并且获取要插入的值(或其他的数据,结合自己的业务场景来选择)=》通过API重新进入编辑状态=》根据之前记录下的索引位置插入需要插入的值。
最终的实现效果为下图:
实现源码:
- window.onload = async () => {
- let designer, spread, sheet;
- let designerConfig = JSON.parse(
- JSON.stringify(GC.Spread.Sheets.Designer.DefaultConfig)
- );
- designer = new GC.Spread.Sheets.Designer.Designer(
- "gc-designer-container",
- designerConfig
- );
- spread = designer.getWorkbook();
- sheet = spread.getActiveSheet();
- let cursorPos = -1;
- sheet.bind(GC.Spread.Sheets.Events.EditStarting, (e, info) => {
- let editor = document.querySelector("div[gcuielement='gcEditingInput']");
- editor.addEventListener("click", () => {
- getCursorIndex(editor);
- });
- });
- let style = new GC.Spread.Sheets.Style();
- style.cellButtons = [
- {
- imageType: GC.Spread.Sheets.ButtonImageType.plus,
- command: (sheet, row, col, option) => {
- let div = document.createElement("div");
- div.className = "testDiv";
- div.style.border = "3px solid red";
- div.style.x = "300px";
- div.style.y = "300px";
- div.style.display = "block";
- div.style.position = "absolute";
- div.style.width = "500px";
- div.style.height = "500px";
- div.setAttribute("gcUIElement", "gcEditingInput");
- let button = document.createElement("button");
- button.innerText = "确定";
- button.style.position = "absolute";
- button.style.right = "0";
- button.style.top = "0";
- button.style.width = "100px";
- button.style.height = "30px";
- div.appendChild(button);
- sheet.getParent().getHost().appendChild(div);
- let newSpread = new GC.Spread.Sheets.Workbook(
- document.querySelector(".testDiv"),
- { sheetCount: 1 }
- );
- let newSheet = newSpread.getActiveSheet();
- button.addEventListener("click", () => {
- if (cursorPos == -1) {
- cursorPos = sheet.getValue(
- sheet.getActiveRowIndex(),
- sheet.getActiveColumnIndex()
- ).length;
- console.log("cursorPos == -1", cursorPos);
- }
- let selection = newSheet.getSelections()[0];
- console.log(selection);
- sheet.getParent().getHost().removeChild(div);
- newSpread.destroy();
- sheet.startEdit();
- let gcEditingInput = document.querySelector(
- "div[gcuielement='gcEditingInput']"
- );
- moveCursorToIndex(gcEditingInput, cursorPos);
- insertAtCursorInDiv("INSERT");
- });
- },
- },
- ];
- sheet.setStyle(0, 0, style);
- sheet.setValue(0, 0, "Test");
- function getCursorIndex(editor) {
- const selection = window.getSelection();
- const range = selection.getRangeAt(0);
- const preCaretRange = range.cloneRange();
- preCaretRange.selectNodeContents(editor);
- preCaretRange.setEnd(range.endContainer, range.endOffset);
- cursorPos = preCaretRange.toString().length;
- console.log(`光标位置: ${cursorPos}`);
- }
- function moveCursorToIndex(div, index) {
- let currentIndex = 0;
- let targetNode = div.firstChild.childNodes[0].firstChild;
- if (targetNode.textContent == "=") {
- for (let i = 0; i < div.firstChild.childNodes.length; i++) {
- let node = div.firstChild.childNodes[i];
- let nodeTextLength = node.textContent.length;
- if (currentIndex + nodeTextLength > index) {
- targetNode = node;
- break;
- }
- currentIndex += nodeTextLength;
- }
- }
- let range = document.createRange();
- let offset = index - currentIndex;
- range.setStart(targetNode, offset);
- range.setEnd(targetNode, offset);
- let selection = document.getSelection();
- selection.removeAllRanges();
- selection.addRange(range);
- }
- function insertAtCursorInDiv(string) {
- let selection = document.getSelection();
- let textNode = document.createTextNode(string);
- selection.getRangeAt(0).insertNode(textNode);
- selection.collapseToEnd();
- }
- };
复制代码
|
|