100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > luckysheet移动端添加复制粘贴(批量粘贴)操作按钮

luckysheet移动端添加复制粘贴(批量粘贴)操作按钮

时间:2021-02-20 00:26:26

相关推荐

luckysheet移动端添加复制粘贴(批量粘贴)操作按钮

需求:

移动端的luckysheet需要有类似钉钉写作文档中的选中一块区域后弹出复制、剪切等按钮。

操作:

luckysheet滑动选中一块区域后会在左上角和右下角有小圆点,点击小圆点或者滑动选择区域时弹出操作框(类似钉钉文档)

开工:

添加dom

CTRL+P找到Moblie.js文件,在document的touchend回调的末尾加上自己的函数,开始处理。

ShowMobileOperation函数内容如下:

function ShowMobileOperation(event){// nby 第一步、判断触摸完毕是否显示复制块if(event.target.contains($('.luckysheet-cs-touchhandle-btn')[1]) && $("#mobileOperation").length==0){// nby 移动端操作区域domif(Store.isMobile){//这个是Store.isMobile是在全局新加的变量,用以表示是移动端,因为luckysheet本身判断有问题,只能手动填写$("body").append(`<div id='mobileOperation' style="z-index:10000;position: absolute;width: auto;height: auto;user-select:none;"><div style="display: flex; "><div style="background-color:wheat;display: flex;justify-content:space-between;align-item:center;padding: 6px;width:auto;border-radius: 10px;"><div id='mobileCopyBtn' style="display: flex;cursor: pointer;margin-right: 10px;"><svg style="width:18px;height:18px;" t="1673399639231" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="/2000/svg" p-id="1908" width="200" height="200"><path d="M720 192h-544A80.096 80.096 0 0 0 96 272v608C96 924.128 131.904 960 176 960h544c44.128 0 80-35.872 80-80v-608C800 227.904 764.128 192 720 192z m16 688c0 8.8-7.2 16-16 16h-544a16 16 0 0 1-16-16v-608a16 16 0 0 1 16-16h544a16 16 0 0 1 16 16v608z" p-id="1909"></path><path d="M848 64h-544a32 32 0 0 0 0 64h544a16 16 0 0 1 16 16v608a32 32 0 1 0 64 0v-608C928 99.904 892.128 64 848 64z" p-id="1910"></path><path d="M608 360H288a32 32 0 0 0 0 64h320a32 32 0 1 0 0-64zM608 520H288a32 32 0 1 0 0 64h320a32 32 0 1 0 0-64zM480 678.656H288a32 32 0 1 0 0 64h192a32 32 0 1 0 0-64z" p-id="1911"></path></svg><span style='font-size: 14px;white-space: nowrap;'>全复制</span></div><div id='mobilePasteBtn' style="display: flex;border: none;cursor: pointer;margin-right: 6px;"><svg style="width:18px;height:18px;" t="1673399835334" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="/2000/svg" p-id="2894" width="200" height="200"><path d="M901.117698 948.224208V814.080577H959.997536v134.143631h-58.879838z m0-328.959095H959.997536v133.887632h-58.879838v-133.887632z m0-198.655454H959.997536v133.887632h-58.879838v-133.887632z m0-207.359429H959.997536v134.143631h-58.879838V213.25023z m-153.599578 752.125931h120.319669V1024h-120.319669v-58.623839z m43.238281-162.303553a93.490943 93.490943 0 0 1-94.23334 92.671745H279.833006v78.079785h-58.879838v-78.079785H158.284541a93.490943 93.490943 0 0 1-94.233341-92.671745V306.689973L355.096799 0.002816H696.57426a93.490943 93.490943 0 0 1 94.233341 92.671745v26.879926H865.277796v58.623839h-74.572594v624.894282zM162.27813 306.177974h203.289041V91.906563z m557.259267-213.503413a22.630338 22.630338 0 0 0-23.039936-22.015939H436.837375v245.247325a61.260632 61.260632 0 0 1-61.439831 60.927833H135.142204v426.238828a22.476738 22.476738 0 0 0 23.039937 22.015939H696.57426a22.451138 22.451138 0 0 0 23.039937-22.015939V92.674561zM450.558937 1024h-120.319669v-58.623839h120.319669V1024z m212.479416 0h-120.319669v-58.623839h120.319669V1024z" fill="#333333" p-id="2895"></path></svg><span style='font-size: 14px;white-space: nowrap;'>粘贴</span></div><div id='copyShowVal' style="display: flex;cursor: pointer;margin-right: 2px;"><svg style="width:20px;height:20px;" t="167540131" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="/2000/svg" p-id="1855" width="200" height="200"><path d="M725.333333 341.333333h128v512H341.333333v-128H213.333333V213.333333h512v128z m0 42.666667v341.333333H384v85.333334h426.666667V384h-85.333334zM256 256v426.666667h426.666667V256H256z" fill="#444444" p-id="1856"></path></svg><span style='font-size: 14px;white-space: nowrap;'>复制文本</span></div></div></div></div>`);let col = luckysheet_touchmove_startPos.xlet row = luckysheet_touchmove_startPos.y// let col = Store.touchCoord.x+'px'// let row = Store.touchCoord.y+'px'$("#mobileOperation").css({"left": col, "top": row}); //定位操作区域,这几个变量上面有计算// nby 第二步,对具体的按钮进行处理// 监听复制文本的按钮,就是只复制单元格的文本,不包括批注、背景等$('#copyShowVal').on('touchend',function(event){// $("#luckysheet-copy-array2").click()// 先得到cell中的m字段二维数组// let copyData=luckysheet.getRangeValue()// copyData = copyData.map(arrItem=>arrItem.map(cell=>cell?.m))// let htmlData='' //构建html数据// let tr_Str = copyData.reduce((preVal,cur)=>{//let str=''//cur.forEach((strItem)=>{// str += `<td>${strItem}</td>`//})//return preVal+`<tr>${str}</tr>`// },'')// htmlData = `<table>${tr_Str}</table>`// selection.copybyformat(event,htmlData)// 上面是之前的代码,本想用html标签的形式作为复制的内容,发现不行,但是在键盘操作cv是行的。let copyData=luckysheet.getRangeValue()// 生成luckysheet的二维数组copyData,因为只复制文本值,所以取单元格对象的m字段// {fa: 'General', t: 'n'}copyData=copyData.map((arrCell)=>arrCell.map(cell=>({v:cell?.m,m:cell?.m,ct:{fa: 'General', t: 'n'}}))) selection.copybyformat(event,JSON.stringify(copyData))Store.isCopyText = true //判定是点击的仅复制文本还是全复制按钮event.stopPropagation();event.stopImmediatePropagation()setTimeout(()=>{$('#mobileOperation').remove()},200)//这里可以封装为一个函数,下面经常用。})// 监听粘贴$('#mobilePasteBtn').on('touchend',function(event){// nby 以下会对粘贴做一些限制,直接从luckysheet本身的粘贴按钮复制过来if (isEditMode() || Store.allowEdit === false) {//此模式下禁用粘贴return;}if ($(event.target).hasClass("formulaInputFocus")) {return;}if (Store.luckysheet_select_save.length > 1) {if (isEditMode()) {alert(locale_drag.noPaste);}else {tooltip.info(locale_drag.noPaste, "");}return;}selection.isPasteAction = true;selection.paste(event,'btn',Store.isCopyText) // nby Store.isCopyText全局变量用来luckysheetactiveCell();event.stopPropagation();event.stopImmediatePropagation()setTimeout(()=>{$('#mobileOperation').remove()},200)})// 监听全复制按钮$('#mobileCopyBtn').on('touchend',function(event){//复制时存在格式刷状态,取消格式刷if (menuButton.luckysheetPaintModelOn) {menuButton.cancelPaintModel();}if (Store.luckysheet_select_save.length == 0) {return;}//复制范围内包含部分合并单元格,提示if (Store.config["merge"] != null) {let has_PartMC = false;for (let s = 0; s < Store.luckysheet_select_save.length; s++) {let r1 = Store.luckysheet_select_save[s].row[0],r2 = Store.luckysheet_select_save[s].row[1];let c1 = Store.luckysheet_select_save[s].column[0],c2 = Store.luckysheet_select_save[s].column[1];has_PartMC = hasPartMC(Store.config, r1, r2, c1, c2);if (has_PartMC) {break;}}if (has_PartMC) {if (isEditMode()) {alert(locale_drag.noMerge);}else {tooltip.info(locale_drag.noMerge, "");}return;}}//多重选区 有条件格式时 提示let cdformat = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].luckysheet_conditionformat_save;if (Store.luckysheet_select_save.length > 1 && cdformat != null && cdformat.length > 0) {let hasCF = false;let cf_compute = conditionformat.getComputeMap();label:for (let s = 0; s < Store.luckysheet_select_save.length; s++) {if (hasCF) {break;}let r1 = Store.luckysheet_select_save[s].row[0],r2 = Store.luckysheet_select_save[s].row[1];let c1 = Store.luckysheet_select_save[s].column[0],c2 = Store.luckysheet_select_save[s].column[1];for (let r = r1; r <= r2; r++) {for (let c = c1; c <= c2; c++) {if (conditionformat.checksCF(r, c, cf_compute) != null) {hasCF = true;continue label;}}}}if (hasCF) {if (isEditMode()) {alert(locale_drag.noMulti);}else {tooltip.info(locale_drag.noMulti, "");}return;}}//多重选区 行不一样且列不一样时 提示if (Store.luckysheet_select_save.length > 1) {let isSameRow = true,str_r = Store.luckysheet_select_save[0].row[0],end_r = Store.luckysheet_select_save[0].row[1];let isSameCol = true,str_c = Store.luckysheet_select_save[0].column[0],end_c = Store.luckysheet_select_save[0].column[1];for (let s = 1; s < Store.luckysheet_select_save.length; s++) {if (Store.luckysheet_select_save[s].row[0] != str_r || Store.luckysheet_select_save[s].row[1] != end_r) {isSameRow = false;}if (Store.luckysheet_select_save[s].column[0] != str_c || Store.luckysheet_select_save[s].column[1] != end_c) {isSameCol = false;}}if ((!isSameRow && !isSameCol) || selectIsOverlap()) {if (isEditMode()) {alert(locale_drag.noMulti);}else {tooltip.info(locale_drag.noMulti, "");}return;}}// nby 全复制也需要做数据自适应// selection.copy(event);selection.copybyformat(event,JSON.stringify(luckysheet.getRangeValue()))// Store.isCopyText = false//这是全复制,故需要将复制文本关闭Store.isCopyText = true; //这是全复制,故需要将复制文本关闭Store.luckysheet_paste_iscut = false;luckysheetactiveCell();event.stopPropagation();event.stopImmediatePropagation()setTimeout(()=>{$('#mobileOperation').remove()},200)})}}}

上面函数的简易思路:

触摸完毕,创建dom,挂载到body上,之后定位到触摸坐标。为dom中的几个按钮添加点击事件处理。

各按钮回调思路

文本复制按钮(#copyShowVal)回调。

(1)首先用luckysheet.getRangeValue()获取复制区域的单元格对象数据(返回结果是二维数组),然后构建出需要的符合单元格对象格式的二维数组。(就是把m也赋值给v,其他批注啥的都不要,这样去粘贴构建出来的数据就都是显示值m了)

(2)之后将构建好的数据交给selection.copybyformat(event,JSON.stringify(copyData))去处理。 最后隐藏操作区域。

全复制(#mobileCopyBtn)按钮回调

同上

粘贴(#mobilePasteBtn)按钮回调

(1)调用selection.paste(event,'btn',Store.isCopyText) 方法,由于需要做批量粘贴,还需要对粘贴的数据进行处理。

(2)进入paste后,获取textarea的内容data(实现复制粘贴功能时clipboard不支持就用这种方法),之后交给pasteHandler方法,在pasteHandler方法里对数据进行自适应处理。自适应数据处理函数代码如下:

// nby 实现批量粘贴数据的函数function selfAdaptionData(data){let primData = $.extend(true, [], data);// 判断当前选区,实现批量粘贴let range = luckysheet.getRange()//获取需要粘贴的区域let pasteRange = [range[0].row[1] - range[0].row[0] + 1 , range[0].column[1] - range[0].column[0] + 1 ]let copyRange = [data.length,data[0].length]let residueColumnNum = pasteRange[1] - copyRange[1] //粘贴区域的列数是否比已复制的数据列数多let residueRowNum = pasteRange[0] - copyRange[0]if(residueColumnNum > 0 || residueRowNum > 0){// 粘贴区域更大,扩大粘贴的数据// 先扩大列数let columnCount = parseInt(pasteRange[1]/copyRange[1])for(let i = 1 ; i < columnCount ; i++){data = data.map((arr,index)=>{return [...arr,...primData[index]]//这里新添加的每行数据需要用对应的那一行,并且需要是之前的数据})}// 扩大行数let primDataArr = $.extend(true, [], data);//先存下,一次粘贴的数据let rowCount = parseInt(pasteRange[0]/copyRange[0])for(let i = 1 ; i < rowCount ; i++){data = [...data,...primDataArr]}}return data}

selfAdaptionData函数说明:

通过luckysheet.getRange()获取粘贴的区域,计算出粘贴区域的行数和列数pasteRange,又通过入参data计算出拷贝区域的行列数copyRange,通过行列相减,判断粘贴区域是否大于拷贝区域。

如果大于,则需要扩大数据。计算出最小整数倍,然后循环添加。先把列处理好之后就是行。

补充说明:

我这里的批量粘贴是啥?

比如我复制一个格子,在需要粘贴之前又框选4x4的格子,如果支持批量粘贴就共有4x4=16个格子都有数据,不然只有第一个格子才有粘贴的数据。

最后附上效果图:

由于移动端操作的局限性,后续还需要加上其他功能按钮。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。