プラグイン開発において、フロントエンドでのjQueryコンポーネントの衝突を防ぐためのベストプラクティスは何ですか?
たとえば、jQuery Appriseダイアログをフロントエンドで何かをロードするプラグインに含めるとしましょう。さらに別のプラグインで同じことができます。これは2回ロードされ宣言されるか、あるいは私のものではないのに1つがフォークされカスタマイズされているので、私たちはフロントエンドでJavascriptエラーを受け取ります(私は思います)。
(フロントエンドにjQueryコンポーネントをロードするために、wp_head()アクションイベントを介してwp_register_script()およびwp_enqueue_script()ストラテジーを使用するベストプラクティスを行っていることに注意してください。)
JQueryコアに関する問題は非常に一般的であり、多くのプラグインにはそれを防止する方法がたくさんあります。
JQuery用のプラグインについて話すとき、別の問題がありますが、あなたはそれを同じような方法で取り除くことができます。
あなたの状況では、私はあなたのプラグインの設定ページにインクルードスイッチを追加する一般的な解決策を好みます - 私はこれがjQueryコアのプラグインに非常に人気があると思いますjQueryプラグインにも使用できます。
別の解決策は、jQueryエクストラメソッド(プラグインから)が定義されているかどうかをチェックするためにjsでスクリプトを書くことです。そうでない場合は、スクリプトにプラグインを含めることができます。この解決策は、非常に低い優先度のスクリプト用のフックを追加した場合にのみ機能します。それは他のプラグインの後に実行され、この状態は機能します。
スクリプトをエンキューまたは登録するためのベストプラクティスは、wp_register_script
およびwp_enqueue_script
を使用することです。スクリプトを追加するためにこの関数を使わないプラグインやテーマは使うべきではありません。
理由は簡単です。wp_register_script()
を使うと、登録されているスクリプトに関する多くの情報を取得することができます。特定のソースがすでに登録されているかどうかは特にです。
ソースが既に登録されているかどうかをテストするために 単純なクラス を書きました。クラスはスクリプトの登録を解除して新しいスクリプトを登録するか、新しいスクリプトをスキップすることができます。このクラスはあなた自身の開発の出発点であるべきです。プロダクション環境ではではなくです!
クラスはどのように機能しますか?
クラスは登録されるべきスクリプトで配列を検索します。それよりも、各登録済みスクリプトのファイル名(およびのみファイル名)を、登録する必要があるスクリプトのファイル名と比較します。 script/filenameがまだ登録されていない場合は、そのハンドルが配列に追加され、後で登録されます。
スクリプトのフルパスまたはバージョン、あるいはスクリプトを登録するかどうかを決定するために必要なものすべてを比較するようにクラスを拡張することができます。
簡単な例
$my_scripts = array(
'foo' => array(
'src' => 'external/ressource/foo.js',
'deps' => array( 'jquery' ),
'version' => false,
'in_footer' => true
),
'bar' => array(
'src' => home_url( '/wp-admin/js/common.min.js' ),
'deps' => false,
'version' => false,
'in_footer' => true
),
'jquery' => array(
'src' => '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js',
'deps' => false,
'version' => '1.8.3',
'in_footer' => true
),
);
$safe_register = new Safe_Registering_Scripts( $my_scripts, true );
global $wp_scripts;
var_dump( $wp_scripts->registered['jquery'] );
最初に、登録するすべてのスクリプトを含む配列を定義します。クラスは私たちのスクリプトを調べて、ソースが既に登録されているかどうか比較します。
foo
スクリプトは常に登録されます。bar
スクリプトは登録されません。jquery
スクリプトは特別な場合です。 jquery
というハンドルが既にありますが、クラス呼び出しの2番目のパラメーターは、このスクリプトソースを新しいソースに置き換える必要があることを示しています。var_dump()
でわかるように、jquery
スクリプトのソースはクラスに置き換えられました。そのため、クラスを拡張してテスト(source、js filename、version、enqueued scriptsなど)を調整すれば、jsの衝突を最小限に抑えることができます。
私の提案は、無名関数にコード分離を混ぜてjqueryが既に存在するかどうかをチェックすることです。
これが例です:
(function() {
var jQuery; // your jquery variable
// check if jquery is present and if it has the version you want
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.8.3') {
// load jquery lib from google hosted libraries
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js");
// wait for jquery lib to load
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
jqueryLoadHandler();
}
};
} else { // for other browsers
script_tag.onload = jqueryLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The current site is already using the jquery you want, so just point your variable to that jquery
jQuery = window.jQuery;
main();
}
// as soons as jquery is loaded
function jqueryLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call plugin main function
main();
}
// plugin main function
function main() {
jQuery(document).ready(function($) {
// Here you can use the $ without any problems
});
}
})(); // We call our anonymous function immediately
他のプラグインがwp_enqueue_scriptなしでjqueryを使用していても、この方法であなたのプラグインで問題なくjQueryを使用することができます。この無名関数内で使用するすべての変数と関数が、ページの残りの部分に干渉することはありません。
Wp_enqueue_scriptと統合されていれば、おそらくもっとうまくいくでしょう。
匿名関数内にjqueryをロードするというこのアプローチの詳細については、 http://alexmarandon.com/articles/web_widget_jquery/ を参照してください。