xmlplus は、フロントエンドおよびバックエンド プロジェクトを迅速に開発するための JavaScript フレームワークです。この記事では主に xmlplus レイアウト コンポーネントのパーティション ボックスを紹介します。興味のある方は参考にしてみてください
パーティション ボックス (pidedBox) は 2 つのカテゴリに分類できるレイアウト コンポーネントです。 1 つは水平分離ボックス (HpidedBox) と呼ばれ、もう 1 つは垂直分離ボックス (VpidedBox) と呼ばれます。水平分割ボックスは子を 2 列に分割し、垂直分割ボックスは子を 2 行に分割します。通常、列と行の間には区切りバーがあり、これをドラッグして子コンポーネントのサイズを変更できます。以下では、そのようなコンポーネントがどのように設計および実装されるかを紹介する例として垂直分離ボックスのみを使用します。
完成したコンポーネントのユースケース
過去の設計経験に基づいて、最初に想像上の完成したコンポーネントのユースケースを書き留めることができ、それはその後の設計と実装に役立ちます。垂直分離ボックスはレイアウト クラスのコンポーネントであるため、上で説明した 3 つのサブレベル コンポーネントを含むコンテナでもある必要があります。使いやすさを考慮して、分離ボックスをコンポーネントの内部に実装する必要はありません。分析後、次のアプリケーション例が得られます:
Example1: { css: "#example p { width: 80%; height: 80%; background: #AAA; }", xml: `<VpidedBox id="example"> <p id='top'/> <p id='bottom'/> </VpidedBox>` }
この例は、2 つの p 要素をラップする垂直分割ボックス コンポーネントで構成されます。ここでは、2 つの p 要素の幅と高さが親の 80% に設定され、背景色がグレーに設定されています。これはテストの便宜のためです。さらに、サブフレームの初期比率の割り当ても考慮する必要があります。デフォルトの比率を 50:50 に設定できますが、比率設定用の動的なインターフェイスを提供しながら、コンポーネントのインスタンス化時に比率を静的に指定するのが最善です。したがって、次のような改良されたユースケースがあります。
Example2: { css: "#example p { width: 80%; height: 80%; background: #AAA; }", xml: `<VpidedBox id="example" percent='30'> <p id='top'/> <p id='bottom'/> </VpidedBox>`, fun: function (sys, items, opts) { sys.top.on("click", e => sys.example.percent = 50); } }
この使用例では、垂直分離ボックスが初期化されるときに、サブボックスの初期比率分布が 30:70 に設定され、ユーザーが最初のサブボックスをクリックすると、比率分布が 50:50 に復元されます。ただし、この比率は仕切りバーのスペースを除いた残りのスペースの比率を指します。
設計と実装
次に、コンポーネントの内部に注目してみましょう。まずはコンポーネントの基本構成を大まかに決めましょう。直観的には、垂直分割フレーム表示には、上部サブフレーム部分、分割バー、および下部サブフレーム部分の 3 つのコンポーネント部分が含まれています。したがって、次のビュー項目部分を一時的に取得できます:
VpidedBox: { xml: `<p id='hbox'> <p id='top'/> <p id='handle'/> <p id='bottom'/> </p>` }
次に、垂直分割ボックス コンポーネント インスタンスの子部分が、上部のサブボックスの上部と下部のサブボックスの底部に正しくマッピングされていることを確認します。方法としては、まずすべての子要素オブジェクトを上部のサブボックス上部に追加し、次に下部の子要素を機能項目内の下部のサブボックス下部に追加します。
VpidedBox: { xml: `<p id='hbox'> <p id='top'/> <p id='handle'/> <p id='bottom'/> </p>`, map: {appendTo: "top" }, fun: function (sys, items, opts) { sys.bottom.elem().appendChild(this.last().elem()); } }
次に、最上位の p 要素の配置方法を相対配置に設定します。 3 つの子要素は絶対配置に設定されます。また、ディバイダーの高さを 5px に設定します。
VpidedBox: { css: `#hbox { position:relative; width:100%; height:100%; box-sizing: border-box; } #top { top: 0; height: 30%; } #bottom { bottom: 0; height: calc(70% - 5px); } #top,#bottom { left: 0; right: 0; position: absolute; } #handle { height: 5px; width: 100%; position:absolute; left:0; top: 30%; z-index:11; cursor:row-resize; }`, xml: `<p id='hbox'> <p id='top'/> <p id='handle'/> <p id='bottom'/> </p>`, map: {appendTo: "top" }, fun: function (sys, items, opts) { sys.bottom.elem().appendChild(this.last().elem()); } }
最後に、分割バーのドラッグイベントに応答してサブボックスの割り当て比率を変更する方法を見てみましょう。サブボックスの比率を変更し、区切りバーのドラッグ イベントをリッスンする関数を定義する必要があります。以下は実装の 1 つです。
VpidedBox: { // 视图项同上 map: { format: {"int": "percent"}, appendTo: "top" }, fun: function (sys, items, opts) { var percent = 50; sys.handle.on("dragstart", function (e) { sys.hbox.on("dragover", dragover); }); sys.hbox.on("dragend", function (e) { e.stopPropagation(); sys.hbox.off("dragover", dragover); }); function dragover(e) { e.preventDefault(); setPercent((e.pageY - sys.hbox.offset().top) / sys.hbox.height() * 100); } function setPercent(value) { sys.handle.css("top", value + "%"); sys.top.css("height", value + "%"); sys.bottom.css("height", "calc(" + (100 - value) + "% - 5px)"); } setPercent(opts.percent || percent); sys.bottom.elem().appendChild(this.last().elem()); return Object.defineProperty({}, "percent", {get: () => {return percent}, set: setPercent}); } }
上記のコードのマッピング項目にはパーセント形式の設定があり、パーセントが整数であることが保証されます。また、機能項目内のサブボックスの割合の設定にはcss3のcalc計算機能を使用していますので、ブラウザフォームのサイズが変わっても変更後の機能が動作します。より多くのブラウザと互換性を持たせたい場合は、さらに作業を行う必要があります。また、コンポーネントの良好なパフォーマンスを確保するために、dragover イベントはユーザーがドラッグを開始したときにのみリッスンされることにも注意してください。
さらなる改善
ここで簡単なテストを行って、子として 2 つのテキスト フィールドを含む垂直区切りボックスのアプリケーション例を作成してみましょう。区切りバーをドラッグして、何が起こるか見てみましょう。
Example3: { css: `#example textarea { width: 80%; height: 80%; }`, xml: `<VpidedBox id="example"> <textarea id='top'/> <textarea id='bottom'/> </VpidedBox>` }
この例では、分割バーが誤動作することがあり、分割バーの位置によってサブボックスの比率が変化しなくなります。問題は、テキストフィールドがドラッグイベントをハイジャックし、コンポーネントが応答イベントを受け取らないことです。いくつかのパッチを作成する必要があります。
VpidedBox: { css: "#hbox { position:relative; width:100%; height:100%; box-sizing: border-box; }\ #top { top: 0; height: 30%; } #bottom { bottom: 0; height: calc(70% - 5px); }\ #top,#bottom { left: 0; right: 0; position: absolute; }\ #handle { height: 5px; width: 100%; position:absolute; left:0; top: 30%; z-index:11; cursor:row-resize; }\ #mask { width: 100%; height: 100%; position: absolute; display: none; z-index: 10; }", xml: "<p id='hbox'>\ <p id='top'/>\ <p id='handle' draggable='true'/>\ <p id='bottom'/>\ <p id='mask'/>\ </p>", map: { format: {"int": "percent"}, appendTo: "top" }, fun: function (sys, items, opts) { var percent = 50; sys.handle.on("dragstart", function (e) { sys.mask.show(); sys.hbox.on("dragover", dragover); }); sys.hbox.on("dragend", function (e) { sys.mask.hide(); e.stopPropagation(); sys.hbox.off("dragover", dragover); }); function dragover(e) { e.preventDefault(); setPercent((e.pageY - sys.hbox.offset().top) / sys.hbox.height() * 100); } function setPercent(value) { sys.handle.css("top", value + "%"); sys.top.css("height", value + "%"); sys.bottom.css("height", "calc(" + (100 - value) + "% - 5px)"); } setPercent(opts.percent || percent); sys.bottom.elem().appendChild(this.last().elem()); return Object.defineProperty({}, "percent", {get: () => {return percent}, set: setPercent}); } }
この問題を解決するために、コンポーネント内の追加の p 要素オブジェクト マスクを参照しました。この要素はデフォルトでは表示されません。ドラッグを開始するとサブボックスとセパレーターバーが覆われ、ドラッグが終了すると再び非表示になります。これにより、テキスト フィールドによるドラッグ イベントのハイジャックが回避されます。
横分割枠と併用します
上記の縦分割枠のデザイン経験があれば、横分割枠の作成は難しくないので、ここでは記載しません。ここでは主に、水平分離ボックスと垂直分離ボックスを総合的に使用する例を示します。もちろん、設計当初はこのような使い方は考えていませんでした。
Example4: { css: `#example p { width: 100%; height: 100%; }`, xml: `<HpidedBox id='example'> <VpidedBox percent='30'> <p/><p/> </VpidedBox> <VpidedBox percent='30'> <p/><p/> </VpidedBox> </HpidedBox>` }
この例は主に、分割ボックスがネストされている場合のパフォーマンスを示すために使用されます。この例には水平方向の分離ボックスが含まれており、その中に 2 つの垂直方向の分離ボックスが含まれています。このレイアウトは多くのエディターで非常に一般的であり、ここでは簡単かつ効率的に実装しました。
この一連の記事は、xmlplus フレームワークに基づいています。 xmlplus についてあまり詳しくない場合は、www.xmlplus.cn にアクセスしてください。詳細な入門ドキュメントはここから入手できます。
【関連おすすめ】
3. php.cn Dugu Jiijian (3) - JavaScriptビデオチュートリアル
以上がJavaScript フレームワーク (xmlplus) コンポーネントの紹介 (8) DividedBoxの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。