惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
B
Blog
T
The Blog of Author Tim Ferriss
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
Y
Y Combinator Blog
Microsoft Azure Blog
Microsoft Azure Blog
L
LangChain Blog
Recent Announcements
Recent Announcements
U
Unit 42
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Register - Security
The Register - Security
Recorded Future
Recorded Future
C
Check Point Blog
V
V2EX
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
酷 壳 – CoolShell
酷 壳 – CoolShell
F
Full Disclosure
小众软件
小众软件
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
MongoDB | Blog
MongoDB | Blog
爱范儿
爱范儿
P
Proofpoint News Feed
罗磊的独立博客
量子位
D
Docker
博客园_首页
D
DataBreaches.Net
Project Zero
Project Zero
博客园 - 司徒正美
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - Franky
Security Latest
Security Latest
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
Netflix TechBlog - Medium
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 三生石上(FineUI控件)
H
Hackread – Cybersecurity News, Data Breaches, AI and More
大猫的无限游戏
大猫的无限游戏

博客园 - lichdr

高德地图热力图的Flutter实现 App消息推送的简单实现 nginx访问日志过滤(多条件) CAS的service参数验证 自定义Token的CAS登录 单元格的计算 表格行列的删除 FastReport的一些另类用法 FastReport分组页码 RFID会议签到系统总结(二十二)――系统中的模式 RFID会议签到系统总结(二十一)――服务端的通讯 RFID会议签到系统总结(二十)――数据窗体状态控制 RFID会议签到系统总结(十九)――单数据窗体 RFID会议签到系统总结(十八)――菜单与工具栏的加载 RFID会议签到系统总结(十七)――菜单与工具栏的改造(下) RFID会议签到系统总结(十六)――菜单与工具栏按钮的改造(上) RFID会议签到系统总结(十五)――管控端的窗体组织 RFID会议签到系统总结(十四)――管控端业务模块的加载 RFID会议签到系统总结(十三)――模块概述(下)
表格行列的移动
lichdr · 2010-11-09 · via 博客园 - lichdr

  很久以来都在做一些没有营养的东西,即使工作之中有时会有一些比较有技巧性的东西也是基于一些不是非常用的第三方组件的,所以也就没有记下来。前一阵做了个编辑表格列头行头定义的功能,写了一大堆javascript,回头来看看还算有点用途,保不准以后会用到,这二天有空把它整理一下。

  先说明一下,下面的代码都是基于Jquery 1.3.2的。

  因为要动态生成表格的行头列头,所以把一些定义放到数据库中,这些定义包括标题、层级关系、行列融合、序号、以及其他一些跟计算有关的属性定义等。现在就是做一个能编辑这个定义的简单界面,在这篇文章里说说它们之间的顺序调整,即表格行列的移动。

  如果是没有任何行列融合的话,移动是非常容易的,但一旦有了行列融合存在,移动就得考虑很多情况了,同一行的元素还好说,如何找同一列的元素是个问题,所以我最终是对行列头每个单元格都定义了相应的class来标识它们是否是属于同一列的,同一列的class是相同的。

  还有这里假定不会出现奇异表格。即列头从上往下,列融合的数目只会越来越小,最后一个td只占一列;同理行头从左往右,行融合的数目也只会越来越小,最后一个td也只占一行。当移动的时候,如果是碰上有行列融合的,最终移动的时候是把整个融合在一起那些行列移动到新位置的。最后在行头定义的最后一列,列头定义的最后一行,我加入一列(或行)来放置操作符,这也是为了明确当前操作的是哪一行、哪一列,因为这些单元格是铁定只占一行一列的。

  a.列的移动

  主要是讲列的左移,因为右移是可以化为左移来处理的。

操作之前的一些处理

var $column = $(sender).parent();
var className = $column.attr("class");
var preClassName = $column.prev().attr("class");
if (!preClassName)
return;var $row = $column.parent();
var $table = $row.parent();var ri = 0;
var $sCol, $pCol;

那个return,是为了当前列是第一列的情况下直接返回用。

基于不会出现奇异表格的事实,从上往下找当前列的第一个单元格

  $sCol = $table.find("td." + className).eq(0);

记下第一个单元格出行时的行索引

  var mcRowIndex = $table.children("tr").index($sCol.parent());

记下这个索引以后要用。

移动位置与要移动的列数

$pCol = $sCol.prev();

preClassName

= $pCol.attr("class");
var $preOpColumn = $row.children("td." + preClassName);
var preEndIndex = $row.children("td").index($preOpColumn); //移动列时,最终的位置,用操作符所在单元格的列索引来判定最终移动列的位置

var moveCount = 1; //要移动的列数
moveCount = $sCol.attr("colspan");
if (!moveCount)
moveCount
= 1;

位置的取得主要就是利用同列的class相同,以及操作符单元格只占一列这二个特性

下面是多列移动的骨架,单列移动下面单独列出

多列的移动

var moveIndex = 0;
var clsName;
var $mvColumn = $column;
while (moveIndex < moveCount) {
clsName
= $mvColumn.attr("class");
$mvColumn
= $mvColumn.next();
var $preColumn, $iterOpCol, opIndex;
$(
"td." + clsName).each(function() {
//......单列的移动......
});
moveIndex
++;
preEndIndex
++;
}

单独一列的移动,即在那个$("td." + clsName).each()里面的遍历函数

单列的移动

$preColumn = $(this).prev();
$iterOpCol
= $row.children("td." + $preColumn.attr("class")); //前一单元格所在列的操作符单元格
if ($iterOpCol) {
opIndex
= $row.children("td").index($iterOpCol);while (opIndex > preEndIndex) {//找移动目的地的单元格
$preColumn = $preColumn.prev();
$iterOpCol
= $row.children("td." + $preColumn.attr("class")); //前一单元格所在列的操作符单元格
if (!$iterOpCol)
break;
opIndex
= $row.children("td").index($iterOpCol);
}
if (opIndex >= preEndIndex)
$(
this).insertBefore($preColumn);
else
$(
this).insertAfter($preColumn);
}

用一个while (opIndex > preEndIndex)循环找目的地,那是因为表格融合的关系,这一行不一定会存在class名为preClassName的单元格。最终找到的是“它”之前或之后的单元格。

从表象上讲,移动的代码到这里就结束了,但后续操作的关系,还有一个东西要处理,即那些未参与移动的单元格的class的变动。比如:

<tr>
  
<td colspan="2" class="1" />
</tr>
<tr>
  
<td class="1" />
  
<td class="2" />
</tr>

当第2列左移时,第一行那个单元格并没有移动过,最张要把它的class从“1”改为“2”.

这时前面那个mcRowIndex就用得上了。

            $table.children("tr:lt(" + mcRowIndex + ")").children("td." + preClassName).each(function() {
                $(this).attr("class", className);
            });

在mcRowIndex这一行之前的其实都是没有参与移动的。

  b.行的移动

  行的移动处理方式其实跟列的移动差不多,唯一要说明的是,操作符所在那一列是专门定义class的。移动行比移动列简单,一是不用处理class的变换问题,二是交换二行比交换二列要容易。

这里就不作一一解释了。

上移一行

var $row = $(sender).parent().parent();
var $preRow = $row.prev();var $opCol = $row.children("td.op:first");
var $preopCol = $preRow.children("td.op:first");
if ($preopCol.size() == 0)
return;var $rowFCell = $row.children("td:first");
var clsName = $rowFCell.attr("class");
var moveCount = $rowFCell.attr("rowspan");
if (!moveCount)
moveCount
= 1;while ($preRow.children("td." + clsName).size() == 0)
$preRow
= $preRow.prev();var stIndex = $preRow.children("td").index($preRow.children("td." + clsName));
var moveIndex = 0;
var $moveRow = $row;
var $nRow;
while (moveIndex < moveCount) {
$nRow
= $moveRow.next();
$moveRow.insertBefore($preRow);
$moveRow
= $nRow;
moveIndex
++;
}

$preRow.children(

"td:lt(" + stIndex + ")").each(function() {
$(
this).insertBefore($rowFCell);
});

下移一行也可以化为上移一行处理的,这里略。