繁体   English   中英

html 表的列中的 Select 文本

[英]Select text in a column of an html table

是否可以 select HTML 表的一个垂直列中的每个单元格的文本(即突出显示以便可以复制+粘贴)。

是否有 JavaScript 方法,或者在某些浏览器中可能与许多文本编辑器中使用的 Alt-Click-Drag 快捷方式等效?

或者这是不可能的?

您要查找的内容称为Range object(IE 中的TextRange )。

更新:这是执行您建议的工作代码: http://jsfiddle.net/4BwGG/3/

在捕获单元格内容时,您可以以任何您希望的方式对其进行格式化。 我只是每次都添加一个新行。

笔记:

  • 在 FF 3 及更高版本中运行良好
  • IE(9 之前)和 Chrome 不支持多选。
  • Chrome 不会突出显示所有单元格(但会捕获所有内容)。 IE9 也一样
  • IE 7 & 8 会抛出错误。

另一种方法是应用 CSS 样式,该样式模拟单击 header 列时突出显示并遍历所有单元格以捕获其内容。 这种方法的外观和感觉可能与原生选择的外观不同(除非您以某种方式捕获 select 事件并更改外观)。

然后使用 jQuery 复制插件将它们复制到剪贴板。

一些代码审查工具实现了这一点,以允许从并排差异的一侧复制和粘贴代码。 我研究了ReviewBoard是如何做到这一点的。

要点是:

  1. 当列选择开始时,使用user-select: none (及其前缀变体,如有必要)设置所有其他列中的单元格样式。 这将创建列选择的外观。 其他栏目还是偷偷选的,所以你要...
  2. 拦截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-leftselecting-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

步骤2:select 使用选择器工具随机单元格

对于 Mac 上的 Chrome,单击检查器左上角的选择器图标进入选择器模式。 在此处输入图像描述

然后单击表中的随机单元格。

第 3 步:通过编辑 CSS 隐藏所有单元格

单击“ New Style Rule按钮(见下图) 在此处输入图像描述

然后输入这个规则(你可能想根据你的 HTML 稍微修改一下)

tr td {
    display: none; # hide all cells
}

现在所有的细胞都应该消失了。

第 4 步:通过编辑 CSS 仅显示您想要的列

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
}

现在,您要从中复制的列应该已经重新出现了。

所有其他列应该是不可见的并且不能被选中。

第 5 步:只需复制该列!

笔记

  • 您可以通过刷新来恢复页面。

  • 如果您只想 select 一两列,我发现这项工作非常完美。

WIP:CSS 唯一解决方案使用:has() 选择器

新的: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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM