[英]Select text in a column of an html table
是否可以 select HTML 表的一个垂直列中的每个单元格的文本(即突出显示以便可以复制+粘贴)。
是否有 JavaScript 方法,或者在某些浏览器中可能与许多文本编辑器中使用的 Alt-Click-Drag 快捷方式等效?
或者这是不可能的?
您要查找的内容称为Range
object(IE 中的TextRange
)。
更新:这是执行您建议的工作代码: http://jsfiddle.net/4BwGG/3/
在捕获单元格内容时,您可以以任何您希望的方式对其进行格式化。 我只是每次都添加一个新行。
笔记:
另一种方法是应用 CSS 样式,该样式模拟单击 header 列时突出显示并遍历所有单元格以捕获其内容。 这种方法的外观和感觉可能与原生选择的外观不同(除非您以某种方式捕获 select 事件并更改外观)。
然后使用 jQuery 复制插件将它们复制到剪贴板。
一些代码审查工具实现了这一点,以允许从并排差异的一侧复制和粘贴代码。 我研究了ReviewBoard是如何做到这一点的。
要点是:
user-select: none
(及其前缀变体,如有必要)设置所有其他列中的单元格样式。 这将创建列选择的外观。 其他栏目还是偷偷选的,所以你要...copy
事件并更改其有效负载以反映所选列的内容。执行此操作的 ReviewBoard 代码包含此 CSS和此 JavaScript 。
我将它提取到一个相当小的jsbin 演示中。
这是CSS,可以创建单列选择的外观(您将selecting-left
selecting-right
添加到左列被选择时,
.selecting-left td.right,
.selecting-left td.right *,
.selecting-right td.left,
.selecting-right td.left *,
user-select: none;
}
.selecting-left td.right::selection,
.selecting-left td.right *::selection,
.selecting-right td.left::selection,
.selecting-right td.left *::selection,
background: transparent;
}
这是 JavaScript 拦截copy
事件并插入单个列的数据:
tableEl.addEventListener('copy', function(e) {
var clipboardData = e.clipboardData;
var text = getSelectedText();
clipboardData.setData('text', text);
e.preventDefault();
});
function getSelectedText() {
var sel = window.getSelection(),
range = sel.getRangeAt(0),
doc = range.cloneContents(),
nodes = doc.querySelectorAll('tr'),
text = '';
var idx = selectedColumnIdx; // 0 for left, 1 for right
if (nodes.length === 0) {
text = doc.textContent;
} else {
[].forEach.call(nodes, function(tr, i) {
var td = tr.cells[tr.cells.length == 1 ? 0 : idx];
text += (i ? '\n' : '') + td.textContent;
});
}
return text;
}
还有一些不太有趣的代码可以在选择的开头添加selecting-left
和selecting-right
类。 这将需要更多的工作来推广到 n 列表。
这在实践中似乎效果很好,但令人惊讶的是它有多难!
您可以有一个 div,在单击时填充列数据并应用 css class 以使列具有被选中的外观
像这样的东西:
var $mytable = $("#mytable"),
$copydiv = $("#copy_div");
$mytable.find("td").click(function(){
//get the column index
var $this = $(this),
index = $this.parent().children().index($this);
//find all cells in the same column
$mytable.find("tr:nth-child(" + index + ")").removeClass("selected").each(function () {
var $this = $(this);
$this.addClass("selected");
$copydiv.html($this.html() + "<br />");
});
});
或者您可以为每一列设置一个单独的表格,但我认为这不值得。
这是一个完全不涉及 javascript 的 hack:
对于 Mac 上的 Chrome,请按command
+ option
+ J
。
对于 Mac 上的 Chrome,单击检查器左上角的选择器图标进入选择器模式。
然后单击表中的随机单元格。
然后输入这个规则(你可能想根据你的 HTML 稍微修改一下)
tr td {
display: none; # hide all cells
}
现在所有的细胞都应该消失了。
Go 前面并在该规则之上添加另一条规则:
tr td:nth-child(2) { # replace 2 with the index of the column you want to copy. 2 means the second column
display: table-cell; # display that column
}
现在,您要从中复制的列应该已经重新出现了。
所有其他列应该是不可见的并且不能被选中。
您可以通过刷新来恢复页面。
如果您只想 select 一两列,我发现这项工作非常完美。
新的:has()选择器给了我在没有 JS 的情况下解决这个问题的希望。 这个想法是禁用所有单元格的文本选择,并且只为悬停的列的单元格激活它。
所以你会有这样的规则:
table:has(tr td:nth-child(1):hover) tr td:nth-child(1) {
-webkit-user-select: auto;
user-select: auto;
}
可在此处找到完整示例: https://codepen.io/catlan/pen/XWELegW
这是正在进行中的工作,因为在当前版本的 Safari (15.6.1) 中,文本范围的显示在选择完成后消失,仅在移动 cursor 几个像素后重新出现。 见https://bugs.webkit.org/show_bug.cgi?id=244445
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.