我遇到的问题我确信很常见。我找到了很多这个问题的解决方案,它们各有利弊。我发布了我在这里发现的内容(我认为这对其他人有用),我希望你能指出我正确的方向。
基本上,这是我的方案:
http://example.com/page_with_content_a_or_b.php
。Content A
,如果有,则返回Content B
。Content A
。Content A
替换为Content B
。问题:JavaScript如何替换内容?
好吧,正如我所说,我一直在寻找不同的解决方案,但似乎都不是完美的。
为了讨论每个可能的解决方案,让我向您介绍每个版本的结果HTML代码:
内容A的HTML
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_A.css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="gallery-animator.js"></script>
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p>Content A</p>
<script type="text/javascript" src="content-b-loader.js"></script>
</body>
</html>
内容B的HTML
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_B.css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="gallery-animator.js"></script>
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p>Content B</p>
</body>
</html>
两个版本之间的差异
如您所见,在示例中,两个版本非常相似,但不完全相同。一般来说,这些是我可能遇到的差异:
Content B
不包含用于加载自身的脚本(Content A
中的最后一个脚本)。我实施的第一个解决方案如下:
content-b-loader.js(选项1)
$(document).ready(function() {
$.ajax({
type: 'POST',
url: window.location.href,
data: { load_content_b: 'true' },
success: function( html ) {
document.open();
document.write(html);
document.close();
}
});
});
显然,解决方案正常运行。但是,在某些情况下我会遇到问题。例如,在我的示例中,两个内容都加载了一个名为gallery-animator.js
的脚本。假设此脚本如下:
廊-animator.js
var galleryInterval = setInterval(function() {
// Fade out current image and fade in the next one
$("body > div.gallery > img")...
}, 5000);
在content-b-loader.js
执行脚本后,有两个超时动画库。结果,动画看起来像一团糟(两个图像同时移动,或根本不工作)。
序列document.open()
,document.write(html)
和document.close()
似乎不会停止并替换原始脚本。
另一个解决方案是执行in this previous question描述的重定向。该解决方案就像一个魅力:一方面,我加载了我需要加载所需的POST数据的URL,这意味着我将获得Content B
,另一方面,{{1}已加载到&#34;新页面&#34;,这意味着Content B
加载的脚本不再存在。
问题出在这里?如果我使用Content A
刷新页面,我会收到一条警告,指出&#34; POST数据即将重新提交&#34;。这是不可取的,因为它看起来让用户感到困惑(我不想让她知道她被重定向到新页面)。
我知道有一个名为PRG (Post-Redirect-Get)的解决方案可以避免这个特殊问题。但是,它需要使用GET请求访问Content B
(使用GET参数或COOKIES,我都不能使用)。
我发现的最后一个解决方案也很有趣。基本上,它会从Content B
隐藏(或清空)正文,在页面中添加 iframe ,并在其中加载Content A
:
content-b-loader.js(选项3)
Content B
anchor.html
此页面实现了第二个解决方案(它使用POST重定向)。
$(document).ready(function() {
$.ajax({
type: 'POST',
url: window.location.href,
data: { load_content_b: 'true' },
success: function( html ) {
$("body").css('', ''); // Remove all paddings and margins
$("body").empty();
$("body")append('<iframe id="content" seamless="seamless"' +
'src="anchor.html"></iframe>');
// Initialize vars in anchor.html and call the redirect functions
document.getElementById('content').contentWindow.url = window.location.href;
document.getElementById('content').contentWindow.options = {
load_content_b: 'true'
};
document.getElementById('content').contentWindow.redirect();
}
});
});
通过使 iframe 与窗口视图一样大,我可以显示替代内容。如果用户刷新网页,则刷新的页面是&#34;容器&#34;页面(最初有<html>
<head>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.redirect.min.js"></script>
<script type="text/javascript">
var url;
var options;
function redirect(){
$().redirect(url, options, 'POST');
}
</script>
</head>
<body></body>
</html>
的页面),因此根本没有警告。
然而,我遇到的解决方案是:
base
directive但是形式怎么样?和执行重定向的JavaScript代码?我有一个页面Content A
。使用GET请求访问时页面返回http://example.com/page_with_content_a_or_b.php
,使用POST访问时返回Content A
。当用户键入网址时,她会获得Content B
,并使用JavaScript加载Content A
。
所有解决方案都存在问题:
有什么想法吗?我错过了什么吗?是否有一种首选的方式来做我想做的事情?
非常感谢!
答案 0 :(得分:0)
POST
请求应执行更改或影响数据的操作。因此,防止用户刷新并且应该是理想的行为是有意义的,我很困惑你是在做一个实际的帖子请求还是为什么重定向到POST
页面是如此有问题?
无论哪种方式,关于您的<iframe>
解决方案,请允许我提出一些建议。 “禁用iframe”在某些浏览器上确实是技术上可行的,但要做到这一点,你必须潜入about:config
或深入IE菜单,默认情况下在Chrome上完全不可能。所以,是的,说实话,我不会关心这一点,就像现在大多数网站都不关心禁用javascript的用户(任何禁用iframe的用户都可能禁用javascript),只是因为它也是很少关心自己,这是你必须自己面对后果的选择之一。现在,我正计划将你引导到<base>
标签,现在就意识到你已经在帖子中提到了它。无论哪种方式,标签也适用于表单,但不适用于javascript'链接'。
总而言之,我建议您重新考虑页面是否应该是POST
,如果是,那么您应该继续使用警告,否则将其重新设计为另一个GET
页面。
答案 1 :(得分:0)
There's a hacky fix针对第一个解决方案中的杂乱脚本行为问题。假设与脚本相关的问题仅在使用超时时发生(我不知道是否存在其他可能出错的情况......),有一种简单的方法可以清除所有超时。只需添加以下代码:
var id = window.setTimeout(function() {}, 0);
while (id--)
window.clearTimeout(id);
答案 2 :(得分:0)
我想我错过了一些东西,因为我不明白你的意思是什么用户的网页浏览器通过JavaScript决定用内容替换内容A. B&#34;,但是:
如果您事先知道您想要替换其内容的元素的参数,那么不会进行简单的个案更换工作吗?
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_A.css">
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p class="content">Content A</p>
</body>
<!-- This could be content-b-loader.js -->
<script>
var $stylesheet = document.getElementsByTagName('link')[0];
$content = document.querySelectorAll('.content')[0];
if ( $stylesheet && $content ) {
if ( $stylesheet.getAttribute('href') == 'style_A.css' ) {
$stylesheet.setAttribute('href', 'style_B.css');
}
$content.innerHTML = 'Content B';
}
</script>
</html>