我试图在Blogger中美化我的代码。我已将Google JS和CSS文件链接到我的模板。问题是我希望代码在页面加载时被美化,所以我在模板上添加prettyPrint();
页面加载事件。
<body onload="prettyPrint();">
此代码无法执行。但是,如果我在控制台中手动键入prettyPrint(),我的代码会正确地进行修饰。博客模板是否会手动调用JS函数?
编辑我通过在每个需要代码美化的帖子中手动调用函数来实现它(见下文)。不过,我想知道为什么我不能在模板上这样做。
<pre class="prettyprint linenums lang-js">
function testCode(){
}
</pre>
// I have to do this in every post :-s
<script type="text/javascript">
prettyPrint();
</script>
编辑2 README表示我不应该直接使用prettyPrint()
作为处理程序,而是将其包装在闭包中。所以我在我的<head>
中添加了这个代码,类似于README中的示例,但无济于事。
<script type='text/javascript'>
window.addEventListener('load', function (event) { prettyPrint() }, false);
</script>
或 的
<script type='text/javascript'>
document.addEventListener('DOMContentLoaded',function() {
prettyPrint();
});
</script>
编辑3 我的模板HTML只是默认的动态视图(经典)模板,其中添加了美化库,如上所述。
编辑4 以下是展示问题的链接:http://testprettyprint.blogspot.com/2013/02/blog-post.html - 代码块未自动美化,但如果您打开Chrome控制台并输入prettyPrint()代码将被正确突出显示。
编辑5 之所以我认为我的问题不是博客,因为这个家伙的代码仍然使用相同的技术进行美化:http://errorbuster.blogspot.com/2012/07/prettify-syntax-highlighter-for-blogger.html
编辑6 正如Jeffery To在他的回答中所指出的,Dynamics View使用AJAX加载博客内容,因此在加载实际内容之前,将对文档加载的任何JS调用执行。因此,对实际博客内容而不是文档执行的任何JavaScript都是无效的。所以我想现在的问题是如何挂钩动态视图ajax:complete
事件,如果有这样的事情,但我怀疑有。谢谢所有回复的人。我不确定这是否可以算作错误,但我会向博主提出问题。
结论请阅读Jeffery To的回答。他发现事件要调用该函数。
答案 0 :(得分:18)
我相信您的测试页面使用的是Blogger的“Ajax模板”(不确定官方名称是什么),而您发布的其他链接则使用的是经典模板。
如果您重新加载测试页,则会首先在页面中间看到Blogger徽标,然后会显示您的内容。如果您查看测试页面源,您将看到很多代码,但不会看到您的内容。我相信布局模板,Blogger的代码首先运行,然后使用Ajax获取您的内容。在将内容加载到页面之前,将运行在文档就绪(DOMContentLoaded)或窗口加载上运行的任何JavaScript代码。
我相信如果您add a HTML/Javascript widget到页面(在您的内容阻止之后),然后在该窗口小部件中包含对prettyPrint()
的调用,则每次显示帖子时都应调用它。
更新:此模板的官方名称为“动态视图”,动态视图似乎不支持HTML / JavaScript小部件。我找不到任何可以让你浏览Blogger的JavaScript的API,所以我相信答案(至少现在)是不可能添加模板级代码来做你想要的。最实用的方法是在每个帖子中加上script
标记prettyPrint()
: - (
更新2:我已经通过Blogger的代码进行了跟踪,我认为我找到了一个合适的(可绑定的)事件。尝试在动态视图代码之后(在head
元素中的<script src='//www.blogblog.com/dynamicviews/...'></script>
元素中)包含此内容:
<script>
$(window.blogger.ui()).on('viewitem', function (event, post, element) {
prettyPrint();
});
</script>
每次用户查看项目时都会触发viewitem
事件(在页面的生命周期内可能会多次发生)。 element
参数是项目容器元素的jQuery对象,因此如果您想保存prettyPrint()
一段时间,您可以执行此操作:
<script>
$(window.blogger.ui()).on('viewitem', function (event, post, element) {
element.each(function () {
// first argument is a callback function
// second argument is a root element or document to check
prettyPrint(null, this);
});
});
</script>
答案 1 :(得分:3)
上面的代码段可能存在一些问题。
如果您使用<body onload="...">
挂钩活动,其他javascript代码可能会覆盖它。
Dom.addEventListener
无法与Internet Explorer一起使用,您需要在Dom.attachEvent
使用// window.ready
function register_onload(func){
var oldOnload = window.onload;
if(typeof(oldOnload) == 'function'){
window.onload = function(){
oldOnload();
func();
}
}else{
window.onload = function(){
func();
}
}
}
// document.ready
function register_onload(func){
var old_onload = document.onreadystatechange;
if(typeof old_onload == 'function'){
document.onreadystatechange = function(){
old_onload();
if(document.readyState == 'complete'){
func();
}
}
}else{
document.onreadystatechange = function(){
if(document.readyState == 'complete'){
func();
}
}
}
}
。
基本上,当我不能或不能使用javascript框架(如jquery进行事件处理)时,我会将旧代码用于onload事件处理:
// copy 2nd snippet here...
register_onload(function(){
prettyPrint();
});
我附上两个代码,这些代码的工作方式略有不同。 主要是如果你使用document.ready(第二个片段),那么当加载页面并创建所有HTML元素时,钩子代码将运行。 但是在document.ready上,无法保证所有javasript和css代码也被加载,所以如果你想加载所有的代码和脚本,那么你需要window.ready(第一个片段)。
根据您的情况,我相信您需要第二个document.ready片段,您可以通过以下方式使用它:
/*<![CDATA[*/ ... /*]]>*/
另外,我建议您将javacript代码放在<script type="text/javascript">/*<![CDATA[*/
// shorter version of the 2nd snippet
function register_onload(f){
var d=document,o=d.onreadystatechange;
if(typeof(o)=='function'){
d.onreadystatechange=function(){o();if(d.readyState=='complete')f();}
}else{
d.onreadystatechange=function(){if(d.readyState=='complete')f();}
}
}
register_onload(function(){
prettyPrint();
});
/*]]>*/</script>
符号之间,这样您的最终代码将如下所示:
{{1}}
希望这可以帮助您解决问题。