it-swarm.cn

向网站添加自定义javascript文件的首选方法是什么?

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

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

68
naugtur

在主题中使用wp_enqueue_script()

基本答案是在wp_enqueue_scripts钩子中使用 wp_enqueue_script() 作为前端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" );
}

这是基础知识。

预定义和多个依赖脚本

但是,假设你想要从 WordPress中包含的默认脚本列表中包含jQuery和jQuery UI Sortable,你希望你的脚本依赖于它们吗?简单,只需使用 在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 );
}

版本化脚本

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

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

Web Performance的第一条规则是最小化HTTP请求 所以只要有可能,你应该限制脚本只在需要的地方加载。例如,如果您只需要管理员将脚本限制为使用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 有一篇很棒的文章,名为 如何:用你的WordPress插件加载Javascript 详细说明。

禁用脚本以获得控制权

Justin Tadlock 有一篇名为 如何禁用脚本和样式 的好文章,以防你想要:

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

使用wp_localize_script()将值从PHP传递给JS

在他的博客上,Vladimir Prelovac有一篇很棒的文章,名为 向WordPress插件添加JavaScript代码的最佳实践 ,他讨论了如何使用wp_localize_script()来设置服务器端PHP中的变量值稍后在您的客户端Javascript中使用。

wp_print_scripts()实现细粒度控制

最后,如果你需要真正细粒度的控制,你可以查看wp_print_scripts(),如 Beer Planet 中所述,标题为 如何有条件地包含CSS和JavaScript只有当帖子 需要时。

Epiloque

这就是使用WordPress包含Javascript文件的最佳实践。如果我错过了某些东西(我可能有),请务必在评论中告诉我,以便为未来的旅行者添加更新。

78
MikeSchinkel

为了赞美Mikes使用入队的精彩插图我只想指出作为依赖性包含的脚本不需要排队......

我将使用 脚本插件中的示例 Mike的答案中的标题。

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);
}

这可以减少阅读..

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);
}

当您设置依赖项时,WordPress会为您的脚本查找并排队它们,因此您无需对这些脚本进行任何独立调用。

另外,你们中的一些人可能想知道设置多个依赖项是否会导致脚本以错误的顺序输出,这里让我举一个例子

wp_enqueue_script( 'first-script', 'example/path/example_script_1.js', array('second-script','third-script') );

如果脚本2依赖于脚本3(即脚本3应该首先加载),这没关系,WordPress将确定这些脚本的入队优先级并以正确的顺序输出它们,简而言之,它们都是自动解决的由WordPress为你。

11
t31os

对于您可能不希望包含在单独文件中的小块脚本,例如因为它们是动态生成的,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);
0
cjbj

我的首选方法是获得良好的性能,因此我不是使用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;

然后将它们插入头部,有时还会带有以下样式:

function wc_inline_head() {
  global $inline_scripts;
  echo "{$inline_scripts}";
  global $inline_styles;
  echo "{$inline_styles}";
}

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

enter image description here 

注意: 这需要使用Fetch API,这在所有浏览器中都不可用。

0
Josh Habdas