处理空白

处理空白

在 DOM 中处理空白

如前所述,空白在渲染时会被折叠和修剪,但在 DOM 中是保留的。这在尝试用 JavaScript 进行 DOM 操作时可能会带来一些陷阱。例如,如果你有一个父节点的引用,并想用 Node.firstChild 来操作它的第一个元素子节点,父节点开始标签后的一个意外的空白节点会给你错误的结果。该文本节点会被选中,而不是你想要的目标元素。

再举一个例子,如果你想对一部分元素根据它们是否为空(没有子节点)来做某些操作,你可以使用 Node.hasChildNodes()。但如果这些元素中任何一个包含了文本节点,你可能会得到错误的结果。

以下 JavaScript 代码展示了几个函数,可以更容易地处理 DOM 中的空白:

js/**

* Throughout, whitespace is defined as one of the characters

* "\t" TAB \u0009

* "\n" LF \u000A

* "\r" CR \u000D

* " " SPC \u0020

*

* This does not use JavaScript's "\s" because that includes non-breaking

* spaces (and also some other characters).

*/

/**

* Determine whether a node's text content is entirely whitespace.

*

* @param nod A node implementing the `CharacterData` interface (i.e.,

* a `Text`, `Comment`, or `CDATASection` node)

* @return `true` if all of the text content of `nod` is whitespace,

* otherwise `false`.

*/

function isAllWs(nod) {

return !/[^\t\n\r ]/.test(nod.textContent);

}

/**

* Determine if a node should be ignored by the iterator functions.

*

* @param nod An object implementing the `Node` interface.

* @return `true` if the node is:

* 1) A `Text` node that is all whitespace

* 2) A `Comment` node

* and otherwise `false`.

*/

function isIgnorable(nod) {

return (

nod.nodeType === 8 || // a comment node

(nod.nodeType === 3 && isAllWs(nod))

); // a text node, all ws

}

/**

* Version of `previousSibling` that skips nodes that are entirely

* whitespace or comments. (Normally `previousSibling` is a property

* of all DOM nodes that gives the sibling node, the node that is

* a child of the same parent, that occurs immediately before the

* reference node.)

*

* @param sib The reference node.

* @return The closest previous sibling to `sib` that is not

* ignorable according to `isIgnorable`, or `null` if

* no such node exists.

*/

function nodeBefore(sib) {

while ((sib = sib.previousSibling)) {

if (!isIgnorable(sib)) {

return sib;

}

}

return null;

}

/**

* Version of `nextSibling` that skips nodes that are entirely

* whitespace or comments.

*

* @param sib The reference node.

* @return The closest next sibling to `sib` that is not

* ignorable according to `isIgnorable`, or `null`

* if no such node exists.

*/

function nodeAfter(sib) {

while ((sib = sib.nextSibling)) {

if (!isIgnorable(sib)) {

return sib;

}

}

return null;

}

/**

* Version of `lastChild` that skips nodes that are entirely

* whitespace or comments. (Normally `lastChild` is a property

* of all DOM nodes that gives the last of the nodes contained

* directly in the reference node.)

*

* @param sib The reference node.

* @return The last child of `sib` that is not ignorable

* according to `isIgnorable`, or `null` if no

* such node exists.

*/

function lastChild(par) {

let res = par.lastChild;

while (res) {

if (!isIgnorable(res)) {

return res;

}

res = res.previousSibling;

}

return null;

}

/**

* Version of `firstChild` that skips nodes that are entirely

* whitespace and comments.

*

* @param sib The reference node.

* @return The first child of `sib` that is not ignorable

* according to `isIgnorable`, or `null` if no

* such node exists.

*/

function firstChild(par) {

let res = par.firstChild;

while (res) {

if (!isIgnorable(res)) {

return res;

}

res = res.nextSibling;

}

return null;

}

/**

* Version of `data` that doesn't include whitespace at the beginning

* and end and normalizes all whitespace to a single space. (Normally

* `data` is a property of text nodes that gives the text of the node.)

*

* @param txt The text node whose data should be returned

* @return A string giving the contents of the text node with

* whitespace collapsed.

*/

function dataOf(txt) {

let data = txt.textContent;

data = data.replace(/[\t\n\r ]+/g, " ");

if (data[0] === " ") {

data = data.substring(1, data.length);

}

if (data[data.length - 1] === " ") {

data = data.substring(0, data.length - 1);

}

return data;

}

以下代码演示了上述函数的使用。它遍历一个元素的所有子元素,找到文本内容为 "This is the third paragraph" 的那个,然后更改该段落的 class 属性和内容。

jslet cur = firstChild(document.getElementById("test"));

while (cur) {

if (dataOf(cur.firstChild) === "This is the third paragraph.") {

cur.className = "magic";

cur.firstChild.textContent = "This is the magic paragraph.";

}

cur = nodeAfter(cur);

}

相关阅读

宂碎的解释及意思
365体育直播下载安装

宂碎的解释及意思

⌚ 08-07 👁️ 5826
计算机犯罪的类型与法律规制
365提款成功但是不到账

计算机犯罪的类型与法律规制

⌚ 10-04 👁️ 962
如何计算项目目标成本
365提款成功但是不到账

如何计算项目目标成本

⌚ 07-08 👁️ 1781