1

サイト内の多くのページで繰り返されるSSIがいくつかあります。特に、ユーザーがツリー内のノードを展開または折りたたむことができるナビゲーションツリーがあります。

同じ.shtmlファイルが前のページに既に読み込まれている場合は、同じ.shtmlファイルが読み込まれないようにしたいのですが、この方法では、ユーザーがナビゲーションツリーのエントリの1つをクリックしても、ツリー全体がターゲットページに更新されません。 (これにより、ユーザーの現在のノードが折りたたまれます)。これを実現する方法について何かアイデアはありますか?

4

2 に答える 2

0

1 つの方法は、ナビゲーション ツリーを (iframe ではなく) 別のフレームに配置することです。これは、独自の問題をもたらします。インクルードはサーバー側で行われるため、インクルードされたコンテンツでページの更新を引き起こすものはすべて、SSI を介して含まれるものとそうでないものを考慮せずに、ページ全体を更新します。独自のフレーム内にツリーがあり、そのリンクがコンテンツ フレームを指すように変更されている場合、この問題は発生しません。もちろん、フレームを使用してこの問題を解決すると、別の問題が発生するだけです。

少し良いオプションは、ツリーのどのノードが展開されているかを記録するために Cookie と Javascript を使用することです。ツリーの状態を表す Javascript オブジェクトを更新する各ノード エキスパンダ/コントラクタにクリック ハンドラをバインドし、クリック イベントごとにそのオブジェクトを文字列にフラット化し、document.cookie を介して保存することができます。こうすることで、ツリーの状態を次のページの読み込みまで維持できます。オンロード ハンドラーは、Cookie にリストされているノードを展開して、ページの再読み込みリンクがクリックされたときの状態にツリーを戻すことができます。

ネイティブ JSON サポートを備えたブラウザまたは同等のライブラリがロードされた jQuery が存在し、ノード エキスパンダ/コントラクタ コントロールがクラス "node-control" を持つ <a> タグとして実装され、コントロールが展開されたノードには「展開された」クラスがあり (おそらく既存のクリック ハンドラーによって与えられます)、それぞれがツリー内での位置を一意に識別する id 属性を持っています。

 // begin "persistent-node-state.js"

 window.nodesExpanded = {};

 // do the following on document load completion: 
 jQuery(document).ready(function() {
   // check for a nodesExpanded value in the cookie
   var cookieMatch = document.cookie.match(/nodesExpanded=(.*?)\;/);
   if (cookieMatch) { // no nodesExpanded cookie found -- do nothing
     // we found a nodesExpanded cookie; let's unserialize its value into
     // window.nodesExpanded
     window.nodesExpanded = JSON.parse(cookieMatch[1]);
   };

   // iterate through the nodesExpanded object's keys, which are IDs of controls whose
   // nodes we want to expand (if we didn't find a cookie, then window.nodesExpanded 
   // is an empty object, making this loop a very complicated no-op)
   for (node_id in nodesExpanded) {
     // call the pre-existing click handler to expand the node
     jQuery('a.node_control#' + node_id).click();
   };

   // now that that's done, give each node control an additional click handler which 
   // puts its state into window.nodesExpanded and updates the cookie
   jQuery('a.node-control').click(function(i,el) {
     var node_id = jQuery(el).attr('id');

     // if this control's node is expanded...
     if (jQuery(el).hasClass('expanded')) {
       // ...then add the control's id as a key in window.nodesExpanded...
       window.nodesExpanded[node_id] = true;
     }
     else {
       // ...otherwise remove any existing key in window.nodesExpanded with this 
       // node's ID
       window.nodesExpanded[node_id] = undefined;
     };

     // store the updated state in the cookie so it'll persist across page loads
     document.cookie('nodesExpanded=' + JSON.stringify(window.nodesExpanded));
   });
 });

 // end "persistent-node-state.js"

もちろん、これらはすべて jQuery なしで実行できますが、そのライブラリをロードするのにそれほど費用はかかりません。ダウンロードする必要さえありませんが、Google の CDN からロードすることができます。 Javascript を使用すると非常に簡単なので、非常に古い (たとえば IE6 より前の) ブラウザー、またはそのような一般的な性質のものをサポートする必要がない限り、Javascript を使用しない正当な理由はありません。

同様に、さまざまな手がかり (つまり、ノードの展開/収縮コントロールを識別する方法、展開されているかどうかを判断する方法、ノードを展開または収縮させるイベントを発生させる方法など) はすべて、必要に応じて変更できます。サイト リンクやいくつかのサンプル コードがないと、状況に合わせて例を調整するのは難しいので、基本的なアイデアを示しながら、できるだけ一般的なものを選びました。 .

于 2012-10-08T23:13:29.290 に答える
0

サーバー側のインクルードは、まさにサーバー側です。複数のページに同じインクルード ファイルがある場合は、そのたびにインクルードされます。Apache (または IIS) がそれを確認します。一方、単一の「ページ」を作成するときに同じファイルが複数のインクルード ファイルに含まれている場合は、インクルード ファイルに変数を設定し、ファイルが含まれる各場所でそれをテストできます。サイトのグローバル変数を設定する構成ファイルを使用してそれを行います。

于 2016-09-23T22:39:53.857 に答える