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

发布于 2024-09-04 23:29:17 字数 2387 浏览 1 评论 0原文

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

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

该网站在表单的 input 元素的 change 事件上使用 jQuery.get(),其中响应被嫁接到公共 <代码>

尽管我读到了有关 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>

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

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

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

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

苏……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);
    });
});

This is a really hard problem to put into a brief sentence, so I apologize if I kill it.

I launched a site recently which had been extensively tested on my local web server on all my desired browser platforms, including IE8 (IE8 standards mode, XHTML Strict). I encountered no problems at all until the site went live on a dedicated web server.

The site uses jQuery.get() on the change event for the input elements of a form, where the response is grafted into a common <div id="results"></div>.

Despite the caching woes I've read about with IE and XMLHTTPRequest, my problem seems to take place AFTER my ajax callback begins execution. My callback (supplied via .get() / .load()-- I've tried both) receives an HTML fragment returned by my server. Testing the returned content in any browser reveals exactly what I expect the content to be.

However, as soon as I put the HTML fragment into the DOM tree in the #results, IE actually clips the first 7 or 8 opening tags off of my markup (along with the children of most of those tags). It's wickedly bizarre. I fixed it in another area of the site by setting the HTML content via jQuery('#results')[0].innerHTML = content, but no dice this time.

Example response:

<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>

Literally EVERYTHING up through the opening tag of that <span rel="stats"> is truncated. The effect is that IE displays my returned AJAX content as if it were to begin with the text node: ..statistics.. </span>. (I tried removing the rel="stats" at the suggestion of a comment below, changing it to a CSS class instead, but the same result occurs.)

If I request my AJAX url directly via the browser's URL field, the returned content is perfect.

If I use alert() to display the AJAX content returned, it is perfect.

If I assign my AJAX content via .html() or .innerHTML, it is immediately truncated.

Sooo.... WTF? IE's (crappy) debugger displays no script errors or anything of that nature. Has anybody ever dealt with this kind of issue before? Again, I add emphasis to the fact that on my development server (127.0.0.1), IE has no problems, and it seems to use the same "mode" (IE8 Standards) and everything.

EDIT: Here is the Javascript powering the AJAX lookup:

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);
    });
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

誰ツ都不明白 2024-09-11 23:29:17

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

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

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

function Redraw(element)
{
 if ($.browser.msie)
 {
  element.addClass("invisible");
  setTimeout(function(){
    element.removeClass("invisible");
   },1);
 }
}

I had a similar issue happen where part of the html code appended was clipped, but if I created an alert of the inner html, or forced a scroll, it appeared.

I then came across an article that seemed to indicate that IE8 was not redrawing the pane correctly.
http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript

The only way I managed to get it to work was to add a class to it, wait, then remove the class. If I did not wait, it seems to skip execution.

function Redraw(element)
{
 if ($.browser.msie)
 {
  element.addClass("invisible");
  setTimeout(function(){
    element.removeClass("invisible");
   },1);
 }
}
执笔绘流年 2024-09-11 23:29:17

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

根据 MSDN

What happens if you remove rel="stats"?

The rel attribute is not allowed to have stats in it, according to MSDN.

夏见 2024-09-11 23:29:17

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

我在页面上的每个 div 中都有一个跨度(用于一组视频标签),这样我就可以在文本太长时截断文本,并将跨度与标题属性一起用作悬停提示。如果标记范围以这种方式格式化:

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

它将不起作用,而:则可以

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

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

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

I can confirm the problem. I have generated a similar AJAX response to the original submitter. Some initial info, then a loop through the data to create 8 different div's worth of content. When running the page, it would do the load, but IE would only show some of the data. One small change fixed this.

I had a span on the page (for a set of video tags) within each div, so that I could truncate text if it was too long, and use the span with the title attribute as a hovertip. If the tag span was formatted this way:

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

it wouldn't work, whereas:

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

worked fine. Of course, I noticed my error in that there is no span closing tag. Fixing this also worked, but the important thing that I noticed is that IE seems to be very intolerant of formatting errors on AJAX, or, more correctly, AHAH.

I would, after having seen this, guarantee that there is some slightly malformed HTML in the return string. I had the exact same error, a fragment of information returned by javascript, that you did, and correcting the error fixed it for me.

奢欲 2024-09-11 23:29:17

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

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

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

这是 IE。你永远不知道。

Here's a wild guess, but it helped me once with an IE problem:

Instead of $('your_container').html( your_content ), try to empty the container object entirely, then use append(). So:

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

It's IE. You never know.

思念绕指尖 2024-09-11 23:29:17

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

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

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

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

Change all your METHODS to POST. The default is GET.

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

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

That should do it... I know I'm missing some stuff from your functions, but this is the jist of it.

长伴 2024-09-11 23:29:17

我有完全相同的问题。我使用 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;" 

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

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

"



<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 );

这对我来说很有效。

I had exactly the same issue. I was using jQuery's .html() to insert response from the server.
The beginning of the response text began with some php followed by a line break and then some HTML. Just removing the line break caused the truncation to stop.

From:

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

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

To:

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

After a few experiments, I was able to isolate the cause of my problem to line breaks at the beginning of the file.

For example, truncation occurs beginning file (quotes added to show line breaks):

"



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

Truncation goes away by removing those first line breaks.

This was using jquery-1.6.4.min.js and IE 9 (in IE 8 emulation mode) on Windows 7 (using VMWare virtual windows machine)

Update:
Being a thorough guy, since I am already using a wrapper around the jquery .html() function to find and register custom elements, I went ahead and took care of the IE problem by trimming any data that was a string. This works well:

// 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 );

This works well for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文