16

我正在尝试在 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自述文件说我不应该prettyPrint()直接用作处理程序,而是将它包装在一个闭包中。所以我添加了这段代码,类似于 README 中的示例,<head>但无济于事。

<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 在他的回答中指出的那样,动态视图使用 AJAX 加载博客内容,因此任何 JS 对文档加载的调用都将在加载实际内容之前执行。因此,对实际博客内容而非文档执行的任何 JavaScript 都是无效的。所以我想现在的问题是如何挂钩 Dynamics Viewajax:complete事件,如果有这样的事情,但我怀疑有。感谢所有回复的人。我不确定这是否可以算作一个错误,但我会向博主提出问题。

结论请阅读 Jeffery To 的回答。他找到了调用函数的事件。

4

2 回答 2

18

我相信您的测试页面使用的是 Blogger 的“Ajax 模板”(不确定正式名称是什么),而您发布的另一个链接使用的是经典模板。

如果您重新加载测试页,您首先会在页面中间看到 Blogger 徽标,然后您的内容就会出现。如果您查看测试页源代码,您会看到很多代码,但看不到您的内容。我相信对于布局模板,Blogger 的代码首先运行,然后使用 Ajax 获取您的内容。任何在文档就绪 (DOMContentLoaded) 或窗口加载时运行的 JavaScript 代码都将在您的内容加载到页面之前运行。

我相信如果您向页面添加一个 HTML/Javascript 小部件(在您的内容块之后),然后在该小部件中包含一个调用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每次用户查看项目时都会触发该事件(在页面的生命周期中可能会发生多次)。参数是项目容器元素的elementjQuery 对象,所以如果你想节省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>
于 2013-02-02T07:10:12.660 回答
3

上面的代码段可能存在一些问题。如果您使用其他 javascript 代码挂钩事件<body onload="...">可能会覆盖它。 Dom.addEventListener不适用于 Internet Explorer,您需要在Dom.attachEvent那里使用。基本上,当我不使用或不能使用 javascript 框架(例如 jquery 进行事件处理)时,我会使用旧代码进行 onload 事件处理:

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

我附上了两个代码,它们的工作方式略有不同。主要是如果您使用 document.ready( 2nd snippet ),那么当页面加载并创建所有 HTML 元素时,挂钩代码将运行。但是在 document.ready 上,不能保证所有的 javasript 和 css 代码也会被加载,所以如果你想加载所有的代码和脚本,那么你需要 window.ready( 1st snippet )。

对于您的情况,我相信您需要第二个 document.ready 片段,您可以通过以下方式使用它:

// copy 2nd snippet here...
register_onload(function(){
    prettyPrint();
});

另外,我建议您将 javacript 代码放在/*<![CDATA[*/ ... /*]]>*/符号之间,这样您的最终代码将如下所示:

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

希望这可以帮助您解决问题。

于 2013-02-01T17:17:50.373 回答