- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
注意:在假定此问题重复之前,此问题底部有一个部分说明了为什么一些类似的问题没有提供我正在寻找的答案。
我们都知道将 NodeList 转换为 Array 很容易,并且有很多方法可以做到这一点:
[].slice.call(someNodeList)
// or
Array.from(someNodeList)
// etc...
我追求的是相反的; 如何将节点数组转换为静态 NodeList?
在不深入的情况下,我正在创建一种新方法来查询页面上的元素,即:
Document.prototype.customQueryMethod = function (...args) {...}
为了忠实于 querySelectorAll
的工作原理,我想返回一个 static collection NodeList
而不是数组。
到目前为止,我已经通过三种不同的方式解决了这个问题:
function createNodeList(arrayOfNodes) {
let fragment = document.createDocumentFragment();
arrayOfNodes.forEach((node) => {
fragment.appendChild(node);
});
return fragment.childNodes;
}
虽然这确实会返回一个 NodeList,但这不起作用,因为调用 appendChild
会将节点从其在 DOM 中的当前位置(它应该停留的位置)移除。
另一种变体涉及克隆
节点并返回克隆。但是,现在您要返回克隆的节点,这些节点没有引用 DOM 中的实际节点。
const FakeNodeList = (() => {
let fragment = document.createDocumentFragment();
fragment.appendChild(document.createComment('create a nodelist'));
function NodeList(nodes) {
let scope = this;
nodes.forEach((node, i) => {
scope[i] = node;
});
}
NodeList.prototype = ((proto) => {
function F() {
}
F.prototype = proto;
return new F();
})(fragment.childNodes);
NodeList.prototype.item = function item(idx) {
return this[idx] || null;
};
return NodeList;
})();
它将以下列方式使用:
let nodeList = new FakeNodeList(nodes);
// The following tests/uses all work
nodeList instanceOf NodeList // true
nodeList[0] // would return an element
nodeList.item(0) // would return an element
虽然这种特殊方法不会从 DOM 中删除元素,但会导致其他错误,例如将其转换为数组时:
let arr = [].slice.call(nodeList);
// or
let arr = Array.from(nodeList);
以上每个都会产生以下错误:Uncaught TypeError: Illegal invocation
我还试图避免使用伪造的节点列表构造函数“模仿”节点列表,因为我认为这可能会在未来产生意想不到的后果。
function createNodeList(arrayOfNodes) {
arrayOfNodes.forEach((node) => {
node.setAttribute('QUERYME', '');
});
let nodeList = document.querySelectorAll('[QUERYME]');
arrayOfNodes.forEach((node) => {
node.removeAttribute('QUERYME');
});
return nodeList;
}
这工作得很好,直到我发现它不适用于某些元素,例如 SVG
的。它不会附加属性(尽管我只在 Chrome 中测试过)。
看起来这应该是一件容易的事,为什么我不能使用 NodeList 构造函数来创建一个 NodeList,为什么我不能以类似于 NodeLists 转换为数组的方式将数组转换为 NodeList ?
答案不适合我的类似问题:
以下问题与本题类似。不幸的是,由于以下原因,这些问题/答案无法解决我的特定问题。
How can I convert an Array of elements into a NodeList?这个问题的答案使用了克隆节点的方法。这行不通,因为我需要访问原始节点。
Create node list from a single node in JavaScript使用文档片段方法(尝试 1)。其他答案在尝试 2 和 3 中尝试了类似的事情。
Creating a DOM NodeList正在使用 E4X
,因此不适用。即使它正在使用它,它仍然会从 DOM 中删除元素。
最佳答案
why can't I use the NodeList constructor to create a NodeList
因为 DOM specification for the NodeList
interface未指定 the WebIDL [Constructor] attribute , 所以它不能直接在用户脚本中创建。
why can't I cast an array to a NodeList in a similar fashion that NodeLists are cast to arrays?
在您的情况下,这肯定是一个有用的函数,但 DOM 规范中没有指定存在这样的函数。因此,不可能从 Node
数组直接填充 NodeList
。
虽然我严重怀疑您会称之为“正确的方式”来处理事情,但一个丑陋的解决方案是找到 CSS 选择器来唯一地选择您想要的元素,并将所有这些路径传递到 querySelectorAll
作为逗号分隔的选择器:
// find a CSS path that uniquely selects this element
function buildIndexCSSPath(elem) {
var parent = elem.parentNode;
// if this is the root node, include its tag name the start of the string
if(parent == document) { return elem.tagName; }
// find this element's index as a child, and recursively ascend
return buildIndexCSSPath(parent) + " > :nth-child(" + (Array.prototype.indexOf.call(parent.children, elem)+1) + ")";
}
function toNodeList(list) {
// map all elements to CSS paths
var names = list.map(function(elem) { return buildIndexCSSPath(elem); });
// join all paths by commas
var superSelector = names.join(",");
// query with comma-joined mega-selector
return document.querySelectorAll(superSelector);
}
toNodeList([elem1, elem2, ...]);
这通过查找 CSS 字符串来唯一选择每个元素,其中每个选择器的形式为 html > :nth-child(x) > :nth-child(y) > :nth-child(z) ...
。也就是说,每个元素都可以理解为作为子元素(等等)的子元素一直存在于根元素之上。通过在节点的祖先路径中找到每个 child 的索引,我们可以唯一地标识它。
请注意,这不会保留 Text
类型的节点,因为 querySelectorAll
(和一般的 CSS 路径)无法选择文本节点。
不过,我不知道这是否足以满足您的目的。
关于javascript - 如何将节点数组转换为静态 NodeList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38440492/
如何从一个 NodeList 中删除另一个 NodeList?例如,如果我有: var all = document.querySelectorAll('*'); var divs = documen
我是 javascript 编程的新手,我想了解更多。当我单击同一 nodeList 中的任何节点时,我想从 nodeList 的每个节点中删除类名。 我写了这段代码: d = document.qu
我正在使用 jQuery 编写一个网站,并且尝试将表单发布到另一个 PHP 文件而不离开页面。然后我找到了一种使用 jQuery 发布表单的方法。但是,当我将数据发布到 PHPpage 时,出现此错误
在下面的代码摘录中,products是一个xml节点列表,其结构为: 1 item1 2 item2 xml = httpRequest.r
我通常听说是因为实时节点列表“不好”(see this Zakas article)并通知 querySelectorAll 返回静态 HTMLCollection 的决定。为什么人们认为实时 Nod
我正在使用 Vaadin,一个 Java 框架。 我处理 XML 内容,我想用这些信息制作一棵树,但我不知道 XML 内容会持续多久。我发送一个调用来获取 XML,但使用不同的 IP 地址。 我知道如
我有一份正在搜索特定实例的文档,但是这些实例是由用户指定的,并且有多个。除了 for 循环内的 for 循环根据数组搜索 Nodelist 之外,我是否缺少一种不会使系统陷入困境的方法?或者更简单的方
这个问题在这里已经有了答案: Why doesn't nodelist have forEach? (10 个回答) Looping through a nodelist JS (1 个回答) 3年前
我想从其中一个包含特定文本的父节点获取所有子节点。换句话说:我开始搜索某个子节点,我确信该子节点包含我需要的一些字符串。一旦找到它,我需要获取同一级别的其他节点,而不是从与相同 Xpath 表达式匹配
我有一个事件日历。我遇到的问题是每次将事件插入到特定日期时,我的其他事件 innerHTML 也会发生变化。 我已经尝试过 event.stopPropagation() 以及 event.stopI
nodeList 和arguments 只是“类似数组”的优点是什么? 最佳答案 参数 arguments 不是真正的数组是历史产物。尽管正如在另一个答案中指出的那样,它具有 callee 属性,并且
我正在寻找一种面向 future 的方法来遍历 NodeList(即来自 element.querySelectorAll(selector))以及跨浏览器兼容。以前我一直在使用 ES6 Spread
我正在写一篇关于 Java 性能的演示文稿,我正在尝试确定这是否是一种不好的做法。我是一个 c++ 的人,所以我还不知道关于 java 的一切。我没有 item() 的源代码,我需要一个快速的答案!
首先是:这不是问如何将 NodeList 变成数组。这是相反的。 为了保持一致性,我想创建一个返回 NodeList 的函数,就像 document.querySelectorAll() 一样。 这是
我的 html 页面上有 3 个 div,所有这些都被分配了一个类名“tagline”。我想通过 JavaScript 为每个 div 分配样式。但我认为 NodeList 对象不允许我这样做。她就是
我有使用 document.getElementsByTagName('p') 存在于页面中的标签. 我想要的是,在 nodeList 中添加这些标签,就像 document.querySelecto
我已经使用nodeList = document.createDocumentFragment().childNodes;创建了一个NodeList;, 然后我设置了 nodeList[0] = do
我有一个包含 3 个对象的数组对象。我想删除除第一个对象之外的所有对象。 这是我从 XML 中获得的数据: mrArr[0] = "Val" = "5"
注意:在假定此问题重复之前,此问题底部有一个部分说明了为什么一些类似的问题没有提供我正在寻找的答案。 我们都知道将 NodeList 转换为 Array 很容易,并且有很多方法可以做到这一点: [].
我在 javascript 中有一个代码并返回 [object NodeList] 我怎么能纠正这个 请帮我 function downloadDiv(filename, elemen
我是一名优秀的程序员,十分优秀!