MSIE:jQuery的append()/html()不起作用,求助于getElementById().innerHTML
这是一篇很长的文章,
The Premise
被要求帮助客户修复他们当前项目的一些错误。 需要修复的是职位列表页面。 您有一个职位列表,单击其中一个职位,如果激活了 JavaScript,则会进行 AJAX 调用以将职位的详细信息动态加载到现有元素中 (DIV#emploi_details)。 如果 JS 未激活,它只会重新加载包含作业详细信息的页面(不太重要)。
我跳上了他们的实验室服务器,在开发网站上工作。
问题
基本上,IE7(一开始)不显示通过 $().load() 加载的内容。 IE6 可以顺利地使用innerHTML。 请求被发送,我每次都会得到回复。 我收到数据,我可以警告()它并查看它,但内容的实际转储不起作用。 Safari、火狐浏览器都没有问题。 我正在加载信息的 DIV#emploi_details 元素有一个 CSS display:none; 在其样式表中,并在加载内容后显示(其他不那么重要的细节)。
show_emploi = function(id, succ_id)
{
$('#emploi_details').fadeOut(800, function() {
var $$ = $(this);
$$.load('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
if (isIE6) document.getElementById('emploi_details').innerHTML = data;
$$.show();
});
$('#bgContent').fadeOut();
});
}
解决方案
起初,我的印象是 $().load() 可能只是在起作用,所以我将其更改为 $.get() 以更好地控制对加载内容的操作。
$.get('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
$$.empty().append(data).show();
});
这有效。 在所有浏览器中,包括 IE6 和 IE7。 没问题。 很奇怪,但你知道它是否有效并且完全可靠,不要问问题。
情节转折
现在事情变得很奇怪了。 我认为该错误已修复,并将解决方案应用于实时网站,但...它不起作用。 IE 只是不喜欢它。 在尝试了 $.ajax 和所有其他类型的东西后,我感到困惑,我最终将其用于实时网站:
$.get('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
document.getElementById('emploi_details').innerHTML = data;
$$.show();
});
它适用于所有浏览器,因为没有什么比准系统 JS 更能完成工作。 当然,此修复程序也适用于开发网站。
“待续”
嵌入内容的功能中有一些内容并不是所有浏览器(显然还有服务器)都点击的。
总而言之,我的问题是个WTF问题。 我不明白为什么一个在一侧工作,而在另一侧却不起作用,甚至为什么它一开始就不能正常工作($().load())。 这显然不是不同的 jQuery 版本 (1.2.6),因为这是我验证框架版本的第一本能。
不管怎样,在我看来,有趣的神秘。
希望斯塔克兰有人能给出上帝赐予的答案。
谢谢
This is a long one,
The Premise
Was called in to help out a client with some bug fixing on a current project of theirs. What needed fixing was a jobs listing page. You have a list of jobs, you click one and if JavaScript is activated an AJAX call is made to dynamically load the job's details into an existing element (DIV#emploi_details). If JS isn't activated, it simply reloads the page with the job's details (less important).
I jumped onto their lab servers to work on the dev website.
The Problem
Basically, IE7 (at first) wasn't displaying the content loaded via $().load(). IE6 worked without a hitch with innerHTML. Requests are sent and I get a reply every time. I receive the data, I can alert() it and see it but the actual dumping of the content doesn't work. Safari, Firefox, no problems. The DIV#emploi_details element I'm loading info into has a CSS display:none; in its styleheets and is shown after content is loaded in (other not so important detail).
show_emploi = function(id, succ_id)
{
$('#emploi_details').fadeOut(800, function() {
var $ = $(this);
$.load('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
if (isIE6) document.getElementById('emploi_details').innerHTML = data;
$.show();
});
$('#bgContent').fadeOut();
});
}
The Solution
At first I was under the impression maybe the $().load() was just acting up, so I changed it for a $.get() for more control over the manipulation of the loaded content.
$.get('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
$.empty().append(data).show();
});
This works. In all browsers including IE6 and IE7. No problem. Weird, but you know if it works and its fullproof, don't ask questions.
The Plot Twist
Now here's where shit gets weird. I considered the bug fixed and applied the solution to the live website and... it doesn't work. IE just isn't liking it. Baffled after trying $.ajax and all other sorts of stuff I end up using this for the live website :
$.get('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
document.getElementById('emploi_details').innerHTML = data;
$.show();
});
And it works on all browsers, because there's nothing like barebones JS to get stuff done. Necessarily, this fix also works on the dev website.
The 'To Be Continued'
There is something in the function of embedding of the content that isn't clicking for all browsers (and clearly servers).
All in all, my question is a WTF question. I can't understand why one works on one side and the same doesn't work on the other side or even why it never worked properly in the beginning ($().load()). It's clearly not different jQuery versions (1.2.6) since it was my first instinct to verify the framework version.
Anyway, interesting mystery IMO.
Hope someone out there in Stackland has the god-given answer.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我已经解开了谜题! 这是我的问题的一个有效示例。
诀窍是在第一次成功后调用另一个 AJAX,这会以某种方式覆盖innerHTML 的问题。
谢谢你们让我走上了正确的方向。
我希望这会对一些人有所帮助,因为到目前为止我还没有看到可行的解决方案。
我还将为此联系 jQuery :P
salut
I have solved the riddle! here is a working example of my problem.
The trick was to call another AJAX after the first success, this will somehow override the problems with the innerHTML.
Thanks guys for setting me to the right direction.
I hope this will help some people, because so far i haven't seen a working solution yet.
I will also contact jQuery for this :P
salut
我猜你一定在场。 以下是一些可能的失败点:
jQuery.clean:使片段添加到 DOM 的函数。
如果文档类型错误,或者响应 HTML 在某些方面有缺陷,则可能会发生这种情况
使 clean 函数失败的方式,从而导致没有任何内容可以插入到 DOM 中。
jQuery.fn.append:将渲染的响应片段添加到 DOM。
这么说吧,因为 jQuery 使用appendChild而不是向 DOM 添加内容
innerHTML,一个错误导致 IE 不知道 DOM 已更改并且不渲染
发出信号的变化。 当您使用innerHTML 时,这将被绕过。
从你的问题中不清楚你是否已经验证注入的 HTML 确实是
那里。 这可以用这样的东西来测试:
jQuery.fn.show():显示结果。
从你的问题中并不清楚最终的失败是否是因为内容
没有被放入 DOM,或者只是没有被显示? 如果
容器有内边距和背景,你看到了吗?
show 函数比仅仅在上面添加
.style.display='block'
更复杂元素。 如果它认为该元素是隐藏的,它就不会显示该元素,IE 有时可能会这样
有奇怪的想法。 用手动设置显示替换 show() 是否会改变
什么?
很明显,IE 处理舞台/开发页面和实时站点的方式有所不同。 我的第一步是尝试发现它们之间的差异。 HTTP 标题、编码、文档类型、额外的脚本、额外的 css,甚至空格...一些看似微小的差异是导致此错误的原因。
无论如何,您应该准备一个简化的测试用例,仅包含复制此错误所需的基本必需品。 即使您没有找到您满意的解决方法,测试用例也应该与您的 向 jQuery 报告错误。
I guess you had to be there. Here are some possible points of failue:
jQuery.clean: The function that makes the fragment that gets added to the DOM.
This could be possible if the doctype is bad, or if the response HTML is flawed in some
way that makes the clean function fail, thus leaving nothing to be inserted into the DOM.
jQuery.fn.append: Adding the rendered response fragment to the DOM.
Let's say that, because jQuery adds content to the DOM with appendChild rather than
innerHTML, a bug causes IE to be unaware that the DOM has changed and not render
the signaled changes. This would then get bypassed when you use innerHTML.
It's not clear from your question if you have verified that the injected HTML is indeed
there. This would be testable with something like this:
jQuery.fn.show(): Displaying the results.
It's not clear from your question if the ultimate failure is because the content
isn't being put into the DOM, or if it just isn't being displayed? If the
container has a padding and a background, do you see it?
The show function is more complex than just adding
.style.display='block'
on theelement. It won't display the element if it thinks it is hidden, which IE may sometimes
have strange ideas on. Does replacing show() with manually setting display change
anything?
It is clear that there is a difference in how IE treats the stage/dev page and the live site. My first steps would be to try to discover the difference between them. HTTP Headings, encoding, doctypes, extra scripts, extra css, even whitespace... Some seemingly minor difference is the cause of this bug.
Inn any case, you should prepare a reduced test case of only the bare necessities required to replicate this bug. Even if you don't find a cure for it that you are comfortable with, the test case should be send along with your bug report to jQuery.