我有一张简单的表格:
Column A | Column B
--------------------
A | Item1
B | Item2
C | Item3
我想让第一列不可复制。当用户选择表格行并按Ctrl + C时,他应该只是
Item1
Item2
Item3
但不是
A Item1
B Item2
C Item3
我试过了-moz-user-select: none; -webkit-user-select: none; user-select: none;
,但它没有用。文本未被选中但仍被复制。它适用于Firefox,但不适用于Chrome和Opera。
解决方案对我有用: 由于高度()不准确,它仍然闪烁并略微修改行高,但对我来说还是可以的。
$(document).on('copy', function(e) {
if (navigator.userAgent.indexOf("Firefox")==-1) {
var nonCopyable = $('.nonCopyable:not(.empty)');
nonCopyable.each(function(index,el) {
var $el = $(el);
if ( $el.hasClass('empty') ) {
return;
}
var width = $(el).width();
var height = $(el).height();
$el.data('content', $el.html()).css({"width" : width+'px', "height": height + 'px'} ).html('');
}).addClass('empty');
setTimeout(function() {
nonCopyable.each(function(index,el) {
$(el).html($(el).data('content')).removeClass('empty').css({"width":'auto', height:'auto'}).data('content',null);
}); });
}
} );
.nonCopyable {
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
当然,如果您在不可复制的单元格(如事件处理程序)中不仅包含文本和图像,那么您需要另一种解决方法。
答案 0 :(得分:4)
我不确定这是否符合您的需求(因为不兼容与Internet Explorer)但是一个选项是使用::before
/ {{1伪元素生成第一列内容并阻止其被选中/复制。
同样要关注DRY principle,我们可以使用::after
属性来定义内容,然后使用data-*
表达式将其分配给伪元素。
attr()
table > tbody td:first-child::before {
content: attr(data-content);
}
table > thead th:first-child::before {
content: attr(data-content);
}
答案 1 :(得分:1)
我找到了一个相当疯狂的解决方案来解决这个问题。当您检测到Ctrl + C keydown事件时,您可以完全隐藏左列,从而将其从选择中删除(至少在Firefox 36.0.1,IE11,Safari 5.1.7和Chrome 41中执行此操作),并设置超时立即重新显示列。最终结果是复制操作只获得右列中的文本。当左栏消失然后重新出现时,用户可能会看到一个奇怪的小闪烁,但我发现它在大多数时候都不明显。
$(document).keydown(function(e) {
if (e.ctrlKey && e.keyCode == 67) {
$('.cellNumber').hide();
setTimeout(function() { $('.cellNumber').show(); });
} // end if
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr><td class="cellNumber">Column A</td><td>Column B</td></tr>
<tr><td class="cellNumber">A</td><td>Item1</td></tr>
<tr><td class="cellNumber">B</td><td>Item2</td></tr>
<tr><td class="cellNumber">C</td><td>Item3</td></tr>
</table>
还应该注意,这仅适用于Ctrl + C按键。您可以将其扩展为适用于Mac用户的Cmd + C按键,但仍然不能涵盖其他复制方式,例如鼠标右键单击复制和菜单栏编辑复制。
编辑:太棒了!我刚刚发现你实际上可以使用copy事件来获取上述复制方法的所有:
$(document).on('copy', function(e) {
$('.cellNumber').hide();
setTimeout(function() { $('.cellNumber').show(); });
} );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr><td class="cellNumber">Column A</td><td>Column B</td></tr>
<tr><td class="cellNumber">A</td><td>Item1</td></tr>
<tr><td class="cellNumber">B</td><td>Item2</td></tr>
<tr><td class="cellNumber">C</td><td>Item3</td></tr>
</table>
这适用于我测试的每个浏览器/系统(Mac上的Firefox,Chrome和Safari,以及Windows上的Firefox,Chrome,Safari和IE)以及每种复制方法(鼠标,菜单栏和Ctrl + C) / Cmd的+ C)。
答案 2 :(得分:-1)
嗯,如果您三次点击B列单元格,它只会选择B列。我不认为您可以阻止访问者选择这两个单元格。
这看起来也像是ul的情况,而不是表格。如果他们复制了文本,他们就不会得到数字。
答案 3 :(得分:-1)
我不喜欢这个想法 - 但也许你应该尝试在表格单元格的顶部添加一个绝对定位的div,这是不可复制的。确保此div具有比表格单元格更高的z-index。这样可以防止用户选择文本,从而复制文本。