1

我实际上正在制作一个侧边栏小工具(基于 AJAX),并且我正在寻找一种从 AJAX 请求中提取单个元素的方法。

我发现的唯一方法是做这样的事情:

var temp = document.createElement("div");
temp.innerHTML = HttpRequest.innerText;
document.body.appendChild(temp);
temp.innerHTML = document.getElementByID("WantedElement").innerText;

但它非常难看,我想直接从请求中提取 WantedElement 而不将其添加到实际文档中......

谢谢!

4

5 回答 5

1

如果您可以控制数据,那么您的处理方式可能是最好的方法。这里的其他答案有它们的好处,但它们也都有相当大的缺陷。例如,该 querySelector()方法仅适用于在主机上以 IE8 模式运行的 Windows 桌面小工具。正则表达式对于解析 HTML 尤其不可靠,不应使用。

如果您无法控制数据,或者数据不是通过安全协议传输的,那么您应该更关注安全性而不是代码美学——您可能会通过插入将未经处理的 HTML 放入文档中。由于小工具以用户或管理员级别的权限运行,明显的安全风险是不受信任的源/ MITM脚本注入,从而为恶意脚本留下一个漏洞,对运行它的机器造成严重破坏。

一种可能的解决方案是使用htmlfileActiveXObject:

function getElementFromResponse(divId)
{
    var h = new ActiveXObject("htmlfile");
    h.open();

    // disable activex controls
    h.parentWindow.ActiveXObject = function () {};

    // write the html to the document
    h.write(html);

    h.close();
    return h.getElementById("divID").innerText;
}

您也可以使用 IE8 的toStaticHTML()方法,但您的小工具需要在 IE8 模式下运行。

于 2010-04-10T21:21:25.533 回答
0

一种选择是使用正则表达式:

var str = response.match(/<div id="WantedElement">(.+)<\/div>/);
str[0]; // contents of div

但是,如果您的服务器响应更复杂,我建议您使用JSON之类的数据格式作为响应。然后在客户端解析会更干净。

于 2010-04-10T18:13:27.717 回答
0

您可以将来自 XMLHttpRequest 的响应附加到隐藏的 div 中,然后调用getElementById以获取所需的元素。稍后在完成后删除 div。或者,也许创建一个为您处理此问题的函数。

function addNinjaNodeToDOM(html) {
    var ninjaDiv = document.createElement("div");
    ninjaDiv.innerHTML = html;
    ninjaDiv.style.display = 'none';
    return ninjaDiv;
}

var wrapper = addNinjaNodeToDOM(HttpRequest.innerText);
var requiredNode = wrapper.getElementById("WantedElement");
// do something with requiredNode
document.body.removeChild(wrapper); // remove when done

将它附加到 DOM 的唯一原因是getElementById除非它是 DOM 树的一部分,否则将无法工作。见MDC

但是,您仍然可以在分离的 DOM 节点上运行选择器和 XPath 查询。这将使您不必将元素附加到 DOM。

var superNinjaDiv = document.createElement('div');
superNinjaDiv.innerHTML = html;
var requiedNode = superNinjaDiv.querySelector("[id=someId]");
于 2010-04-10T18:52:56.523 回答
0

I think using getElementById to lookup the element in this case is not a good approach. This is because of extra steps you have to take to use it. You wrap the element in a DIV, inject in DOM, lookup your element using getElementById and then remove the injected DIV from DOM.

DOM manipulation is expensive and injection might cause unnecessary reflow as well. The problem is that you have a document.getElementById and not a element.getElementById which would allow you to query without injection in the document.

To solve this, using querySelector is an obvious solution which is far more easier. Else, I would suggest using getElementsByClassName if you can and if your element has a class defined.

getElementsByClassName is defined on ELEMENT and hence can be used without injecting the element in DOM.

Hope this helps.

于 2010-04-11T23:16:44.537 回答
-1

通过 AJAX 请求传递 HTML 有点不寻常。通常你传递一个客户端可以直接评估的 JSON 字符串,并使用它

话虽如此,我认为没有一种方法可以按照您想要的跨浏览器的方式在 javascript 中解析 HTML,但这是在 Mozilla 衍生产品中执行此操作的一种方法:

var r = document.createRange();
r.selectNode(document.body);
var domNode = r.createContextualFragment(HTTPRequest.innerText);
于 2010-04-10T18:22:01.957 回答