javascript - 将 Range 或 DocumentFragment 转换为字符串

标签 javascript selection range tostring documentfragment

有没有办法在 W3C 兼容的浏览器中获取 JavaScript Range 对象的 html 字符串?

例如,假设用户选择以下内容:Hello <b>World</b>
可以使用 Range.toString() 以字符串形式获取“Hello World”方法。 (在 Firefox 中,也可以使用文档getSelection 方法。)

但我似乎找不到获取内部 HTML 的方法。

经过一番搜索,我发现范围可以转换为 DocumentFragment对象。

但是DocumentFragments没有innerHTML属性(至少在 Firefox 中;尚未尝试过 Webkit 或 Opera)。
这对我来说似乎很奇怪:显然应该有某种方法来访问所选项目。

我意识到我可以创建一个 documentFragment ,将文档片段附加到另一个元素,然后得到 innerHTML该元素的。
但该方法将自动关闭我选择的区域内的所有打开的标签。
除此之外,肯定有一个明显的“更好的方法”,而不是将其附加到 dom 只是为了将其作为字符串获取。

那么,如何获取Range或DocFrag的html字符串呢?

最佳答案

So, how to get the string of the html of a Range or DocFrag?

与其他响应相反,可以使用 XMLSerializer.prototype 直接将 DocumentFragment 对象转换为 DOMString https://w3c.github.io/DOM-Parsing/#the-xmlserializer-interface 中描述的 .serializeToString 方法.

要获取 Range 对象的 DOMString,只需使用 Range.prototype 将其转换为 DocumentFragment 即可。 cloneContentsRange.prototype.extractContents 方法,然后按照 DocumentFragment 对象的过程进行操作。

我附上了一个演示,但其要点在于这两行:

const serializer = new XMLSerializer();
const document_fragment_string = serializer.serializeToString(document_fragment);

(() => {
	"use strict";
	const HTML_namespace = "http://www.w3.org/1999/xhtml";
	document.addEventListener("DOMContentLoaded", () => {
		/* Create Hypothetical User Range: */
		const selection = document.defaultView.getSelection();
		const user_range_paragraph = document.getElementById("paragraph");
		const user_range = document.createRange();
		user_range.setStart(user_range_paragraph.firstChild, 0);
		user_range.setEnd(user_range_paragraph.lastChild, user_range_paragraph.lastChild.length || user_range_paragraph.lastChild.childNodes.length);
		selection.addRange(user_range);

		/* Clone Hypothetical User Range: */
		user_range.setStart(selection.anchorNode, selection.anchorOffset);
		user_range.setEnd(selection.focusNode, selection.focusOffset);
		const document_fragment = user_range.cloneContents();

		/* Serialize the User Range to a String: */
		const serializer = new XMLSerializer();
		const document_fragment_string = serializer.serializeToString(document_fragment);

		/* Output the Serialized User Range: */
		const output_paragraph = document.createElementNS(HTML_namespace, "p");
		const output_paragraph_code = document.createElementNS(HTML_namespace, "code");
		output_paragraph_code.append(document_fragment_string);
		output_paragraph.append(output_paragraph_code);
		document.body.append(output_paragraph);
	}, { "once": true });
})();
<p id="paragraph">Hello <b>World</b></p>

关于javascript - 将 Range 或 DocumentFragment 转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4896944/

相关文章:

ms-access - Access VBA : How to count items of a ComboBox?

html - 基于范围 slider 拇指悬停的元素样式

javascript - 选择的奇怪行为

mysql - 检查表的时间重叠?

mysql - 如何在 find() cakephp 中指定范围

javascript - backbone.js 事件和 el

javascript - React Flux 实现调度链

php - 来自 PHP 的 JSON 对象值

javascript - 正则表达式: Matching a non digit character BESIDES a certain character

date - 选择以今天为默认日期的选项?