简体   繁体   English

jQuery .html() 没有正确设置内容?

[英]jQuery .html() not setting content correctly?

Here is the example I prepared to tell about the problem easier.这是我准备更轻松地讲述问题的示例。

http://codepen.io/anon/pen/EVpYXm http://codepen.io/anon/pen/EVpYXm

As you can see the initial <html> is set to display a text:如您所见,初始<html>设置为显示文本:

"This is the old html!" “这是旧的html!”

It sets the whole content to the data in the variable myHtml .它将整个内容设置为变量myHtml的数据。 however here is what I notice:然而,这是我注意到的:

the style is not carried from the <body> element.样式不是从<body>元素携带的。 Moreover, the <body> element is somehow not created at all!此外, <body>元素以某种方式根本没有被创建!

Here is the sring myHtml , tidied up to display as an html:这是 sring myHtml ,整理后显示为 html:

<html>
<head>
<title>Title Here</title>
<link href='style.css' rel='stylesheet' type='text/css'/>
</head>
<body style='background-color: red'>
<div>Div!</div>
</body>
</html>

I've realized that when link element is removed, everything works fine.我意识到当链接元素被删除时,一切正常。 Try it, see it yourself.试试看,自己看。

Stuck with this issue for the last few hours.过去几个小时一直被这个问题困扰。 Looking for a result.寻找结果。

Here is the full code:这是完整的代码:

page html:页面html:

<html>
  This is the old html!
</html>

javascript: javascript:

$(function(){
  var myHtml = "<html><head><title>Title Here</title><link href='style.css' rel='stylesheet' type='text/css'/></head><body style='background-color: red'><div>Div!</div></body></html>"
  $("html").html(myHtml);
})

The main purpose of this question is to understand the reason of this behavior as well as finding the best solution.这个问题的主要目的是了解这种行为的原因以及找到最佳解决方案。

The issue is that, when you use jQuery's html(val) , it does something like this:问题是,当您使用 jQuery 的html(val) ,它会执行以下操作:

html: function(value) {
  /* ... */
  // See if we can take a shortcut and just use innerHTML
  if ( typeof value === "string" && !rnoInnerhtml.test( value ) && /* ... */) {
    /* ... */ elem.innerHTML = value; /* ... */
  }
  /* ... */
}

That is, it checks the string with the regex rnoInnerhtml , which is也就是说,它使用正则表达式rnoInnerhtml检查字符串,即

rnoInnerhtml = /<(?:script|style|link)/i

Therefore, presumably to avoid inserting stylesheets, jQuery avoids innerHTML and does complicated things with domManip .因此,大概是为了避免插入样式表,jQuery 避免使用innerHTML并使用domManip做复杂的事情。

I recommend using native innerHTML :我建议使用原生的innerHTML

$("html").prop('innerHTML', myHtml);

 var myHtml = "<head><title>Title Here</title><link href='style.css' rel='stylesheet' type='text/css'/></head><body style='background-color: red'><div>Div!</div></body>" $("html").prop('innerHTML', myHtml);
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> This is the old html!

Or with vanilla-js:或者使用 vanilla-js:

document.documentElement.innerHTML = myHtml;

 var myHtml = "<head><title>Title Here</title><link href='style.css' rel='stylesheet' type='text/css'/></head><body style='background-color: red'><div>Div!</div></body>" document.documentElement.innerHTML = myHtml;
 This is the old html!

The problem is that you're appending an html element inside the root html element, which is undefined behavior and cannot be rendered reliably by the browser.问题是您在根html元素中附加了一个html元素,这是未定义的行为,浏览器无法可靠地呈现。 Strip the opening and closing <html> and </html> tags from your myHtml string and it works!从你的myHtml字符串中去除开始和结束<html></html>标签,它就可以工作了!

Working demo工作演示

$(function() {
  var myHtml = "<head><title>Title Here</title></head><body style='background-color: red; '><div>Div!</div></body>"
  $('html').html(myHtml);
})

Alternatively, you could keep the tags and write directly to the document object instead, which opens a new stream and overwrites the previous document.或者,您可以保留标签并直接写入document对象,这会打开一个新流并覆盖之前的文档。

// ...
document.write(myHtml);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM