何时使用add_action('init')vs add_action('wp_enqueue_scripts')


10

在主题的functions.php中,我调用add_action以获得对加载jquery位置的控制(在页脚以及主题的其他脚本中)。

我遇到的问题是,当我使用add_action('wp_enqueue_scripts')时,只有在未加载任何插件的情况下,它才会启动。但是,add_action('init')方法在所有情况下均适用。

我不记得为什么,但是我相信在这种情况下首选add_action('wp_enqueue_scripts')。如果是这样,我如何在所有情况下都能正常工作?

在functions.php中

//if(!is_admin()){add_action('init', 'my_theme_init');} //THIS WORKS ALL THE TIME
//add_action('wp_enqueue_scripts', 'my_theme_init'); //THIS ONLY WORKS WHEN NO PLUGINS PRESENT

if(!is_admin())
{
    require_once(TEMPLATEPATH . '/functions_public.php');   
}

在functions_public.php中

function my_theme_init()
{

/* PREVENT DUPLICATE COPIES OF JQUERY FROM PLUGINS
**************************************************/
wp_deregister_script('jquery');

/* LOAD THE LOCAL WORDPRESS COPY OF JQUERY AND THEME CUSTOM SCRIPTS IN THE FOOTER
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);

wp_enqueue_script('jquery');

}

使用add_action('wp_enqueue_scripts')的第二种方法显然不会在存在插件的情况下执行,该插件向主题写出脚本依赖性。


5
请不要注册自己的jquery副本-使用WordPress随附的版本,否则最终将破坏插件:)
Stephen Harris

我同意,实际上我正在使用jQuery附带的那个。我只是将其与主题需要的其他js文件一起加载到单个.js(mythemescripts.js)中,以减少http请求。
N2Mystic 2012年

在所有浏览器中,一旦从您的站点请求了脚本,它就会被本地缓存。您只会在首页加载时收到额外的HTTP请求。如果将所有脚本合并为一个脚本,则每次WP发布使用新版本jQuery的更新时,您都将不得不更改此脚本。这==维护噩梦。
EAMann 2012年

2
@EAMann,第一次安装主题时,此后每次保存主题选项页面时,我都在重写mythemescripts.js,将jquery库的最新副本加载到其中。如果用户更新了其WP版本,则我的主题选项例程将加载其随附的jquery。它总是最新的。
N2Mystic 2012年

当页脚之前的文档正文中包含jquery调用时,仍然会出现问题。显然,在将.js脚本加载到页脚之前,会触发jQuery(document).ready。
N2Mystic 2014年

Answers:


26

许多插件开发人员的方法都不正确。在正确的方式是挂钩到wp_enqueue_scripts像你正在试图做的。

但是,这是典型请求中运行的挂钩的顺序:

  • muplugins_loaded
  • registered_taxonomy
  • Registered_post_type
  • plugins_loaded
  • sanitize_comment_cookies
  • setup_theme
  • load_textdomain
  • after_setup_theme
  • auth_cookie_malformed
  • auth_cookie_valid
  • set_current_user
  • 在里面
  • widgets_init
  • register_sidebar
  • wp_register_sidebar_widget
  • wp_default_scripts
  • wp_default_stypes
  • admin_bar_init
  • add_admin_bar_menus
  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts
  • posts_selection
  • wp
  • template_redirect
  • get_header
  • wp_head
  • wp_enqueue_scripts
  • wp_print_styles
  • wp_print_scripts
  • ... 多很多

关键是,最初告诉几个开发人员加入init他们的脚本入队。早在我们wp_enqueue_script陷入困境之前,那是做事的“正确”方法,而使这种做法永存的教程仍在互联网上四处徘徊,破坏了本来不错的开发人员。

我的建议是将您的功能分为两部分。在挂钩上执行wp_deregister_script/ wp_register_scriptinitwp_enqueue_scripts在实际将jQuery放入队列时使用该挂钩。

这将使您始终处在“正确执行”队列中的脚本中,并通过将jQuery替换为串联版本,然后再将其添加到队列中,从而使您免受数百名仍在“错误执行”的开发人员的保护。 。

您还需要添加init具有较高优先级的钩子:

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}

2
我本来会建议这样做,但是后来我意识到OP实际上是在注销jQuery,然后完全注册一个不同的脚本并将其称为“ jquery”。我认为这不是鼓励的好习惯,并且认为更好的方法是完全使jQuery出队,然后使用自定义句柄使自定义脚本入队。
Chip Bennett 2012年

指向有关priority添加操作的注意事项。这完全取决于您如何看待优先级。如果希望您的计算机“先运行”,则数字越小越好-执行队列顺序中的优先级越高。但是,如果您希望函数的效果优先于其他函数,那么您将希望它在以后运行-因此,按“效果”优先级更高。在这种情况下,您可能想要的数字更大。正如前面的评论者所建议的那样,换掉jquery的RTM版本没有什么好处。
Paul G.

3

这里有多个相互关联的问题。

  1. 用于排队脚本的正确动作挂钩是 wp_enqueue_scripts
  2. 要通过wp_enqueue_script(),在页脚中打印脚本,请将$footer参数设置为true
  3. 您的add_action( $hook, $callback )通话不应包裹在任何东西中;让他们直接从执行functions.php
  4. 您应该将is_admin()条件检查放入回调中
  5. 出于任何原因,您都不应从主题中注销核心捆绑脚本。即使您的目的是脚本串联,也就是Plugin领域
  6. 如果必须注销jquery,wp_enqueue_scripts则为时已晚。将您的注销/注册代码拆分为一个挂接到的回调init
  7. 其他脚本称为“ jquery”可能也不是一个好习惯。更好的选择就是让jQuery出队,然后加载自定义脚本。
  8. 确保对回调设置低优先级,以便覆盖插件
  9. 使用get_template_directory()而不是TEMPLATEPATH

放在一起:

<?php
function wpse55924_enqueue_scripts() {
    if ( ! is_admin() ) {

        // Dequeue jQuery
        wp_dequeue_script( 'jquery' );

        // Register/enqueue a custom script, that includes jQuery
        wp_register_script( 'mythemescripts', get_template_directory_uri() . '/scripts.mythemescripts.js', false, false,true );
        wp_enqueue_script( 'mythemescripts' ); 
    }
}
add_action( 'wp_enqueue_scripts', 'wpse55924_enqueue_scripts', 99 );

但是再次:这确实不是最好的方法。更好的选择是删除用于注销核心jQuery的插件add_action()回调-或使用不会像替换核心捆绑的jQuery那样鲁re的插件。


OP将WP分发版的jQu​​ery与其他一些脚本以编程方式组合在一起,因此,他的主题仅发出一个HTTP请求以加载所有JS文件。因此,自定义脚本确实包含jQuery,并且以这种方式加载不会破坏任何内容。覆盖已注册的“ jquery”句柄对于防止两次加载jQuery是必要的-一次在组合的JS文件中,第二次由任何尝试自行入队jQuery的插件再次执行。
EAMann 2012年

从语义上和实践_doing_it_wrong()上来说,不仅将jQuery称为“ jQuery”。另外:jQuery本身可以简单地出列,以确保它不会被加载两次。该wp_dequeue_script()电话只需要具有足够优先发生,以确保没有排队,后来它。
Chip Bennett
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.