我已经添加了脚本,但是我想知道首选方法。
我只是将<script>标记直接放在模板的header.php中。

是否有插入的首选方法外部或自定义js文件?
如何将js文件绑定到单个页面? (我有主页)

评论

看几天前我的问题,部分问题的答案在那里:-如何用WordPress链接外部jQuery / Javascript文件

好问题!这是一个非常常见的问题,我们肯定需要在这里进行详细记录。

谢谢。我已经看到了,但是还没有完全解决我的问题。

没关系,我知道它不会回答您所有的问题,但是对于将来冲浪的人,还有其他文章的参考文献:-)

另请参阅wordpress.stackexchange.com/questions/575/…

#1 楼

在主题中使用wp_enqueue_script()

基本的答案是在前端wp_enqueue_script()wp_enqueue_scripts挂钩中使用admin_enqueue_scripts。它可能看起来像这样(假设您正在从主题的functions.php文件进行调用;请注意我如何引用样式表目录):

<?php
add_action( 'wp_enqueue_scripts', 'mysite_enqueue' );

function mysite_enqueue() {
  $ss_url = get_stylesheet_directory_uri();
  wp_enqueue_script( 'mysite-scripts', "{$ss_url}/js/mysite-scripts.js" );
}


这是基础。

预定义脚本和多个相关脚本

但是,假设您要同时包含jQuery和jQuery UI的Sortable,这些列表可从WordPress随附的默认脚本列表中获得,并且您想要自己的脚本依靠他们?很简单,只需使用WordPress中定义的预定义句柄包含前两个脚本,然后为您的脚本提供wp_enqueue_script()的第三个参数,这是每个脚本使用的脚本句柄的数组,例如:

<?php
add_action( 'wp_enqueue_scripts', 'mysite_enqueue' );

function mysite_enqueue() {
  $ss_url = get_stylesheet_directory_uri();
  wp_enqueue_script( 'mysite-scripts', "{$ss_url}/js/mysite-scripts.js", array( 'jquery', 'jquery-ui-sortable' ) );
}


插件中的脚本

如果要改为在插件中执行该怎么办?使用plugins_url()函数指定Javascript文件的URL:

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue' );

function my_plugin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url('/js/my-script.js',__FILE__), array('jquery','jquery-ui-sortable'), MY_PLUGIN_VERSION );
}


版本化脚本

还请注意,上面我们给插件提供了一个版本号,并将其作为第4个参数传递给wp_enqueue_script()。版本号在源中作为脚本的URL中的查询参数在源中输出,并用于在版本更改时强制浏览器重新下载可能缓存的文件。

仅在需要的页面上加载脚本

Web Performance的第一条规则要求最小化HTTP请求,因此,只要有可能,就应该限制脚本仅在需要的地方加载。例如,如果您只需要在admin中使用脚本,则使用admin_enqueue_scripts挂钩将其限制为管理页面:

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_enqueue' );

function my_plugin_admin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url( '/js/my-script.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable' ), MY_PLUGIN_VERSION );
}


将脚本加载到页脚中

如果您的脚本是需要加载到页脚中的脚本之一,则wp_enqueue_script()的第5个参数告诉WordPress延迟它并将其放置在页脚中(假设您的主题没有行为不当,并且确实调用了wp_footer钩子,例如所有好的WordPress主题都应该):

<?php
define( 'MY_PLUGIN_VERSION', '2.0.1' );
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_enqueue' );

function my_plugin_admin_enqueue() {
  wp_enqueue_script( 'my-script', plugins_url( '/js/my-script.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable' ), MY_PLUGIN_VERSION, true );
}


更细粒度的控制

如果您需要更精细的粒度控制,那么Ozh撰写了一篇很棒的文章,标题为How若要:使用WordPress插件加载Java脚本,它会详细介绍更多信息。

禁用脚本来获得控制权

Justin Tadlock的文章不错,标题为“如何禁用脚本和样式,以备不时之需” to:


将多个文件合并为单个文件(里程可能因JavaScript而异)。
仅在我们使用脚本或样式的页面上加载文件。
不必在style.css文件中使用!important来进行简单的CSS调整。

通过wp_localize_script()将值从PHP传递到JS


他的博客Vladimir Prelovac上有一篇很棒的文章,标题为向WordPress插件添加JavaScript代码的最佳实践,他在其中讨论了使用wp_localize_script()来允许您设置服务器端PHP中的变量值,以供以后在客户端Javascript中使用。 br />
使用wp_print_scripts()进行真正的细粒度控制


最后,如果您需要真正的细粒度控制,则可以按照《啤酒星球》中题为How的文章中讨论的wp_print_scripts()进行研究。仅在帖子需要时才有条件地包括CSS和JavaScript。

Epiloque

关于在WordPress中包含Javascript文件的最佳做法,这就是它。如果我错过了某件事(可能已经错过了),请务必在评论中告知我,以便为将来的旅行者添加更新。

评论


那是一篇巨大的文章!现在我有很多选择;)

–naugtur
2010年8月19日在12:19

