コアスクリプトを2回含めないようにする
以前のリクエストでスクリプトがすでに含まれている場合は、これを使用して、スクリプトが再度含まれないようにします。
// For jQuery core, Yii switches between the human-readable and minified
// versions based on DEBUG status; so make sure to catch both of them
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
Yii::app()->clientScript->scriptMap['jquery.min.js'] = false;
独立してレンダリングされているビューと、AJAXに含まれるHTMLフラグメントとしてレンダリングされているビューがある場合は、これを内側にラップしてif (Yii::app()->request->isAjaxRequest)
すべてのベースをカバーできます。
jQueryスクリプトが2回含まれないようにするため(JSソリューション)
スクリプトがクライアント側に2回含まれるのを防ぐ可能性もあります。これは直接サポートされておらず、少し面倒ですが、実際には正常に機能し、サーバー側でクライアント側で何が起こっているか(つまり、どのスクリプトがすでに含まれているのか)を知る必要はありません。
アイデアは、サーバーからHTMLを取得し、<script>
正規表現の置換でタグを削除することです。重要な点は、jQueryコアスクリプトとプラグインがすでにロードされているかどうかを検出し(それらが作成$
またはプロパティを作成するため)、これを条件付きで実行できることです。
function stripExistingScripts(html) {
var map = {
"jquery.js": "$",
"jquery.min.js": "$",
"jquery-ui.min.js": "$.ui",
"jquery.yiiactiveform.js": "$.fn.yiiactiveform",
"jquery.yiigridview.js": "$.fn.yiiGridView",
"jquery.ba-bbq.js": "$.bbq"
};
for (var scriptName in map) {
var target = map[scriptName];
if (isDefined(target)) {
var regexp = new RegExp('<script.*src=".*' +
scriptName.replace('.', '\\.') +
'".*</script>', 'i');
html = html.replace(regexp, '');
}
}
return html;
}
対応するスクリプトがすでに含まれている場合に定義されるファイル名とオブジェクトのマップがあります。着信HTMLをこの関数に渡すと、<script>
以前にロードされたスクリプトに対応するタグがチェックされ、削除されます。
ヘルパー関数isDefined
は次のとおりです。
function isDefined(path) {
var target = window;
var parts = path.split('.');
while(parts.length) {
var branch = parts.shift();
if (typeof target[branch] === 'undefined') {
return false;
}
target = target[branch];
}
return true;
}
イベントハンドラーを2回アタッチしないようにする
Javascriptオブジェクトを使用するだけで、ハンドラーを既にアタッチしているかどうかを覚えておくことができます。はいの場合は、再度取り付けないでください。例(コードを表示):
Yii::app()->clientScript->registerScript("view-script","
window.myCustomState = window.myCustomState || {}; // initialize if not exists
if (!window.myCustomState.liveClickHandlerAttached) {
window.myCustomState.liveClickHandlerAttached = true;
$('.link').live('click',function(){
alert('test');
})
}
");