DOM 树向下递归
这是来自 Crockford 的 JavaScript:The Good Parts 的代码。
var results = [];
var walkDOM = function (node,func) {
func(node); //What does this do?
node = node.firstChild;
while(node) {
walkDOM(node,func);
node = node.nextSibling;
}
};
我理解除了 func(node)
之外的代码。我想重点是在函数 func
中将 node
作为参数传递,但是浏览器如何以这种方式理解它呢? node
和 func
可以是任何东西——所以当调用该函数时,它可以读成这样:
walkDOM(document.body,function(att) {
node.getAttribute(att);
results.push(node);
});
当传递 func
时,walkDOM
将处理 function(att) {...}(document.body)——这没有任何意义。那么为什么 Crockford 选择包含 func(node) 呢?
This is code from Crockford's JavaScript: The Good Parts.
var results = [];
var walkDOM = function (node,func) {
func(node); //What does this do?
node = node.firstChild;
while(node) {
walkDOM(node,func);
node = node.nextSibling;
}
};
I understand the code except for func(node)
. I guess the point is to pass node
as a parameter in function func
, but how will the browser understand it this way? node
and func
could be anything--so when the function is called it could read like this:
walkDOM(document.body,function(att) {
node.getAttribute(att);
results.push(node);
});
When func
is passed, walkDOM
will process function(att) {...}(document.body)--which wouldn't make any sense. So why has Crockford chosen to include func(node)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,这个树遍历函数是有意义的,因为:
document.body
,如果func 不知道如何处理它)也就是说,这个算法对我来说仍然看起来不正确,因为它只探索第一个兄弟;其他兄弟姐妹将被简单地忽略。因此,我建议使用这种更传统的方法:
请注意,版本是“深度优先”(即在处理子项之前不调用 call
func()
),但我宁愿推荐它,因为func
可能会改变节点。这样,父进程的处理将能够在发出可能不适当的更改之前考虑其已处理的子进程的最新状态。Yes this tree traversal function makes sense since :
document.body
for instance, if func doesn't know how to handle it)That said, this algorithm still looks incorrect to me, as it only explores through the first sibling ; other siblings will be simply ignored. So I would recommend using this more traditional approach instead :
Note that version is "deep first" (i.e. not calling call
func()
before processing children), but I'd rather recommend it sincefunc
is likely to change nodes. This way the processing of a parent will be able to consider the latest state of its already-processed children before issuing possibly un-appropriate changes.在我看来,func 用于对树中的每个节点执行某些操作。
例如,如果我想提醒整个树中每个节点的标签名称:
在您的示例函数中:
...您已将
node
参数命名为att
,但这并不能神奇地生成属性的名称。我希望运行node.getAttribute(att)
时出现“变量'node'未定义”,因为节点被设置为att
...没有该函数范围内的node
。Looks to me like the
func
is used for doing something to every node in the tree.For example, if I wanted to alert the tag name for every node in the entire tree:
In your example function:
... you have named the
node
parameter toatt
, but that doesn't magically make in a name of an attribute. I would expect a "variable 'node' is not defined" whennode.getAttribute(att)
is ran, because node is being set toatt
... there is nonode
in that function's scope.该行中的
func
就是通常所说的回调函数。它是可供
walkDOM
函数使用的函数。使用更详细的函数名称可能会有意义:希望这可以帮助您解决问题。
The
func
that's in theline is what is typically known as a callback function. It a function that is available for use by the
walkDOM
function. It might make sense with a more verbose function name:Hope this clears things up for you.
Crockford 的代码将回调传递给 walkDOM,它可以通过多种方式使用来处理传递给它的参数。
一个示例是返回具有指定 tagName 的所有 DOM 元素的计数的方法:
Crockford's code is passing a callback to walkDOM which can be used in many ways to process the arguments passed to it.
An example could be a method which returns the count of all DOM elements with the specified tagName: