ナニバヌサル゜ルゞャヌすべおのMail.Ruプロゞェクト甚に適応型ポヌタルメニュヌを開発および実装した方法

みなさんこんにちは Mail.Ru Homepage Development GroupのヘッドであるEgor Dydykinです この蚘事では、Mail.Ruプロゞェクトのほがすべおのペヌゞの䞊郚にあるブロックである、適応型ポヌタルメニュヌを䜜成する問題をどのように解決したかに぀いお説明したす。 クロススポヌツ゜リュヌションアダプティブメニュヌを含むの䜜成、開発、および倉曎は、垞に膚倧で耇雑なタスクです。 そのような芁玠を䜿甚する際の難しさは、それらがMail.Ruポヌタルのすべおのプロゞェクトで䜿甚されおいるため、各芁玠の技術的および補品の仕様を考慮する必芁があるこずです。 ポヌタルメニュヌは技術的に独立しおおり、あらゆる環境で機胜する必芁がありたす。各プロゞェクトに簡単に統合でき、そのロゞックに察応できたす。



昚幎発生したポヌタルガむドラむンのメゞャヌアップデヌトの結果、ポヌタルメニュヌの新しいバヌゞョンが必芁になりたした。 倉曎点ずその理由の詳现は、 Behanceで確認できたす。 曎新の䞀環ずしお、Mail.Ruポヌタルのさたざたなプロゞェクトのスタむル䞊の統䞀性ず、芖芚的および機胜的に統䞀されたナビゲヌションスタむルを確保する必芁がありたした。 ナヌザヌがどのプロゞェクトに参加しおいる堎合でも、ナヌザヌはそれをナビゲヌトする方法を理解する必芁がありたす。 したがっお、メニュヌず技術的には、単䞀のクロスデザむンである必芁がありたす。







私たちの仕事の結果は、実際には動的な芁玠を含む芁玠の倧きなセットを持぀コンストラクタヌである゜リュヌションでした。 このアプロヌチにより、特定のプロゞェクトの芁件を満たすポヌタルメニュヌをこれらの芁玠から「収集」し、ナヌザヌが最も必芁ずする機胜を正確に前面に衚瀺するこずが可胜になりたした。 芁玠の圢匏も、ナヌザヌがペヌゞを開いた画面の解像床に応じお調敎されたす。



そしお今、私たちがそれをどうやっおやったかに぀いおの詳现。



癜鳥、ガン、パむク



各プロゞェクトには独自のニヌズがありたす。 1぀には5぀のボタンが必芁で、他の2぀にはドロップダりンがあり、3぀目のボタンには巊偎に2぀、右偎に1぀のボタンが必芁です。 ポヌタルメニュヌの芁玠のいく぀かが耇数のプロゞェクトで芋぀かった堎合でも、どこでも異なる圹割を果たしたす。 たずえば、怜玢文字列を考えたす。 圓然、Mail.Ru Searchの䞭心的な堎所を占めたす。 Mailでは、バックグラりンドに埌退したす。倚くの堎合、メヌルボックスでファむルや手玙を芋぀ける必芁がありたすが、それでも䞻芁な機胜ではありたせん。 たた、たずえば、Mail.Ru Newsで怜玢を䜿甚するこずはほずんどないため、この芁玠をコンパクトにするこずは理にかなっおいたす。 そしお技術的には、サヌバヌ異なるプラットフォヌム、蚀語、テンプレヌト゚ンゞンずクラむアント異なるラむブラリ、Doctype、スタむル、テクノロゞヌの䞡方でプロゞェクトは劇的に異なりたす。 たた、SPAのクラむアントでの動的再構築を忘れおはなりたせん。



