IE+jQuery+Ajax+XHTML:HTML 在 .html() 或 .innerHTML 之后被剪切

Posted

技术标签:

【中文标题】IE+jQuery+Ajax+XHTML:HTML 在 .html() 或 .innerHTML 之后被剪切【英文标题】:IE+jQuery+Ajax+XHTML: HTML getting clipped after .html() or .innerHTML 【发布时间】:2011-03-01 06:33:51 【问题描述】:

这是一个很难用简短的句子表达的问题,所以如果我杀了它,我很抱歉。

我最近启动了一个站点,该站点已在我的本地 Web 服务器上在所有我想要的浏览器平台上进行了广泛的测试,包括 IE8(IE8 标准模式,Xhtml Strict)。在网站在专用网络服务器上上线之前,我完全没有遇到任何问题。

该站点在change 事件上使用jQuery.get() 来表示表单的input 元素,其中响应被移植到一个公共<div id="results"></div>

尽管我读到过关于 IE 和 XMLHTTPRequest 的缓存问题,但我的问题似乎发生在我的 ajax 回调开始执行之后。我的回调(通过.get() / .load() 提供——我都试过了)收到我的服务器返回的 HTML 片段。在任何浏览器中测试返回的内容都会准确地显示出我所期望的内容。

但是,一旦我将 HTML 片段放入 #results 的 DOM 树中,IE 实际上会从我的标记中剪掉前 7 或 8 个开始标记(以及大多数这些标记的子标记)。这是非常奇怪的。我通过jQuery('#results')[0].innerHTML = content 设置 HTML 内容,将它修复在网站的另一个区域,但这次没有骰子。

示例响应:

<div>
    <a href="#">some link</a>
    <span>stuff, blah blah</span>
    <a href="#">another link</a>

    <ul>
        <li id="item-2342">
            <img src="#" />
            <div class="info">
                <h6> ..title.. </h6>
                <a href="#">View</a>
                <span rel="stats"> ..statistics.. </span>
            </div>
        </li>

        <!-- ... and so on in a loop over items to create more <li> items ... -->
    </ul>
</div>

从字面上看,从 &lt;span rel="stats"&gt; 的开始标签开始的所有内容都会被截断。效果是 IE 显示我返回的 AJAX 内容,就好像它以文本节点开头:..statistics.. &lt;/span&gt;。 (我尝试根据下面评论的建议删除rel="stats",将其更改为 CSS 类,但结果相同。)

如果我直接通过浏览器的 URL 字段请求我的 AJAX url,返回的内容是完美的。

如果我用alert()来显示返回的AJAX内容就完美了。

如果我通过.html().innerHTML 分配我的AJAX 内容,它会立即被截断。

Sooo.... WTF? IE 的(蹩脚的)调试器不显示任何脚本错误或任何类似性质的东西。以前有没有人处理过这种问题?再次强调,在我的开发服务器 (127.0.0.1) 上,IE 没有问题,而且它似乎使用相同的“模式”(IE8 标准)等等。

编辑:这是支持 AJAX 查找的 javascript

jQuery('.ajax-panel').live('load', function(event, request_string)
    var panel = jQuery(this).stop(true).fadeTo(100, 0.2).addClass('loading');
    var form = jQuery(panel.attr('rel'));
    jQuery.get(form.attr('action'), request_string ? request_string : form.serialize(), function(response)

        // WTF?
        // panel[0].innerHTML = response;
        panel.empty().append(response);

        // Carry on.
        panel.removeClass('loading').stop(true).fadeTo(100, 1);
    );
);

【问题讨论】:

您有示例页面,我们可以试试这个吗? 只是好奇,您是否尝试在响应处理程序中为 .innerHTML 分配一些不同的内容?这可以让您了解导致错误的原因(文本长度、特定标签等)。 你是在 IE8 的 IE8 模式下还是在 IE7 兼容模式下尝试这个? IE8 标准模式。我将文档类型声明为严格的 XHTML。示例页面(缩短,大量 GET 参数):bit.ly/9EULaH 页面加载,它评估我提到的&lt;form&gt;,然后触发 ajax 并将结果放入&lt;div id="ajax-panel"&gt;。 JS 工作发生在第 32-44 行函数的/media/js/base.js 中。这是我交叉手指的地方,希望您看到与我看到的相同的鬼魂:) @NikitaRybak ajax 响应的长度似乎并不重要——是否有一个&lt;li&gt; 或十个。我将不得不使用不同的内容进行更多测试。 【参考方案1】:

我遇到了类似的问题,其中附加的部分 html 代码被剪切,但是如果我创建了内部 html 的警报,或者强制滚动,它就会出现。

然后我看到一篇文章似乎表明 IE8 没有正确重绘窗格。 http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript

我设法让它工作的唯一方法是向它添加一个类,等待,然后删除该类。如果我不等待,它似乎会跳过执行。

函数重绘(元素)

 如果($.browser.msie)
 
  element.addClass("不可见");
  设置超时(函数()
    element.removeClass("不可见");
   ,1);
 

