prettyPrint() не вызывается при загрузке страницы
Я пытаюсь подтвердить свой код в 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()
непосредственно как обработчик, но вместо этого заверните его в замыкание. Поэтому я добавил этот код, похожий на пример в 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 - это просто шаблон Dynamics View (Classic) по умолчанию с библиотекой prettify, добавленной, как описано выше.
РЕДАКТИРОВАТЬ 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 Как указал Джеффри То в своем ответе, Dynamics View загружает содержимое блога с помощью AJAX, поэтому любой вызов JS при загрузке документа будет выполняться ДО того, как будет загружен фактический контент. Поэтому любой JavaScript, выполняемый с фактическим содержимым блога, а не с документом, является недействительным. Итак, я думаю, что вопрос сейчас заключается в том, как подключиться к Dynamics View ajax:complete
событие, если есть такая вещь, но я сомневаюсь, что есть. Спасибо всем, кто ответил. Я не уверен, что это можно считать ошибкой, но я сообщу о проблеме блоггеру.
ЗАКЛЮЧЕНИЕ Пожалуйста, прочитайте ответ Джеффри То. Он нашел событие для вызова функции.
2 ответа
Я полагаю, что ваша тестовая страница использует "шаблоны Ajax" Blogger (не уверен, как называется официальное название), тогда как другая размещенная вами ссылка использует классические шаблоны.
Если вы перезагрузите тестовую страницу, сначала вы увидите логотип Blogger в середине страницы, а затем появится ваш контент. Если вы просматриваете исходный код тестовой страницы, вы увидите много кода, но не ваш контент. Я считаю, что с помощью шаблонов макетов сначала выполняется код Blogger, а затем он загружает ваш контент с помощью Ajax. Любой код JavaScript, который выполняется при готовности документа (DOMContentLoaded) или при загрузке окна, будет запущен до того, как ваш контент будет загружен на страницу.
Я полагаю, что если вы добавите виджет HTML/Javascript на страницу (после блока контента), то включите вызов prettyPrint()
внутри этого виджета он должен вызываться каждый раз, когда отображается сообщение.
Обновление: официальное название этого шаблона - "Динамические представления", и похоже, что виджет HTML / JavaScript не поддерживается для динамических представлений. Я не могу найти упоминания об API, который позволяет подключаться к JavaScript Blogger, поэтому я считаю, что ответ (по крайней мере, сейчас) заключается в том, что невозможно добавить код уровня шаблона, чтобы делать то, что вы хотите. Наиболее практичным способом было бы включить 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
событие вызывается каждый раз, когда пользователь просматривает элемент (что может происходить несколько раз за время существования страницы). 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>
Там может быть несколько проблем с вашими фрагментами выше. Если вы подключите событие с <body onload="...">
другие коды javascript могут перезаписать его.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( 2-й фрагмент), то подключенный код будет запускаться, когда страница загружена и все элементы HTML созданы. Но на document.ready нет гарантии, что все javasript и css коды также загружены, поэтому, если вы хотите, чтобы все коды и скрипты были загружены, вам нужен window.ready( 1-й фрагмент).
Я полагаю, что для вашей ситуации вам понадобится второй фрагмент document.ready, и вы можете использовать его следующим образом:
// copy 2nd snippet here...
register_onload(function(){
prettyPrint();
});
Также я рекомендую вам поместить свой код JavaScript между /*<![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>
Надеюсь, это поможет вам решить вашу проблему.