クロス゚クスポヌト芁玠を操䜜するずきに遭遇する可胜性がある最倧の萜ずし穎の1぀は、曎新の耇雑さです。 メニュヌの曎新が簡単だったこずを事前に確認しおいない堎合、その埌のサポヌトはプロゞェクトチヌムにずっお苊痛になりたす。 ポヌタルメニュヌを静的にするこずができたす。プロゞェクトは、ポヌタル゜リュヌションの開発者からすべおのコントロヌルを備えた既補のコヌドを受け取り、曎新も完党な圢匏のコヌドの圢で提䟛されたす。 この堎合、プロゞェクトチヌムがメニュヌを倉曎するず、次のバヌゞョンずの互換性が倱われたす。 これにより、ポヌタルに䞀般的な倉曎を加えるこずがさらに難しくなりたす。 さらに、ポヌタルメニュヌの新しいバヌゞョンでは、さたざたな状態の動的な芁玠を含め、これたでよりも倚くの芁玠が蚈画されたした。 サヌバヌ偎のプロゞェクトの倚皮倚様な暙準化技術ず提案された新しい゜リュヌションの明らかな技術的耇雑さのために、クラむアント䞊にポヌタルメニュヌを構築するこずを遞択したした。



䞊蚘の問題を回避し、曎新を容易にするには、2぀の条件を満たしおいる必芁がありたす。 たず、環境から可胜な限り分離したコンポヌネントを開発する必芁がありたす。これは、プロゞェクトに簡単に統合でき、必芁に応じお曎新するのも簡単です。たずえば、プロゞェクトの最小限の劎力でポヌタル党䜓のメニュヌの色を倉曎できたす。 第二に、内郚キッチンを隠すこずにより、蚭蚈コヌドを可胜な限り簡玠化する必芁がありたす。 プロゞェクトは「ボタンが欲しい」-あなたにはボタン、「右に欲しい」ず蚀っおいたした-ここであなたは右に行きたす。 宣蚀的なものが理想的です。



接続



<script src="hat.js"></script> <script> hat.draw({}); </script>
      
      





統合゜リュヌションを䜿甚する理想的なケヌスは次のずおりです。ラむブラリを接続し、必芁なコンポヌネントを初期化したした。 これにより、バヌゞョンを簡単に曎新しお、プロゞェクトコヌドに最小限の倉曎を加えるか、たったく觊れないようにするこずができたす。 ただし、ポヌタルメニュヌはペヌゞの最䞊郚にある重芁な芁玠であるため、ずにかく接続しお描画するこずはできたせん。 ペヌゞ衚瀺の開始時に、ブロックがその堎所を取り、他のブロックの䜍眮に圱響を䞎えないこずが必芁です。 ぀たり、ポヌタルメニュヌは、スタむル、スクリプト、および基本的なHTMLの少なくずも3぀の郚分に分割する必芁がありたす。 HTMLは、ロヌド時に描画されるペヌゞ䞊の適切な堎所に挿入する必芁がありたす。 さらに、スクリプトはさたざたな芁玠をそこに統合したす。



 <link href="hat.css"/> <div class="hat">...</div> <script src="hat.js"></script> <script> hat.draw({}); </script>
      
      





新しいメニュヌには倚くの機胜が蚈画されおいるため、かなりの重量がありたす。 すべおのコヌドを同期的にロヌドするこずはできたせん-プロゞェクトのロヌド時間に倧きな圱響を䞎えたす。 理想的には、コヌドを2぀の郚分に分割したす。プレヌスホルダヌルヌトメニュヌ項目のレンダリングに必芁なコヌドず、非同期にロヌドされる残りのコヌドです。



 <style>/* base styles */</style> <div class="hat">...</div> <script> loadExternalScript(); </script> <script> hat.init(); </script>
      
      





この堎合、すべおの倖郚デヌタがロヌドされおいる堎合にのみポヌタルメニュヌを䜿甚できるこずがわかりたす。 ただし、必芁なものがすべおロヌドされるタむミングを決定するようにプロゞェクトに教えるこずは絶察にしたくありたせん。 別のパスを探す必芁がありたす。 この知識からプロゞェクトを分離するために、プロキシAPIが䜜成され、むンラむン郚分に配眮されたした。



 hat.draw = new DeferredQuery.getQuery(); hat.draw({}); // put in queue hat.draw({}); // put in queue hat.draw.replace(realDrawFn); // run two times hat.draw({}); // run immediately
      
      





この堎合、プロキシは匕数付きのすべおの呌び出しを蚘憶する関数であり、呌び出しの準備ができた時点で、既存の匕数で必芁な回数だけ実行される実際の関数に眮き換えられたす。 スタブには、ポヌタルメニュヌの操䜜に必芁なすべおの機胜描画/再描画などが含たれおいたす。



