偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

設置表格列寬—在富文本編輯器中的實現(xiàn)

開發(fā) 前端
之前因為工作上的一些原因,使用的 wangEditor 富文本編輯器的表格(table)功能并不能滿足需求,創(chuàng)建的表格只是設置了 width: 100%,列的寬度的自適應的效果非常不美觀。

大家好,我是前端西瓜哥。

之前因為工作上的一些原因,使用的 wangEditor 富文本編輯器的表格(table)功能并不能滿足需求,創(chuàng)建的表格只是設置了 width: 100%,列的寬度的自適應的效果非常不美觀。于是決定修改源碼,對表格功能做了加強,使其支持調(diào)整列寬。

為了方便讀者理解,最近把這部分邏輯單獨抽離出來并做了優(yōu)化,寫了個能獨立運行的 demo,配合這篇文章簡單說一說實現(xiàn)思路。

實現(xiàn)思路

1、 創(chuàng)建空表格

第一步是創(chuàng)建空表格。要想支持表格可以設置寬度,需要在 table 元素下使用 colgroup 元素。我們根據(jù)表格列的數(shù)量,在 colgroup 下創(chuàng)建同等數(shù)量的 col 元素并設置寬度,就能給對應順序的列賦予寬度。效果可以查看這個 在線demo 。

此外,表格的單元格如果沒有內(nèi)容,是會發(fā)生高度塌陷的,且無法通過 min-height 和 height 設置高度 。為解決這個問題,我們通常會在創(chuàng)建空表格時,給單元格添加內(nèi)容。

2、 高亮線的顯現(xiàn)

第二步是實現(xiàn)光標劃到列之間的分割線上方時,將高亮線顯現(xiàn)出來。實現(xiàn)方式是:

  • 初始化時,在編輯器容器元素下創(chuàng)建一個絕對定位的 div 元素作為高亮線,并隱藏。
  • 給編輯器容器元素綁定鼠標移動事件。當光標移動到表格元素內(nèi)部時,遍歷 col 元素得到所有列分隔線的位置(最左邊的不需要)。若光標位于這些分隔線附近,拿到左位移量,然后修改高亮線的位置并將其顯現(xiàn)出來;否則隱藏高亮線。

3、 拖拽高亮線實現(xiàn)設置列寬

前面提到,當光標懸浮在列分割線上方附近,會出現(xiàn)高亮線。其實為實現(xiàn)修改列寬,我們還要記錄一些數(shù)據(jù):(1)對應的表格元素;(2)第幾列 rowIdx。當然光標移開時,要把這些數(shù)據(jù)清空。

下面是拖拽這一動作的實現(xiàn),涉及到鼠標按下、鼠標移動、鼠標釋放三個事件:

  • 當鼠標在高亮線上 按下 時,我們要將上面的數(shù)據(jù)拷貝一份,然后再記錄好要修改的(3)列的寬度;(4)光標左偏移量 left(后面要用來計算相對移動位置)(5)對應的 col 元素。
  • 在鼠標按下不釋放的情況下,移動鼠標,就代表著 拖拽 這一動作的發(fā)生。此時,我們計算光標的相對左移動,給對應的 col 元素設置寬度,就能實現(xiàn)動圖上的效果。
  • 鼠標釋放,將這些數(shù)據(jù)重置為空。

因為只需要得到拖拽的相對位置,所以我們不是必須要將事件綁定到編輯器容器上。另外為了確保鼠標釋放事件正在發(fā)生,最終我選擇在 document 元素上綁定事件。document 元素上綁定的鼠標釋放事件,按下鼠標后,即便在瀏覽器外面釋放鼠標,也能觸發(fā)。

另外,為處理列寬過小,甚至計算出負值的情況,我們需要設置一個最小列寬。

代碼實現(xiàn)

那么這里就簡單講解一下核心代碼。

首先是創(chuàng)建空表格:

const DEFAULT_COL_WIDTH = 80
const DEFAULT_COL_SIZE = 5
const DEFAULT_ROW_SIZE = 5
// 生成空 table
function createTable(row = DEFAULT_ROW_SIZE, col = DEFAULT_COL_SIZE, hasTh = false, colWidth = DEFAULT_COL_WIDTH) {
const tbody = document.createElement('tbody')
let tr, td
for (let i = 0; i < row; i++) {
tr = document.createElement('tr')
tbody.appendChild(tr)
for (let j = 0; j < col; j++) {
td = document.createElement((i === 0 && hasTh) ? 'th' : 'td')
td.innerHTML = '<br />' // 填充點東西,處理單元格高度塌陷問題
tr.appendChild(td)
}
}
const colgroup = document.createElement('colgroup')
let colElm
for (let i = 0; i < col; i++) {
colElm = document.createElement('col')
colElm.style.width = colWidth + 'px'
colgroup.appendChild(colElm)
}
const table = document.createElement('table')
table.appendChild(colgroup)
table.appendChild(tbody)
return table
}

