设置表格列宽(电脑怎样设置表格列宽)

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

之前因为工作上的一些原因,使用的 wangEditor 富文本编辑器的表格(table)功能并不能满足需求,创建的表格只是设置了 width: 100%,列的宽度的自适应的效果非常不美观。于是决定修改源码,对表格功能做了加强,使其支持调整列宽。

为了方便读者理解,最近把这部分逻辑单独抽离出来并做了优化,写了个能独立运行的 demo,配合这篇文章简单说一说实现思路。

设置表格列宽(电脑怎样设置表格列宽)

实现思路

1. 创建空表格

第一步是创建空表格。要想支持表格可以设置宽度,需要在 table 元素下使用 colgroup 元素。我们根据表格列的数量,在 colgroup 下创建同等数量的 col 元素并设置宽度,就能给对应顺序的列赋予宽度。效果可以查看这个 在线demo 。

此外,表格的单元格如果没有内容,是会发生高度塌陷的,且无法通过 min-height 和 height 设置高度 。为解决这个问题,我们通常会在创建空表格时,给单元格添加 内容。

2. 高亮线的显现

第二步是实现光标划到列之间的分割线上方时,将高亮线显现出来。实现方式是:

  • 初始化时,在编辑器容器元素下创建一个绝对定位的 div 元素作为高亮线,并隐藏。
  • 给编辑器容器元素绑定鼠标移动事件。当光标移动到表格元素内部时,遍历 col 元素得到所有列分隔线的位置(最左边的不需要)。若光标位于这些分隔线附近,拿到左位移量,然后修改高亮线的位置并将其显现出来;否则隐藏高亮线。

3. 拖拽高亮线实现设置列宽

前面提到,当光标悬浮在列分割线上方附近,会出现高亮线。其实为实现修改列宽,我们还要记录一些数据:(1)对应的表格元素;(2)第几列 rowIdx。当然光标移开时,要把这些数据清空。

下面是拖拽这一动作的实现,涉及到鼠标按下、鼠标移动、鼠标释放三个事件:

  • 当鼠标在高亮线上 按下 时,我们要将上面的数据拷贝一份,然后再记录好要修改的(3)列的宽度;(4)光标左偏移量 left(后面要用来计算相对移动位置)(5)对应的 col 元素。
  • 在鼠标按下不释放的情况下,移动鼠标,就代表着 拖拽 这一动作的发生。此时,我们计算光标的相对左移动,给对应的 col 元素设置宽度,就能实现动图上的效果。
  • 鼠标释放,将这些数据重置为空。

因为只需要得到拖拽的相对位置,所以我们不是必须要将事件绑定到编辑器容器上。另外为了确保鼠标释放事件正在发生,最终我选择在 document 元素上绑定事件。document 元素上绑定的鼠标释放事件,按下鼠标后,即便在浏览器外面释放鼠标,也能触发。

另外,为处理列宽过小,甚至计算出负值的情况,我们需要设置一个最小列宽。

代码实现

那么这里就简单讲解一下核心代码。

首先是创建空表格:

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 = '' // 填充点东西,处理单元格高度塌陷问题
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
}

显现高亮线的核心实现逻辑如下。计算左偏移量使用了 getBoundingClientRect() 方法和鼠标事件中得到的 clientX 坐标。其中还需要注意坐标系有 “相对表格” 和 “相对编辑器容器” 两种。

const hl = new HL(editorEl) // 高亮线对象
// ...
let lastState = {} // 高亮线出现时,记录对应的 tableEl 和 rowIdx
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) // 转换为相对 editor 容器的左偏移量
lastState = { tableEl: nearestTable, rowIdx } // 保存 table 元素和 列索引,鼠标按下时要用到。
editorEl.style.cursor = 'col-resize'
} else {
hl.hideHL()
lastState = {}
}
}

然后是拖拽的逻辑。dragState.tableEl 除了记录保存当前表格元素,还在 moveover 事件中做是否触发拖拽的标识。

