IE中未定义的outerHTML

Posted

技术标签:

【中文标题】IE中未定义的outerHTML【英文标题】:outerHTML undefined in IE 【发布时间】:2018-01-04 16:02:07 【问题描述】:

我的代码从包含 XML 的 Ajax 调用中获取 JSON,并通过它读取一些信息。

虽然 XML 的解析在 Chrome 中运行良好,但在 IE 中却不行,因为在 IE 中outerhtml 返回undefined

我浏览了几篇帖子并尝试了几种可能的解决方案,但均未成功。

javascript 代码是:

$.ajax(
    url: 'getJSONwithXML.do',
    type:'POST',
    data:'',
    dataType: 'json',
    cache: false
).done(function(data) 
    var jsonResp = JSON.parse(data.data.respuesta);
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(jsonResp,"text/xml");
    var texto = $(xmlDoc).find('texto').prop('outerHTML');
    console.log(texto); // <--- undefined in IE
    $('body').append('<div>' + texto + '</div>');
);

我在jsonResp下得到的xml是:

<?xml version="1.0" encoding="UTF-16"?>
<envio>
    <version>1.0.0</version>
    <anuncios>
        <remitente>
            <nodoRemitente>Nodo Remitente</nodoRemitente>
        </remitente>
        <anuncio>
            <emisor>
                <nodoEmisor>Nodo Emisor</nodoEmisor>
            </emisor>
            <metadatos>
                <id>16249</id>
            </metadatos>
            <contenido>
                <texto>
                    <p>
                        Notificación de prueba
                    </p>
                    <p>
                        Notificación de prueba
                    </p>
                    <p>
                        Notificación de prueba
                    </p>
                </texto>
            </contenido>
        </anuncio>
    </anuncios>
</envio>

在 Chrome 或 Fireforx 下,texto 返回

<texto>
    <p>
        Notificación de prueba
    </p>
    <p>
        Notificación de prueba
    </p>
    <p>
        Notificación de prueba
    </p>
</texto>

这是我想要的(texto 标记中的 HTML 代码),但在 Internet Explorer 中我得到了undefined

我已经看到了textContent 属性,但这不是我想要的,因为它不是 HTML 代码。

有什么想法吗?

【问题讨论】:

如果您能提供一个您收到的 XML 的最小示例,那就最好不过了。每个人都在猜测,这很好,但实际确定的答案需要知道结构是什么。还。 $(this).find('texto') 永远不会返回 undefined,只会返回一个 length 为 0 的 jQuery 对象。 非常感谢关于代码改进的建议。更新。我还编辑了我的问题并提供了我在jsonResp 下得到的 xml 字符串 【参考方案1】:

Internet Explorer 不为 XML 文档中的节点提供 outerHTML 属性(也不提供 innerHTML)。您可以使用XMLSerializer(在 IE 9+ 中)来解决这个问题:

var node = $(xml).find('texto')[0]; // get DOM node
// Try outerHTML. If not available, use XMLSerializer
var texto = node.outerHTML || new XMLSerializer().serializeToString(node);

您会注意到texto 字符串可能会获得根节点的xmlns 属性。但我认为这对你使用它的方式并不重要。

【讨论】:

非常感谢@trincot!!你的建议就像一个魅力! @codenamezero,确实如此。我删除了对 IE11 的引用。【参考方案2】:

因为您使用的是 JQuery(与返回单个 DOM 元素的标准 DOM API 方法相反),所以您的所有 JQuery 查询将至少返回一个 JQuery 包装集。该包装集可能已填充或未填充,因此您不应该测试包装集的存在,而应该测试它的内容。这是通过检查集合的length 来完成的。

此外,您的测试确保您想要获得outerHTML 的元素有点复杂。测试typeof 时会得到"undefined"(作为字符串),因此请确保在测试undefined 时使用它作为字符串。

看这个例子:

// There is no element with an id of "special" in this DOM
var result = $("#special");

// But, the JQuery query will still return a "wrapped set" container object
console.log(result === null);                         // false - there is a wrapped set

// You need to test for what's in the container:
console.log(result.length > 0);                       // false - the set is empty
console.log(typeof result[0] === "undefined");        // true  - nothing exists at position 0
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

所以你的代码应该检查length。请记住,在if 条件中使用的0 中的length 是“假的”并将转换为false,而任何其他值都是“真实的”并将转换为true

if($(this).find('texto').length)
  debugger;
  var texto = $(this).find('texto').prop('outerHTML');
  .  . .

但由于您可能需要多次访问该包装集,您可以使用:

var el = $(this).find('texto');

if(el.length)
  debugger;
  var texto = el.prop('outerHTML');
  .  . .

【讨论】:

如果您删除了not ornot 部分,那么您需要将其改为and - 但这就像说1+1=2 应该2=1+1 @freedomn-m 是的,这是我最初的想法——斯科特,我不认为你的“应该是”部分与 OP 的代码有任何不同。虽然我同意最终的 sn-p 是简单、优雅的解决方案! if ($(this).find('texto'))总是返回 true。你需要if ($(this).find('texto').length&gt;0)(答案中的代码应该是if (el.length&gt;0) @freedomn-m 是的,好点。我已更新答案以解决此问题。 非常感谢您对代码改进的建议,但重点是,无论我以何种方式检查 $(this).find('texto'),在 Chrome 和 Firefox 中,我都可以从 $(this).find('texto').prop('outerHTML') 获得我需要的东西,但是这在资源管理器中不起作用。【参考方案3】:

我认为问题在于您在 XML 中使用了 jQuery 的 HTML 方法与底层 DOMParser 的混合。 $(this).find(...) 在各种版本的 IE 中做了很多工作来解决其易碎的文档模型,但其中很多都不能很好地与 XML 配合使用。

IE 支持 XML,但自定义元素存在问题,因此&lt;texto&gt; 在 XML 中很好,但在 HTML5 中无法识别。

为了确定我们需要了解 jQuery 的确切版本和 IE 当前使用的文档模型(基于文档声明)。

但是,解决此问题的一种简单方法是将 jQuery 切换为 XML 解析步骤,或者从原生 DOMParser 切换到 $.parseXML。

我会先尝试前者 - 将所有 $(this).find(...) 替换为 this.getElementsByTagName(...)

【讨论】:

@freedomn-m 这不是一个微优化(如果我们要去那里,我会从不使用 jQuery 开始) - outerHTML 是一个 DOM 元素属性,而不是一个 jQuery 函数。 $texto[0] 只是获取 DOM 元素的一种方式,而不是包装器直接调用属性。 @bentakayze 在问题的澄清之后,我已经重写了答案。我认为这是 IE 的 DOM 解析器和 XML 的问题。 我也尝试了您的解决方案,但在资源管理器浏览器中也获得了 Undefined 文本。检查$texto[0]时没有这样的方法或属性。没有outerHTML 也没有html() @bentakayze 我已经重写了答案。 好的。非常感谢。我会根据你的建议再试一次。

以上是关于IE中未定义的outerHTML的主要内容,如果未能解决你的问题,请参考以下文章

ASP.Net MVC JQuery 在 IE8 中未定义,但在 Chrome 中可以

SCRIPT5009:“JSON”在 IE 10 中未定义属性“$”的值为 null 或未定义,不是函数对象

拖放指令 - IE 中未触发的事件

在 Internet Explorer 中未定义 constructor.name

在microsoft边缘扩展中未定义chrome

IE 11 边界半径怪异(在 IE 9 和 IE 10 中未发生)