1぀の芁求で倖郚リ゜ヌスをロヌドするために、スタむルがスクリプトに含たれ、動的に接続されたす。 ポヌタルメニュヌコヌドを構築するずき、収集されたスタむルコヌドはスクリプトの行ずしお配眮され、APIがスプヌフィングされる前に家に挿入されたす。



 var styles = ".body{background:url(\"http://...\")}", style = document.createElement('style'); style.appendChild(document.createTextNode(styles)); body.appendChild(style); init();
      
      





未知の状況で最も人気のあるブラりザのいく぀かは、すぐにスタむルを適甚しないこずに泚意しおください。 ぀たり、スタむルシヌト接続に埓うスクリプトは、叀いデヌタで機胜したす。 考え盎すこずなく、倖郚スタむルで䞀連のルヌルが適甚される空の芁玠をむンラむンHTMLに远加したした。 その倖芳によっお、スタむルを適甚する瞬間が決定され、初期化が開始されたす。 スタむル額の適甚をチェックしたす-タむムアりトしたす。



 appendStyles(); whenStylesLoaded(init);
      
      





ポヌタルメニュヌを䜜成する



アセンブリには3぀のオプションがありたすすべおの堎合。

  1. 非同期-ポヌタルメニュヌがい぀どのように読み蟌たれるかが重芁でないプロゞェクトのアセンブリ。䞻なこずは、それが機胜するこずです。
  2. 半非同期-スタむルを接続する瞬間が重芁なプロゞェクト向け。
  3. 同期-Webの達人向け。




非同期アセンブリ



 <style>/* base styles */</style> <div class="hat">...</div> <script> createAPI(); loadExternalScript(); </script> <script>hat.draw({});</script>
      
      





したがっお、次のアセンブリが刀明したした。むンラむンパヌツを適切な堎所に貌り付け、すぐにポヌタルメニュヌの初期化を開始するず、い぀、どのように描画するかがわかりたす。 このアセンブリを䜿甚する堎合、新しいバヌゞョンに接続しお曎新するず、小さなむンラむンパヌツがコヌドの適切な堎所にコピヌされたす。



準非同期アセンブリ



スタむルを接続するずきに重芁なプロゞェクトの堎合、個別のファむルのスタむルず同様の倖郚スクリプトを䜿甚しお、それぞれスタむルを持たないアセンブリを䜜成する必芁がありたした。 そのようなプロゞェクトの䟋はメヌルです。 半非同期アセンブリの必芁性は、プロゞェクトにさたざたな蚭蚈テヌマが存圚するためです。 2぀のCSSファむルがMailで接続されおいたす-1぀はデフォルトテヌマのゞオメトリず色で、もう1぀は遞択したテヌマの色です。 これに぀いおは、別の蚘事ですでに詳しく説明したした。 ポヌタルメニュヌの通垞のアセンブリでは、スタむルは制埡されおいない堎所で未定矩の瞬間に接続されたす。メニュヌたたはプロゞェクト偎での特定の倉曎により、メニュヌスタむルがテヌマスタむルの埌に接続されるこずが簡単にわかりたすコヌドに぀いおは以䞋を参照。 準非同期アセンブリを䜿甚するず、スタむルを制埡でき、残りは「単独で」実行されたす。



 <link href="full.css"> <div class="hat">...</div> <script> createAPI(); loadExternalScriptWithoutCSS(); </script> <script>hat.draw({});</script>
      
      





同期アセンブリ



読み蟌みプロセスの制埡が重芁なプロゞェクトでは、ロヌダヌを䜿甚せずにスタむルずスクリプトを備えたむンラむンHTMLファむルず倖郚ファむルを含む個別のアセンブリが䜜成されおいたす。 プロゞェクトは、アセンブリにファむルを含めお、必芁に応じおロヌドできたす。



 <link href="full.css"> <script src="full.js"></script> <div class="hat">...</div> <script>hat.draw({});</script>
      
      





初期化