【讨论】:

【参考方案2】:

如果删除 rel="stats" 会发生什么?

rel 属性中不允许有stats,根据MSDN。

【讨论】:

相同的结果。奇怪的是,我使用了一些非标准的 rel 值而没有任何其他副作用,包括同一 HTML 块中的几个其他实例,它们都没有遇到这个问题。请注意,我的 AJAX HTML 中的所有以下 &lt;li&gt; 条目都没有受到伤害。只有第一个被烧毁(HTML 导致它)【参考方案3】:

我可以确认问题。我对原始提交者生成了类似的 AJAX 响应。一些初始信息,然后循环遍历数据以创建 8 个不同 div 的内容。运行页面时,它会进行加载,但 IE 只会显示部分数据。一个小改动解决了这个问题。

我在每个 div 内的页面上有一个跨度(用于一组视频标签),因此如果文本太长,我可以截断文本,并将具有标题属性的跨度用作悬停提示。如果标签跨度是这样格式化的:

<div>Tags: <span title="Miller, Jackson, Brown">Miller, Jackson...</div>

它不起作用,而:

<div>Tags: Miller, Jackson, Brown</div>

工作正常。当然,我注意到我的错误在于没有跨度结束标记。解决这个问题也有效,但我注意到的重要一点是 IE 似乎非常不能容忍 AJAX 上的格式错误,或者更准确地说是 AHAH。

在看到这个之后,我会保证返回字符串中存在一些格式不正确的 HTML。我遇到了与您所做的完全相同的错误,即 javascript 返回的信息片段,并且更正错误为我修复了它。

【讨论】:

【参考方案4】:

这是一个疯狂的猜测,但它曾经帮助我解决了 IE 问题:

尝试完全清空容器对象,而不是$('your_container').html( your_content ),然后使用append()。所以:

$('your_container').empty().append( your_content );

它是 IE。你永远不知道。

【讨论】:

每个人都喜欢在未知之上的未知。 无论是 jQuery 还是 IE,这也不起作用。我很确定我没有被缓存的 ajax 响应所欺骗——它的行为似乎完全相同。【参考方案5】:

将所有方法更改为 POST。默认为 GET。

jQuery.ajax(
    url: form.attr('action'), 
    success: function()
        panel.empty().append(response);

        // Carry on.
        panel.removeClass('loading').stop(true).fadeTo(100, 1);
    
);

应该这样做......我知道我在你的函数中遗漏了一些东西,但这就是它的要点。

【讨论】:

【参考方案6】:

我遇到了完全相同的问题。我正在使用 jQuery 的 .html() 插入来自服务器的响应。 响应文本的开头是一些 php,然后是换行符,然后是一些 HTML。只是删除换行符会导致截断停止。

发件人:

<?php 
$this->load->helper('stdclass_helper');
?>

<div id="expense_entry" class="element_record" style="padding:20px;" 

收件人:

<?php 
$this->load->helper('stdclass_helper');
?>
<div id="expense_entry" class="element_record" style="padding:20px;" 

经过几次实验,我能够将 my 问题的原因隔离到文件开头的换行符。

例如,文件开头发生截断(添加引号以显示换行符):

"



<div id="expense_entry" class="element_record" style="padding:20px;" saveHandler="Accounting.Expenses.saveExpense">
<!-- BEGIN EXPENSE ENTRY FORM -->
<?php 
$this->load->helper('stdclass_helper');
?>
"

通过删除第一个换行符来消除截断。

这是在 Windows 7(使用 VMWare 虚拟 Windows 机器)上使用 jquery-1.6.4.min.js 和 IE 9(在 IE 8 仿真模式下)

更新: 作为一个彻底的人,因为我已经在 jquery .html() 函数周围使用了一个包装器来查找和注册自定义元素,所以我继续通过修剪任何字符串数据来解决 IE 问题。这很好用:

// Override jQuery's html() method, so that we can register any special elements in new html.
(function( $, oldHtmlMethod )

    // Override the core html method in the jQuery object.
    $.fn.html = function(data)
        // Execute the original HTML method using the
        // augmented arguments collection.
        //trim whitespace that could cause IE to truncate returned content
        **if(typeof data == 'string')
            data = data.trim();
        **
        var results = oldHtmlMethod.apply( this, arguments );
        return results;

    ;

)( jQuery, jQuery.fn.html );

这对我很有效。

【讨论】:

以上是关于IE+jQuery+Ajax+XHTML:HTML 在 .html() 或 .innerHTML 之后被剪切的主要内容,如果未能解决你的问题,请参考以下文章

ajax 请求 对json传的处理 Jquery 使用Ajax获取后台返回的Json数据后,页面处理

“对象不支持IE中的属性或方法'find'”

jQuery ajax 调用后 IE 7 重定向

IE 使 Jquery.html 失败,权限被拒绝

jQuery实现form表单基于ajax无刷新提交方法详解

JQuery+ajax数据加载..........