好的,它起作用了。现在,问题的第二部分-如何检查我是否在首页上?

–naugtur
2010年8月19日13:39

在此处寻找答案:wordpress.stackexchange.com/questions/575/…

–naugtur
10年8月23日在10:23

插入admin_init而不是要求is_admin()。如果您使用的是Google CDN,请删除version参数,否则浏览器缓存将保存两个版本:一个不包含来自其他站点的查询字符串,另一个不包含您的。

– fuxia♦
2010年11月9日23:02

@toscho-好的,我会更新。

– MikeSchinkel
2010年11月10日,1:11

#2 楼

为了赞扬Mikes使用排队的精彩示例,我只想指出不需要将包含为依赖关系的脚本排入队列...

我将在插件标题下的脚本下使用该示例。迈克的答案。

define('MY_PLUGIN_VERSION','2.0.1');

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_scripts' );
function my_plugin_enqueue_scripts() {
    wp_enqueue_script('jquery');
    wp_enqueue_script('jquery-ui-sortable');
    wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION);
}


可以将其修整为可读。 ,WordPress会为您的脚本找到并准备好队列,因此您不需要对这些脚本进行任何独立调用。脚本以错误的顺序输出,这里让我举一个例子

define('MY_PLUGIN_VERSION','2.0.1');

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_scripts' );
function my_plugin_enqueue_scripts() {
    wp_enqueue_script('my-script', plugins_url( '/js/my-script.js', __FILE__ ), array('jquery','jquery-ui-sortable'), MY_PLUGIN_VERSION);
}


如果脚本2依赖于脚本3(即脚本3应该首先加载),没关系,WordPress将确定这些脚本的入队优先级并以正确的顺序输出它们,总之,WordPress会自动为您解决所有问题。

评论


我认为init不是分发队列的适当位置。

–brasofilo
2013年9月21日在23:14

代码最初是从Mike的答案复制而来,然后进行调整以说明问题。但是您是正确的,所以我更新了答案,以使用更好,更正确的钩子。

– t31os
2014年1月28日14:42

#3 楼

对于小脚本,您可能不想包含在单独的文件中,例如,因为它们是动态生成的,因此WordPress 4.5并提供了wp_add_inline_script。此功能基本上将脚本锁定到另一个脚本。例如,假设您正在开发主题,并希望客户能够通过以下方式插入自己的脚本(例如Google Analytics(分析)或AddThis)选项页面。然后,您可以使用wp_add_inline_script将脚本锁定到您的主js文件(例如mainjs),如下所示:

$custom_script = get_option('my-script')
if (!empty($custom_script)) wp_add_inline_script ('mainjs', $custom_script);


#4 楼

我的首选方法是获得良好的性能,因此,与其使用wp_enqueue_script而不是使用HEREDOC和Fetch API来并行异步加载所有内容:
头部,有时还带有诸如此类的样式:

$jquery_script_path = '/wp-includes/js/jquery/jquery.js?ver=1.12.4';
$jquery_dependent_script_paths = [
  get_theme_file_uri( '/assets/js/global.js' ),
  get_theme_file_uri( '/assets/js/jquery.scrollTo.js' ),
  get_theme_file_uri( '/assets/js/skip-link-focus-fix.js' ),
  get_theme_file_uri( '/assets/js/navigation.js' )
];
$jquery_dependent_script_paths_json = json_encode($jquery_dependent_script_paths);
$inline_scripts = <<<EOD
<script>
(function () {
  'use strict';
  if (!window.fetch) return;
  /**
   * Fetch Inject v1.6.8
   * Copyright (c) 2017 Josh Habdas
   * @licence ISC
   */
  var fetchInject=function(){"use strict";const e=function(e,t,n,r,o,i,c){i=t.createElement(n),c=t.getElementsByTagName(n)[0],i.type=r.blob.type,i.appendChild(t.createTextNode(r.text)),i.onload=o(r),c?c.parentNode.insertBefore(i,c):t.head.appendChild(i)},t=function(t,n){if(!t||!Array.isArray(t))return Promise.reject(new Error("`inputs` must be an array"));if(n&&!(n instanceof Promise))return Promise.reject(new Error("`promise` must be a promise"));const r=[],o=n?[].concat(n):[],i=[];return t.forEach(e=>o.push(window.fetch(e).then(e=>{return[e.clone().text(),e.blob()]}).then(e=>{return Promise.all(e).then(e=>{r.push({text:e[0],blob:e[1]})})}))),Promise.all(o).then(()=>{return r.forEach(t=>{i.push({then:n=>{"text/css"===t.blob.type?e(window,document,"style",t,n):e(window,document,"script",t,n)}})}),Promise.all(i)})};return t}();
  fetchInject(
    $jquery_dependent_script_paths_json
  , fetchInject([
    "{$jquery_script_path}"
  ]));
})();
</script>
EOD;


导致看起来像这样的瀑布,立即加载所有内容,但控制执行顺序:



注意:这需要使用Fetch API,并非所有浏览器都提供。