javascript 选择 html 表格列中的文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6619805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:18:17  来源:igfitidea点击:

Select text in a column of an html table

javascripthtml

提问by cbp

Is it possible to select the text (i.e. have it highlighted so that it can be copy+pasted) of every cell in one vertical column of an HTML table.

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

Is there a JavaScript method, or perhaps an equivalent in some browsers to the Alt-Click-Drag shortcut used in many text editors?

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

Or is this impossible?

或者这是不可能的?

采纳答案by Mrchief

What you're looking for is called Rangeobject (TextRangein IE).

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

Update:Here's a working code to do what you're suggesting: http://jsfiddle.net/4BwGG/3/

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

While capturing cell contents, you can format them in any manner you wish. I'm simply appending a new line every time.

在捕获单元格内容时,您可以按照您希望的任何方式设置它们的格式。我只是每次都添加一个新行。

Note:

笔记:

  • Works fine in FF 3 and above
  • IE (before 9) and Chrome do not support multiple selection.
  • Chrome doesn't highlight all cells (but captures all content). Same goes for IE9
  • IE 7 & 8 will throw an error.
  • 在 FF 3 及更高版本中工作正常
  • IE(9 之前)和 Chrome 不支持多选。
  • Chrome 不会突出显示所有单元格(但会捕获所有内容)。IE9 也一样
  • IE 7 & 8 会抛出错误。

An alternative is apply a CSS style that simulateshighlighting on click of column header and loop through all cells to capture their content. Look and feel of this approach may differ from native selection's look (unless you somehow capture select event and alter the appearnce).

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

Then use jQuery copy plugin to copy them to clipboard.

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

回答by danvk

Some code review tools implement this to allow copying & pasting code from one side of a side-by-side diff. I looked into how ReviewBoardpulls it off.

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

The gist is:

要点是:

  1. When a column selection begins, style the cells in all other columns with user-select: none(and its prefixed variants, if necessary). This creates the appearance of a column selection. The other columns are still secretly selected, so you have to...
  2. Intercept the copyevent and change its payload to reflect the contents of the selected column.
  1. 当列选择开始时,将所有其他列中的单元格样式设置为user-select: none(及其前缀变体,如有必要)。这将创建列选择的外观。其他栏目还是偷偷选择的​​,所以你要……
  2. 拦截copy事件并更改其有效负载以反映所选列的内容。

The ReviewBoard code to do this consists of this CSSand this JavaScript.

执行此操作的 ReviewBoard 代码由此 CSS此 JavaScript 组成

I pulled it out into a fairly minimal jsbin demo.

我把它拉成一个相当小的jsbin 演示

Here's the CSS to create the appearance of a single-column selection (you add the selecting-leftclass to the table when the left column is being selected, or selecting-rightfor the right):

Here's the CSS to create the appearance of a single-column selection (you add the selecting-leftclass to the table when the left column is being selected, or selecting-rightfor the 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;
}

Here's the JavaScript to intercept the copyevent and plug in a single column's worth of data:

这是拦截copy事件并插入单列数据的 JavaScript :

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;
}

There's also some less interesting code to add the selecting-leftand selecting-rightclasses at the start of a selection. This would require a bit more work to generalize to n-column tables.

还有一些不太有趣的代码可以在选择开始时添加selecting-leftselecting-right类。这将需要更多的工作来推广到 n 列表。

This seems to work well in practice, but it's surprising how hard it is!

这在实践中似乎很有效,但令人惊讶的是它有多难!

回答by Ilia Choly

You could have a div which gets populated with the column data on click and apply a css class to give the columns the appearence of being selected

你可以有一个 div,它在点击时填充列数据并应用一个 css 类来使列看起来被选中

something like this:

像这样:

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 />");
    });
});

or you could have a separate table for each column, but I don't think that would be worth it.

或者您可以为每一列设置一个单独的表格,但我认为这不值得。