js实现复制到剪贴板 document.createRange() API
选中元素→range→selection是一一对应的,即选区必须连续,不可以有分开的多个区域。另外,被选元素必须在dom树上,不可以是游离元素,并且实践发现display不能为none,visibility不能为hidden,即使不需要渲染。也就是说我可以创建一个游离元素,插入dom树,选择后copy,然后立刻从dom树移出,整个过程都在浏览器下一次渲染之前,所以页面上没有任何变化。
为了实现选中分开的三列table,最后的方案就是用原来的内容新建一个3列的table,按上述步骤插入body,复制后再移除。
代码:
/* 创建range对象 */
const range = document.createRange();
range.selectNode(element); // 设定range包含的节点对象
/* 窗口的selection对象,表示用户选择的文本 */
const selection = window.getSelection();
if (selection.rangeCount > 0) selection.removeAllRanges(); // 将已经包含的已选择的对象清除掉
selection.addRange(range); // 将要复制的区域的range对象添加到selection对象中
document.execCommand('copy'); // 执行copy命令,copy用户选择的文本
相关文档:
Introduction
A Range identifies a range of content in a Document, DocumentFragment or Attr. It is contiguous in the sense that it can be characterized as selecting all of the content between a pair of boundary-points.
2.3. Creating a Range
A Range is created by calling the createRange()
method on the DocumentRange
interface. This interface can be obtained from the object implementing the Document
interface using binding-specific casting methods.
interface DocumentRange {
Range createRange();
}
The initial state of the Range returned from this method is such that both of its boundary-points are positioned at the beginning of the corresponding Document, before any content. In other words, the container of eachboundary-point is the Document node and the offset within that node is 0.
Like some objects created using methods in the Document interface (such as Nodes and DocumentFragments), Ranges created via a particular document instance can select only content associated with that Document, or with DocumentFragments and Attrs for which that Document is the ownerDocument
. Such Ranges, then, can not be used with other Document instances.
addRange
- Set the context object's range to range by a strong reference (not by making a copy).
A selection object represents the ranges
that the user has selected. Typically, it holds only one range, As the Selection API specification notes, the Selection API was initially created by Netscape and used multiple ranges, for instance, to allow the user to select a column from a <table>
. However browsers other than Gecko did not implement multiple ranges, and the specification also requires the selection to always have a single range.
Originally, the Selection interface was a Netscape feature. The original implementation was carried on into Gecko (Firefox), and the feature was later implemented independently by other browser engines. The Netscape implementation always allowed multiple ranges in a single selection, for instance so the user could select a column of a table However, multi-range selections proved to be an unpleasant corner case that web developers didn't know about and even Gecko developers rarely handled correctly. Other browser engines never implemented the feature, and clamped selections to a single range in various incompatible fashions.
This specification follows non-Gecko engines in restricting selections to at most one range, but the API was still originally designed for selections with arbitrary numbers of ranges. This explains oddities like the coexistence of removeRange()
and removeAllRanges()
, and agetRangeAt()
method that takes an integer argument that must always be zero.
3.background-attachment 设为fixed会相对于视口静止,相当于给window设置的background,定位会以整个视口为基准(同position:fixed),不再以设置的元素为基准
4. 对checkbox来说,点击时先改变checked属性(prop里的),再触发click事件,最后触发change事件。vue对checkbox的双向绑定是在change事件里改变数据的,对有v-model的checkbox绑定click事件时要注意此时数据还没有同步(只有DOM对象变成checked了。)
checkbox里这两个事件的触发顺序,不同浏览器里可能不同
5. 伪元素的content属性可以用attr()函数,获取元素的attr属性值