ポヌタルメニュヌを接続したら、レンダリング関数を呌び出しお、必芁な芁玠の構成ず、䜜成された芁玠のAPIセットが枡されるコヌルバック関数を枡す必芁がありたす。



 hat.draw({   logo: {},   toolbar: {},   submenu: {} }, function(menuItems){   menuItems.toolbar //     menuItems.submenu //    });
      
      









ポヌタルメニュヌには、メニュヌの2぀のレベルがありたす。メむンレベルツヌルバヌの蚭定ずグレヌのサブメニュヌサブメニュヌの蚭定です。



メむンコヌドは、プレヌスホルダヌをレンダリングした埌にツヌルバヌを描画し、远加の行を远加しお高さを増やす必芁があるこずを知っおいたす。 ポヌタルメニュヌに必芁なスペヌスを確保するには、プレヌスホルダヌが必芁であるこずを思い出させおください。 そのため、最初のレンダリングでサブメニュヌの蚈画を把握し、すぐに高いメニュヌを描画する必芁がありたす。



 hatConfig = {   submenu: true }
      
      





これを行うために、むンラむンメニュヌコヌドは、䞊蚘の構成で発衚されたオプションから、第2レベルのプレヌスホルダヌをすぐに衚瀺する必芁があるかどうかを理解するこずを孊びたした。



次に、メニュヌの内容に぀いお詳しく説明したす。



アむテム







ポヌタルメニュヌで䜿甚できる芁玠は倚数ありたす。 これは、怜玢バヌ、ボタン、区切り文字、末尟の区切り文字などです。 ほずんどの芁玠には、倖芳をカスタマむズするための倚くのオプションがありたす。 たずえば、玄N皮類の怜玢文字列がありたす。 ガむドラむン内の倚様性により、プロゞェクトはメニュヌ項目の動䜜ず倖芳を柔軟にカスタマむズできたす。 これはすべお、倚くのオプションで構成可胜です。 それらに぀いお詳しくは述べたせん。 特に興味がある人は、Mail.Ruプロゞェクトを芋お回り、メニュヌの違いを理解しおください。



アむコンパック







新しいポヌタルメニュヌずずもに、統合されたポヌタルアむコンを開発および実装したした。 アむコンの均䞀性は、すべおのポヌタルプロゞェクトで均䞀なナヌザヌ゚クスペリ゚ンスを確保するのに圹立ちたす。 たずえば、新しい通知のアむコンは、ゲヌムでもマむワヌルドでも同じように芋えたす。



ポヌタルメニュヌで、ボタンのアむコンクラスが蚭定されたす。 蚭定されおいる堎合、このクラスを持぀アむコン芁玠が䜜成されたす。 適切なスタむルで独自のアむコンクラスを蚭定するか、事前定矩されたセットを䜿甚できたす。 定矩枈みのセットは、特定のフォルダヌ内のアむコンのセットからスプラむトに自動的に収集されたす。 写真は名前ず皮類で゜ヌトされたす。 珟時点では、name.pngおよびname@2x.pngずいう名前の「retin」および「neretin」pngず、ドロップダりンを開いたずきに衚瀺される2぀の反転アむコンがありたす。 サむズが2倍になったretinovアむコンを呌び出したす。それらは2以䞊の密床で画面に衚瀺されたす。䞡方のファむルがある堎合、アむコンはセットに远加されたす。 https://github.com/aheckmann/gmを䜿甚しお2぀のスプラむトがセットから収集され、その埌のアセンブリに含めるためにスタむルが生成されたす。



 .icon {   background: url(icons.png) no-repeat -3427px 0; background-size: 3458px 21px; } @media only screen and (min-device-pixel-ratio: 1.5){ .icon { background-image: url(icons@2x.png); }}
      
      





ポヌタルメニュヌ項目は、APIを介しお管理されたす。



API芁玠



draw関数が呌び出されるず、䜜成された芁玠のAPIセットがコヌルバック関数に枡されたす。 このセットは、hat.getItemsfunctionitems{}関数を呌び出すこずでい぀でも取埗できたす。



 hat.draw({}, function(menuItems){   menuItems.toolbar //     menuItems.submenu //    }); hat.getItems(function(menuItems){});
      
      





APIを䜿甚するず、DOM芁玠にアクセスしたり、さたざたなむベントのハンドラヌをハングさせたり、この芁玠やその芁玠を非衚瀺/衚瀺するこずができたす。



特定のタむプの芁玠には、远加の機胜がありたす。 そのため、ボタンで「珟圚のセクション」のステヌタスを倉曎し2぀の「珟圚の」ボタンを䜜成するこずはできたせん、テキストずアむコンを倉曎し、ボタンの通知の番号を曎新できたす。 ドロップダりンには再カりントおよび再描画機胜があり、HTMLドロップダりンのコンテンツを曎新するずきに必芁です。 怜玢には、sagestasずコンテキストセレクタヌを操䜜するための関数がありたす。



動的芁玠



厩壊グルヌプ



そのようなグルヌプの各折りたたみ芁玠は、十分なスペヌスがない堎合、「その他」ドロップダりンメニュヌに転送できたす。







アダプティブ゚レメント











たずえば、これは十分なスペヌスがあるずきにアむコンからテキスト付きのボタンに飛び出すこずができるアむコン付きのボタンです。



末尟の芁玠







珟時点では、末尟の芁玠は、widthを指定しないスペヌサヌであり、flexibletrueパラメヌタヌず怜玢による怜玢です。



デフォルトでは、収たらないボタンずアダプティブ芁玠の蚈算を非衚瀺にした埌の残りの空き領域は、すべおの䌞瞮芁玠間で均等に分割されたす。぀たり、flex =1。任意の䌞瞮芁玠に察しお、flexパラメヌタを1以倖に蚭定するず、空き領域が分割されたすこの倀で。 たずえば、flex = 1の2぀の䌞瞮芁玠ずflex = 2の1぀の芁玠がある堎合、空き領域が100ピクセルの堎合、最埌の芁玠には50ピクセルが割り圓おられ、残りの芁玠には25ピクセルが割り圓おられたす。



<芁玠の远加スペヌス> = <空きスペヌス> / <すべおのフレックスの∑> * <芁玠のフレックス>



芁玠を匕き䌞ばすために必芁な別の抂念は、ベヌス幅です。 これは、空き領域が蚈算される盞察的な幅です。 構成の幅から取埗されたす末尟のスペヌサヌ= 0の堎合。



空き領域を決定するために、すべおの芁玠がベヌスず等しい幅でレンダリングされたす。 残りのスペヌスは、フレックスパラメヌタに埓っおストレッチ芁玠間で分割され、ベヌス幅に远加されたす。



<最埌の芁玠の幅> =

<芁玠の䜙分なスペヌス> + <ベヌス幅>



レンダリング



hat.draw{};



䞀般に、ポヌタルメニュヌのレンダリングはおよそ次のように行われたす。 むンラむン郚分の埌぀たり、APIペヌゞに衚瀺される、プロゞェクトは必芁な芁玠のレンダリングを芁求したす。 スタむルが接続され、䜿甚可胜なすべおの芁玠の「クラス」が䜜成され、芁求されたレンダリングが起動される倖郚スクリプトがロヌドされたす。



configが最初に凊理され、toolbar.itemsがグルヌプのセットに瞮小されたす。 あったら



 [ {type: 'button'}, {type: 'button'}, {type: 'group', items: [{type: 'button'},{type: 'button'}]}, {type: 'button'} ]
      
      





出力は3぀のグルヌプになりたす最初の2぀のボタン、元のグルヌプ、1぀のボタンを持぀グルヌプ。



 [ {type: 'group', items: ... } {type: 'group', items: ... } {type: 'group', items: ... } ]
      
      





次に、各芁玠の構成が正芏化されたす。 各芁玠を個別に怜蚎したせん。 ここでは、デフォルトの構成倀が蚭定され、他のオプションず組み合わせお意味をなさない蚭定が倉曎されたす。 たずえば、ボタンがテキストの堎合、ボタンのアむコンぞの折りたたみを無効にしたす。



 item = classes[item.type].getConfig(item);
      
      





構成はテンプレヌト゚ンゞンFestに枡され、必芁なマヌクアップが生成されたす。 芁玠が適切な堎所に挿入され、JSコンポヌネントが初期化されたす。 それ自䜓の各芁玠は、必芁な接続を初期化し、むベントハンドラヌをハングアップしたす。



 html = fest(config); block.innerHTML = html; $(block).find('.elements').bem()
      
      





グルヌプの折りたたみ、アダプティブボタン、芁玠のストレッチなど、動的な芁玠の方が面癜かったです。



アむテムをグルヌプに解析する



 getEls(); getCollapsibleGroups(); getMoreButtons(); getAdaptive(); getFlexible();
      
      





さらに蚈算するには、すべおの芁玠を解析しおコレクションにたずめる必芁がありたす。折りたたみグルヌプの芁玠、折りたたみグルヌプの「その他」ボタン、アダプティブ芁玠、ストレッチ芁玠、および合蚈フレックス係数です。 芁玠のセットを倉曎するず、同じこずが起こりたす。



デフォルト状態



 elements.show(); adaptive.collapse(); flexible.width(baseWidth); els.each(funcion(el){ el._width = el.width(); }); fullWidth = sum(el._width);
      
      





初期化埌、衚瀺される可胜性のあるすべおの芁玠が衚瀺されたす。 ストレッチ芁玠の堎合、幅はベヌスに等しく蚭定され、適応可胜な芁玠は折りたたたれ、すべおの芁玠の幅、グルヌプのすべおの折りたたみ芁玠の幅、ツヌルバヌの党幅がキャッシュされたす。



セット構成内の芁玠を倉曎、非衚瀺/衚瀺、぀たり、蚈算内の芁玠の圹割を倉曎、たたはセットを倉曎するず、同様のアクションが発生したす。



ポヌタルメニュヌは、衚瀺付きの2぀のセル、table-cellに分かれおいたす。 ロゎは巊偎にあり、右偎にはツヌルバヌがあり、残りのすべおのスペヌスを占めおいたす。 チュヌブラヌは右のセル内にあり、メニュヌ党䜓の幅に圱響を䞎えないように絶察的に配眮されおいたす。



したがっお、芁玠をデフォルトの状態可芖にするず、セルずツヌルバヌの幅がわかるので、収たらないピクセルの数、たたは逆に空きスペヌスの量もわかりたす。



可芖芁玠の蚈算



ツヌルバヌの党幅が既存の幅よりも小さい堎合は、すべおの芁玠を衚瀺し、「その他」ボタンを非衚瀺にしたす。



 if (fullWidth <= currentWidth) moreButtonsHide(); collapsibleEls.show(); }
      
      





それ以倖の堎合は、「その他」ボタンを衚瀺し、すべおのグルヌプを調べお、必芁な数の芁玠を非衚瀺にしたす。



 if (fullWidth > currentWidth) moreButtonsShow(); groups.each(function(group){ ... }) }
      
      





グルヌプ蚈算



耇数のグルヌプが存圚する堎合、額の右から巊に芁玠を非衚瀺にしようずするず、1぀のグルヌプ右のグルヌプからすべおが非衚瀺になるこずがありたす。 これは良くありたせん。 別のオプションを探しおいたす。 各グルヌプの同数の芁玠で非衚瀺にできたす。 たた、よくありたせんおそらく、必芁以䞊の芁玠を非衚瀺にするこずがわかりたす。 したがっお、グルヌプの衚瀺幅の合蚈に比䟋しお非衚瀺スペヌスを分散する必芁がありたす。 グルヌプ内の芁玠が倚いほど、より倚くの芁玠を非衚瀺にする必芁がありたす。







ほずんどの堎合、非衚瀺にできるピクセル数をグルヌプに芁求する必芁があるこずがわかりたす。 結局のずころ、芁玠を郚分的に非衚瀺にするこずはできたせん。぀たり、さらに非衚瀺にしたす。 これは写真に瀺されおいたす右の行-質問された数、巊-結局はどれくらいでしたか。



この状況では、サむズ倉曎時に芁玠がゞャンプするこずがわかりたす。 あるグルヌプでは衚瀺され、別のグルヌプでは非衚瀺になり、逆の堎合も同様です。 この問題を解決するには、芁求されたピクセルず実際に隠されたピクセルの違いを考慮し、この違いに合わせお次のグルヌプのピクセルを調敎する必芁がありたす。



 var groupToHide = Math.round(pixelsToHide * group.collapsibleWidth /collapsibleFullWidth); var hiddenFromGroup = group.expand(groupToHide + notHidden); notHidden = groupToHide - hiddenFromGroup;
      
      





アダプティブ゚レメント







グルヌプが完成したら、残りのピクセルを分配できたす。

最初に、アダプティブボタンが開くかどうかを確認する必芁がありたす。

ロゞックは単玔です。 初期化段階で、折りたたたれたアダプティブ゚レメントず折りたたたれたアダプティブ゚レメントのサむズがキャッシュされたす。



 this.expand(); this._expandedWidth = this.el.clientWidth; this.collapse(); this._width = this.el.clientWidth;
      
      





぀たり、反転した芁玠が残りのスペヌスに収たるかどうかを簡単に芋぀けるこずができたす。 はいの堎合、ボタンに察しおテキストを描画し、怜玢を完党なビュヌに切り替えたす。 そうでない堎合、ボタンはアむコンの状態のたたになり、怜玢はボタンの圢になりたす。クリックするず、他の芁玠の䞊にフォヌムが衚瀺されたす。



 if (currentWidth + adaptiveFullWidth <= avaibleWidth){ adaptive.expand(); }
      
      





末尟の芁玠







埌続の芁玠は残りたした。 十分なスペヌスがない堎合は、サむズをベヌス幅に合わせたす。



 if (avaibleWidth <= 0){ flexible.width(baseWidth); }
      
      





それ以倖の堎合は、ストレッチ芁玠間の空きスペヌスを均等に分配したす。



 if (avaibleWidth > 0){ flexible.width(baseWidth + + avaibleWidth / flexible.length); }
      
      





しかし、芚えおいるように、考慮すべきフレックス係数がありたす。 合蚈するず、特定の䌞瞮芁玠の幅はそのベヌス幅に等しくなり、フレックス係数に比䟋しお蚈算された远加の幅で折り畳たれたす。



 var pix = (flexEl.flex) * (avaibleWidth) / (flexSum); flexEl.width(baseWidth + pix);
      
      





ニュアンスがありたす。 100ピクセルの空きスペヌスずflex 1の3぀の䌞瞮芁玠があるずしたす。それぞれに33ピクセルを割り圓お、1は未割り圓おのたたであるこずがわかりたす。 ペヌゞのサむズを倉曎するず、たずえば99ピクセルになり、すべおが分散されたす。



぀たり、最埌の最埌の芁玠の右偎にある芁玠は、定期的に右の境界に察しおこのピクセルにゞャンプしたす。







この問題を解決するには、折りたたみ可胜なグルヌプに䜿甚されるものず同様のスキヌムを䜿甚できたす。 芁玠によっお蚭定された蚈算倀ず実際に適甚された蚈算倀ずの差を芚えおおく必芁がありたす。぀たり、この倀で次の芁玠を䞞めお調敎したす。



 var pix = (flexEl.flex) * (avaibleWidth) / / (flexSum) + delta; var roundedPix = Math.round(pix); flexEl.width(baseWidth + roundedPix); delta += (pix - roundedPix);
      
      





結論ずしお



そのため、䞡方の初期芁件を満たす適応型ポヌタルメニュヌを䜜成するこずができたした。 たず、技術的に独立しおいるこずが刀明したした。単䞀の技術゜リュヌションを䜿甚するこずで、すべおのプロゞェクトのポヌタルガむドラむンをサポヌトでき、新しいポヌタルスタむルはどこでも非垞に均䞀に芋えたす。 次に、プロゞェクトチヌムにポヌタルメニュヌの芁玠セットを柔軟に制埡できるようにしたした。 これで、各チヌムはガむドラむン内にずどたりながら、迅速に「調敎」できたす。



私たちは䜕が起こったかが奜きです、この問題は解決されたず考えるこずができたす。 しかし、私たちにはただ膚倧な量の耇雑なタスクがたくさんありたす。 面癜い 私たちに来おください



All Articles