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>

EDIT 2 READMEprettyPrint()には、ハンドラーとして直接使用するのではなく、代わりにクロージャーでラップする必要があると書かれています。そのため、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 は、上記で説明したように、prettify ライブラリが追加されたデフォルトの Dynamics View (クラシック) テンプレートです。

EDIT 4問題を示すリンクは次のとおりです: http://testprettyprint.blogspot.com/2013/02/blog-post.html -- コード ブロックは自動的に整形されませんが、Chrome のコンソールを開いて prettyPrint() と入力するとコードが正しく強調表示されます。

EDIT 5ブロガーの問題ではなく私の問題だと思う理由は、この男がまだ同じ手法を使用してコードを整形しているためです

編集 6 Jeffery To が彼の回答で指摘したように、Dynamics View は AJAX を使用してブログ コンテンツを読み込むため、ドキュメントの読み込みに関する JS 呼び出しは、実際のコンテンツが読み込まれる前に実行されます。したがって、ドキュメントではなく、実際のブログ コンテンツに対して実行される JavaScript はすべて無効です。したがって、Dynamics View イベントにフックする方法が問題になると思いますがajax:complete、そのようなものがあるとは思えません。返信してくれたみんなありがとう。これがバグとして数えられるかどうかはわかりませんが、blogger に問題を報告します。

結論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 のコードを調べたところ、適切な (バインド可能な) イベントが見つかったと思います。これを Dynamic Views コードの後 (head要素内、<script src='//www.blogblog.com/dynamicviews/...'></script>タグの後)に含めてみてください。

<script>
$(window.blogger.ui()).on('viewitem', function (event, post, element) {
    prettyPrint();
});
</script>

このviewitemイベントは、ユーザーがアイテムを表示するたびにトリガーされます (ページの存続期間中に複数回発生する可能性があります)。引数は項目のコンテナー要素のjQuery オブジェクトなので、少し時間elementを節約したい場合は次のようにします。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

上記のスニペットにはいくつかの問題がある可能性があります。イベントを<body onload="...">他の JavaScript コードでフックすると、イベントが上書きされる可能性があります。 Dom.addEventListenerInternet Explorer では動作しません。そこで使用する必要がDom.attachEventあります。基本的に、イベント処理に jquery などの JavaScript フレームワークを使用しない、または使用できない場合は、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();
            }
        }
    }
}

少し異なる方法で機能する 2 つのコードを添付します。主に document.ready( 2nd snippet ) を使用する場合、フックされたコードは、ページが読み込まれたときに実行され、すべての HTML 要素が作成されます。しかし、document.ready では、すべての javasript および css コードも読み込まれるという保証はありません。そのため、すべてのコードとスクリプトを読み込む場合は、window.ready( 1st snippet ) が必要です。

あなたの状況では、2番目の 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 に答える