Добавление onload к тегу body

25 авг. 2010 г., 09:24:15
Просмотры: 14.7K
Голосов: 5

Сейчас я разрабатываю плагин, который будет встраивать тур по Google Earth в запись или страницу WordPress через шорткод.

Проблема, с которой я столкнулся, заключается в том, что для загрузки тура необходимо добавить атрибут onload="init()" в тег <body>.

Я могу изменить конкретный файл шаблона, но поскольку это для релиза, мне нужно добавить его динамически через хук. Есть идеи?

1
Комментарии

Разве нельзя использовать ненавязчивый JavaScript через jQuery?

MikeSchinkel MikeSchinkel
25 авг. 2010 г. 10:20:39
Все ответы на вопрос 5
6

А вот решение на jQuery (как предложил Майк в своем первом комментарии).

function add_my_scripts() {
    wp_enqueue_script( 'jquery' );
    wp_enqueue_script( 'my_init_script', SCRIPTSRC, 'jquery', '1.0' );
}
add_action( 'init', 'add_my_scripts' );

Затем добавьте скрипт в ваш плагин, который делает следующее:

jQuery.noConflict();

jQuery(document).ready(function($) {
    init();
});

Это запустит jQuery в режиме без конфликтов (если он еще не в этом режиме) и добавит вызов метода init(), когда документ будет готов. Это более безопасный метод, чем использование body onready(), потому что функция onready() может вызывать только одну вещь... так что никто другой не сможет подключить что-либо к этому или добавить собственный скрипт. Лучше сделать ваш плагин как можно менее навязчивым, чтобы другие плагины не мешали ему или наоборот.

25 авг. 2010 г. 17:18:20
Комментарии

Я считаю, что ваш метод один из предпочтительных. Думаю, jQuery-код можно даже сократить, потому что jQuery предлагает сокращение для функции ready.

hakre hakre
25 авг. 2010 г. 19:02:52

@EAMann - Не могли бы вы подробнее объяснить jQuery.noConflict()? Я никогда не использовал эту функцию, и документация мне не совсем понятна.

MikeSchinkel MikeSchinkel
25 авг. 2010 г. 21:17:40

По умолчанию jQuery использует символ $ как синоним для jQuery... это может нарушить работу других библиотек (Prototype, Scriptaculous и т.д.), а также пользовательских функций $. Использование jQuery.noConflict() отключает это поведение по умолчанию, но вы по-прежнему можете использовать функцию $ в своём коде, если передадите её... так что функция, которую я определил выше, может использовать $.ajax и другие нативные вызовы внутри объявленной функции.

EAMann EAMann
25 авг. 2010 г. 21:35:42

@MikeSchinkel: http://hakre.wordpress.com/2010/08/11/selekturz-they-iz-serius-bizniss/

hakre hakre
28 авг. 2010 г. 01:43:19

@EAMann - Спасибо. Я знал про использование внутри функции ready(), но не осознавал, что будет конфликт, если просто никогда не использовать $ за пределами замыкания. Я до сих пор не понимаю, что это делает. Возможно, мне стоит просто поизучать этот вопрос подробнее...

MikeSchinkel MikeSchinkel
28 авг. 2010 г. 02:49:58

@MikeSchinkel - По умолчанию jQuery устанавливает глобальный $ как псевдоним объекта jQuery. Вызов jQuery в режиме noConflict() переопределяет это поведение по умолчанию.

EAMann EAMann
14 дек. 2010 г. 16:56:33
Показать остальные 1 комментариев
2

Вот один из подходов. Вы должны добавить вызов add_action() внутри вашего хука, как я полагаю. Предполагается, что функция init уже определена в приведённом JavaScript коде. Если это не так, то данный код не сработает, но подключение скрипта, кажется, это проблема, которую вы уже решили, если я правильно вас понял. Обратите внимание, что вам не обязательно добавлять его в wp_foot, вы так же легко можете добавить его в wp_head:

<?php