顯現(xiàn)高亮線的核心實現(xiàn)邏輯如下。計算左偏移量使用了 getBoundingClientRect() 方法和鼠標事件中得到的 clientX 坐標。其中還需要注意坐標系有 “相對表格” 和 “相對編輯器容器” 兩種。

const hl = new HL(editorEl) // 高亮線對象
// ...
let lastState = {} // 高亮線出現(xiàn)時,記錄對應的 tableElrowIdx
function handleMovemove(event) {
// 找到最近的table父元素
const nearestTable = getNearestTable(event.target, editorEl)
if (!nearestTable) {
hl.hideHL()
lastState = {}
return
}
const tableLeftByViewport = nearestTable.getBoundingClientRect().left
const cursorLeftByTable = event.clientX - tableLeftByViewport
const tableLeftByEditor = tableLeftByViewport - editorEl.getBoundingClientRect().left
//accurateLeft 為精準的列分割線上的左偏移量
const { idx: rowIdx, left: accurateLeft } = getNearestRowBorder(nearestTable, cursorLeftByTable)
if (rowIdx !== -1) {
hl.drawHL(nearestTable, tableLeftByEditor + accurateLeft) // 轉(zhuǎn)換為相對 editor 容器的左偏移量
lastState = { tableEl: nearestTable, rowIdx } // 保存 table 元素和 列索引,鼠標按下時要用到。
editorEl.style.cursor = 'col-resize'
} else {
hl.hideHL()
lastState = {}
}
}

然后是拖拽的邏輯。dragState.tableEl 除了記錄保存當前表格元素,還在 moveover 事件中做是否觸發(fā)拖拽的標識。

// 拖拽過程中保存的變量
const emptyDragState = {
tableEl: undefined,
rowIdx: undefined,
col: null,
width: undefined,
left: undefined,
}
let dragState = {...emptyDragState}
function dragMouseDown(event) {
// TODO: 需要點左鍵才執(zhí)行
const { tableEl, rowIdx } = lastState
if (!tableEl) return
const col = getCol(tableEl, rowIdx)
const width = parseFloat(col.style.width)
const left = event.clientX
dragState = { ...dragState, ...lastState, col, width, left }
}
function dragMouseover(event) {
const { left, tableEl, width, rowIdx } = dragState
if (!tableEl) return
const offset = event.clientX - left
setColWidth(tableEl, rowIdx, width + offset)
}
function dragMouseup() {
dragState = {...emptyDragState}
}

結尾

俗話說的好,“Talk is cheap, show me your code!”。如果你對里面的實現(xiàn)細節(jié)感興趣的話,請去我的在線 demo 閱讀源碼和測試:

??https://codepen.io/F-star/pen/eYWjKBg?editors=1010。??

責任編輯:姜華 來源: 今日頭條
相關推薦

2023-04-17 11:03:52

富文本編輯器MTE

2017-07-27 20:21:06

iOSUITableView富文本編輯器

2016-09-23 20:30:54

Javascriptuiwebview富文本編輯器

2013-11-18 10:08:56

工具免費編程工具

2023-05-11 07:34:36

Yjs協(xié)同編輯

2022-03-11 08:00:49

編輯器框架Draft.js

2012-08-10 10:47:45

JavaScript

2018-01-05 14:48:03

前端JavaScript富文本編輯器

2020-12-23 22:25:11

Vi文本編輯器Unix

2010-03-24 09:20:07

CentOS vi編輯

2020-04-09 19:07:12

Vuetiptap前端

2022-02-15 09:00:18

Vue編輯器字符串

2017-02-14 10:00:57

2021-01-07 11:00:59

Sed文本編輯器Linux

2022-05-13 15:32:11

GNOME文本編輯器

2021-01-08 13:56:50

LinuxJOE文本編輯器

2025-05-28 02:02:00

2011-08-24 14:47:55

LUA文本編輯器

2012-09-29 11:38:27

編程工具文本編輯器編程

2022-01-18 09:35:36

GNOME編輯器Linux
點贊
收藏

51CTO技術棧公眾號