// 拖拽过程中保存的变量
const emptyDragState = {
tableEl: undefined,
rowIdx: undefined,
col: null,
width: undefined,
left: undefined,
}
let dragState = {...emptyDragState}
function dragMouseDown(event) {
// TODO: 需要点左键才执行
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!”。如果你对里面的实现细节感兴趣的话,请去我的在线 demo 阅读源码和测试:

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

以上内容来源于网络,由“WiFi之家网”整理收藏!

原创文章,作者:电脑教程,如若转载,请注明出处:https://www.224m.com/200204.html

(0)
电脑教程电脑教程
10分钟搭建自己的企业邮箱服务(搭建企业邮箱服务器)
上一篇 2022年10月31日 19:21
纯外行自己修电脑(1)
下一篇 2022年10月31日 20:34

相关推荐

  • 5款自带黑科技的Windows软件(电脑上的黑科技软件)

    很久没有给大家分享电脑软件了,今天给大家带来5款自带黑科技的Windows软件,款款实用到位,千万别错过。 1、PotPlayer 用过电脑自带的视频播放器都知道,它的兼容性不是很…

    2022年11月7日
    3.3K
  • 腾达(Tenda)FS395路由器固定(静态)IP上网设置

    本文介绍了腾达(Tenda)FS395路由器固定(静态)IP上网设置方法,固定(静态)IP上网指的是用户办理宽带业务后,宽带运营商会提供一根网线到用户家里,同事会给用户分配一组IP地址、子网掩码、网关、DNS给用户。在未使用路由器的情况下,用户只需要把宽带运营商提供的入户网线插在电脑上面,然后在自己

    2021年6月16日
    6.0K
  • 腾达路由器限制连接人数的设置方法(腾达路由器有限连接数的设置方法)

    前几天,有粉丝留言求助: 家住在单位宿舍,自己拉了20M的宽带,平时自己一个人用也就够了,但万万没想到引来了一堆 邻居来要WiFi密码,因为都是同事,也不好意思拒绝就让他们用了,但后来越来越多人连上我家的WiFi,网速慢到能急死人,有没有什么办法限制路由器连接的

    2022年2月5日
    14.1K
  • tplogincn怎么登陆(tp的wifi6路由器登录地址是什么)

    本文目录1、tplogincn怎么登陆,tp的wifi6路由器登录地址是什么?2、LINK路由器设置教程?3、tplink吸顶式路由器怎么登录界面?4、app扩展器登录入口?5、tploginco路由器设置?tplogincn怎么登陆旧版本的TP-Link路由器的登陆网址是:192.168.1.1;新版本的TP-Link路由器的登陆网址是:tplogin.c

    2023年7月30日
    27.4K
  • 二手路由器华为怎么设置(华为A2路由器怎么设置)

    二手路由器华为怎么设置(华为A2路由器怎么设置) 如果您购买了一台二手华为A2路由器,您可能需要对路由器进行设置,以确保它能够正常工作并满足您的需求。下面是华为A2路由器设置的详细…

    网络 2023年10月20日
    7.8K
  • Win8系统开始菜单设置为经典模式操作步骤

    原标题:"Win8系统开始菜单怎么设置为经典模式"相关电脑问题教程分享。 - 来源:WiFi之家网。Win8系统因为没有经典的开始菜单而饱受诟病,其实我们可以自己开启经典菜单的,那么怎么开启呢?下面介绍

    2021年7月25日
    6.4K
  • 19216801路由器手机设置入口

    手机192.168.0.1登录本文目录19216801路由器手机设置入口?192.168.0.1.1登录页面设置?192.168.0.1输入密码登录?路由器设备注册怎么登录?192.168.8.1登陆?19216801路由器手机设置入口?1.手机

    192.168.0.1 2022年11月20日
    75.3K
  • 雷柏多模无线刀锋键盘体验(雷柏刀锋键盘怎么样)

    2022年才注册ZEALER不到一个月, 首次在ZEALER得到雷柏刀锋无线键盘E9350G的试用机会!感谢ZEALER和雷柏提供本次产品——雷柏多模无线刀锋键盘 E9350G!拿…

    2023年1月23日
    918
  • TP-Link TL-H69RT路由器无线桥接设置教程

    TP-Link TL-H69RT路由器无线桥接设置方法,在面积较大的场所使用无线路由器时,单台路由器的无线信号覆盖范围有线,部分区域信号较弱或者没有无线信号覆盖。

    2021年4月7日
    13.7K
  • 常用的分类ip地址有(图文)

    【导读】常用的分类ip地址有,下面就是WiFi之家网整理的网络知识百科,来看看吧!大家好,我是191路由器网小编,上述问题将由我为大家讲解。常用的分类ip地址有:  1、A类地址。  A类地址第1字节为

    2021年8月19日
    34.4K