function mypluginprefix_onload_init() { ?>
<script language="text/javascript">
// проверяем стандартный способ добавления событий onload
if ( typeof(window.addEventListener) !== 'undefined' )
    window.addEventListener( "load", init, false );
// или старый нестандартный способ для msie
else if ( typeof(window.attachEvent) !== 'undefined' ) {
    window.attachEvent( "onload", init );
}
</script>
<?php }

// это помещается в ваш хук
add_action('wp_foot', 'mypluginprefix_onload_event');
?>
25 авг. 2010 г. 17:09:08
Комментарии

Почему чистый JavaScript, а не jQuery? jQuery обрабатывает все крайние случаи, когда код может выполниться до полной загрузки страницы.

MikeSchinkel MikeSchinkel
25 авг. 2010 г. 21:16:10

Для простого события onload, я считаю jQuery избыточным. Просто прикрепите обработчик и всё. jQuery создает дополнительную нагрузку в плане загрузки. Я люблю jQuery, но это не решение для всего. Если бы jQuery уже был подключен, тогда я бы сказал использовать его, но мой ответ обходится без него.

artlung artlung
25 авг. 2010 г. 22:00:24
0

Игнорируя возможность сделать это с помощью jQuery, одним из вариантов является использование хука template_include вместе с ob_start() и callback-функцией. Ваша callback-функция может выполнить поиск строки '<body' и заменить её на '<body onload="init()"', как показано в следующем коде. Вы можете использовать его напрямую в своем плагине, просто убедитесь, что изменили названия в соответствии с вашими соглашениями об именовании:

<?php
add_filter('template_include','start_buffer_capture',1);
function start_buffer_capture($template) {
  ob_start('end_buffer_capture');  // Запускаем буферизацию вывода
  return $template;
}
function end_buffer_capture($buffer) {
  return str_replace('<body','<body onload="init()"',$buffer);
}

Обратите внимание, что я бы не считал приведенный выше код полностью надежным. Сомневаюсь, что он обработает все крайние случаи, так как я просто быстро его написал для ответа на ваш вопрос. Тем не менее, он показывает, как решить задачу в стандартном случае, и после тестирования вы сможете доработать его для обработки важных крайних случаев (например, что делать, если '<BODY' написан в верхнем регистре и т.д.).

25 авг. 2010 г. 10:50:12
0

Вот JavaScript для динамического добавления callback при загрузке страницы, с jQuery или без него:

function add_onload() {
    ?>
    <script type="text/javascript">
    my_onload_callback = function() { alert('Привет!'); }; // тестовая функция

    if( typeof jQuery == "function" ) { 
        jQuery(my_onload_callback); // document.ready
    } else {
        document.getElementsByTagName('body')[0].onload = my_onload_callback; // body.onload
    }
    </script>
    <?php
}
add_action( 'wp_footer', 'add_onload' );

В вашем случае вам нужно просто заменить my_onload_callback на ваш метод инициализации.

25 авг. 2010 г. 13:49:35
4

Покопался ещё немного и нашёл «лучший» способ заставить это работать (Google усложняет встраивание своих туров по Земле, и их гаджет не работает).

В итоге я создал плагин, который использует комбинацию шорткода и произвольного поля.

26 авг. 2010 г. 17:58:06
Комментарии

Если у вас есть возможность, я бы рекомендовал опубликовать код для пользы других пользователей, которые найдут этот пост.

User User
26 авг. 2010 г. 18:45:27

Да, это помогло бы лучше понять, о чем вы изначально спрашивали. Вопрос и ответ должны идти вместе.

hakre hakre
28 авг. 2010 г. 01:46:36

Для тех, кто может захотеть, вот плагин. Он размещен в репозитории WP http://wordpress.org/extend/plugins/google-earth-tours/

Norcross Norcross
14 сент. 2010 г. 23:54:25

Вы можете принять свой собственный ответ, чтобы показать, что проблема решена для вас.

Jan Fabry Jan Fabry
4 нояб. 2010 г. 20:02:38