データを使用した単純なdivの垂直方向のセンタリング-

良い一日。



問題がありました :Twitterブートストラップには、クラス「col-md-6」と「col-md-6」の2つの列(div)があります。 最初の列は、YouTubeの2番目のビデオのテキストで、最初の列は2番目の列の2倍です。 ビデオを最初の列に対して垂直方向に中央揃えする必要があります。 また、サイトにはそのようなサイトがいくつかあります。 一部の場所では、2つの列の高さを等しくする必要があります。



毎回私の手を編集することは可能でしょうが、私は物事をスピードアップして、データを追加することによって私のためにルーチンを実行するスクリプトを書くことを試みることにしました。



必要な属性を示します。





次の3つのオプションを選択しました。



  1. height-列の高さを揃えます。
  2. margin-画面の中央にdivの子を配置します(最初の子のmargin-topを使用)。
  3. マージンの高さ -子を中央に配置し(最初の子のmargin-topを使用)、小さい列の下の境界線を大きい列の値まで下げます(最後の子のmargin-bottomを使用)。


必要なアクションを決定しました。 次に、条件を追加します。



  1. ユーザーの画面の幅を変更するときは、スクリプトでサイズを再カウントします(ユーザーがブラウザーの幅で遊んでいない場合は、ページが読み込まれたときに再計算が1回実行されます)
  2. ブラウザーの幅はありますが、ブラウザーウィンドウの幅をこの値より小さくすると、列は互いの下に配置されます。 ここでは、センタリングや高さの計算は必要ありません。


変数を定義しましょう:



var allowedWidthOfTheWindow = 992; //  ,        var elemsToCompare = [], // DOM    [[a,b,c],[a,b,c]] dataForCompareHeight = {}; //    (  localArrayForStaticElems) var localArrayForStaticElems = []; //       () var correctingHeights = false; //    allowedWidthOfTheWindow,     /   var userScreenWidth, userScreenHeight; //    
      
      





data-compareheight属性を使用して、すべてのdivを持つ配列を取得します



 var elemsWithOurDataset = document.querySelectorAll("div[data-compareheight]");
      
      





結果のDOM要素の配列から、同じdata-compareheight属性を持つ要素を抽出する必要があります 。 また、ペアのないアイテムも破棄します。



 //      var i = 0; while(true){ if (elemsWithOurDataset.length <= 1) break; //       2 ,      if(!dataForCompareHeight[elemsWithOurDataset[i].dataset.compareheight]) { dataForCompareHeight[elemsWithOurDataset[i].dataset.compareheight] = ""; localArrayForStaticElems.push(elemsWithOurDataset[i].dataset.compareheight);}; dataForCompareHeight[elemsWithOurDataset[i].dataset.compareheight] += i + " "; i++; if (i == elemsWithOurDataset.length) break; //     DOM  }
      
      





上記のコードの後、共通のdata-compareheightを持つ要素番号で構成される配列を持つ配列を取得します。 つまり、現時点では次のとおりです。

[[a、b、c]、[d、e]](ここで、a、b、c、d、eは要素の数であり、 さらに 、要素abcおよび要素deは同じdata-compareheightを持ちます ) 。



結果の配列を要素番号からDOM要素の配列に変換する必要があります。



 //    DOM  for (var i = 0; i < localArrayForStaticElems.length; i++){ var numberOfElems = dataForCompareHeight[localArrayForStaticElems[i]].split(" "); numberOfElems.pop(); if (numberOfElems.length < 2) continue; var localArr = []; for (var j = 0; j < numberOfElems.length; j++){ localArr.push(elemsWithOurDataset[numberOfElems[j]]); } elemsToCompare.push(localArr); }
      
      





これで、(要素番号ではなく)DOM要素を含む配列が作成されました。 定数部分( 追加要素なく 、ページがリロードされない場合 )が受信されます。 さらに、サイズとスタイルを操作します。



また、スクロールバーの幅(ある場合)を計算する価値があります。 クライアントウィンドウの表示幅が狭くなり、列の転送は予想よりも低い値で発生します。



 //        ()      function setBreakePointWidthMinusScrollWidth(){ allowedWidthOfTheWindow = allowedWidthOfTheWindow - window.innerWidth + document.body.clientWidth; }
      
      





ユーザーの画面の高さと幅を決定する関数を作成します。



 function checkUserScreenSize(){ userScreenWidth = document.documentElement.clientWidth; userScreenHeight = document.documentElement.clientHeight; }
      
      





次に、配列の最大値を見つける関数を作成します。 これは単純な並べ替えで行うことができます(ただし、通常は.sort()並べ替えが文字列として機能することを考慮する必要があります。型番号による並べ替えのための追加関数を記述します)。



 //     ,  -  //       function checkTheLargestElement(){ for (var i = 0; i < elemsToCompare.length; i++){ elemsToCompare[i].sort(compareNumericArray); } } //      numberic  function compareNumericArray(a, b) { return b.clientHeight + getComputedStyle(b).marginTop + getComputedStyle(b).marginBottom - a.clientHeight - getComputedStyle(a).marginTop - getComputedStyle(a).marginBottom; }
      
      





ユーザーのブラウザの幅が列が互いの下に並ぶ値を超えたかどうかを判断する関数を作成します。



 //          -  function checkAllowedMovingOrNot(){ if (userScreenWidth < allowedWidthOfTheWindow){ if (!correctingHeights) return; correctingHeights = false; } else{ correctingHeights = true; } }
      
      





上記の関数では、画面サイズ(または幅)に応じて、インデントの計算に使用できるtrue / falseを取得します。



2番目の属性data-compareheightdoに応じて何をするかを決定する関数を作成します。



 function checkParams(elem){ if (elem.getAttribute("data-compareheightdo")){ var a = elem.getAttribute("data-compareheightdo").toLowerCase(); if (a == "margin"){ return 1; } if (a == "height"){ return 2; } if ((a == "margin height") || (a == "height margin")){ return 3; } } return 0; }
      
      





関数が0を返す場合、 data-compareheightdo属性が指定されていないか、誤って指定されています。



サイズに移りましょう。 DIV内のすべての子の高さを計算します(子の子に入ることなく、つまりparent.children [i]に制限します)。 最初の子については、マージントップを考慮しません。 この値は、垂直方向の中央揃えに使用され、他のパラメーターに応じて自動的に設定されます。



 //       margin-top   function getTotalHeightOfChildren(parent){ var heightNow = 0; for (var i = 0; i < parent.children.length; i++){ if(i == 0){ heightNow += parent.children[i].offsetHeight + parseInt(getComputedStyle(parent.children[i]).marginBottom); continue; } if(i == (parent.children.length - 1)){ heightNow += parent.children[i].offsetHeight + parseInt(getComputedStyle(parent.children[i]).marginTop); continue; } heightNow += parent.children[i].offsetHeight + parseInt(getComputedStyle(parent.children[i]).marginTop + getComputedStyle(parent.children[i]).marginBottom); } return heightNow; }
      
      





これで、インデント関数を記述するためのすべてのヘルパー関数ができました。



 //     margin-top (,  ) //   height function makeElementsEqualHeight(){ if(correctingHeights){ //           for(var i = 0; i < elemsToCompare.length; i++){ for (var j = 1; j < elemsToCompare[i].length; j++){ if (checkParams(elemsToCompare[i][j]) == 0) continue; if(checkParams(elemsToCompare[i][j]) == 1){ elemsToCompare[i][j].children[0].style.marginTop = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j]))/2) + "px"; } if(checkParams(elemsToCompare[i][j]) == 2){ if(!elemsToCompare[i][j].querySelector("div[class='notchange']")){ //        notchange var div = document.createElement("div"); //    ,   div.classList.add("notchange"); //       DOM  elemsToCompare[i][j].appendChild(div); //       } elemsToCompare[i][j].lastChild.style.marginBottom = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j])) - 1) + "px"; } if(checkParams(elemsToCompare[i][j]) == 3){ if(!elemsToCompare[i][j].querySelector("div[class='notchange']")){ var div = document.createElement("div"); div.classList.add("notchange"); elemsToCompare[i][j].appendChild(div); } elemsToCompare[i][j].children[0].style.marginTop = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j]))/2) + "px"; elemsToCompare[i][j].lastChild.style.marginBottom = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j]))/2 - 1) + "px"; } } } } else{ //           for(var i = 0; i < elemsToCompare.length; i++){ for (var j = 1; j < elemsToCompare[i].length; j++){ if (checkParams == 0) continue; elemsToCompare[i][j].children[0].style.marginTop = ""; elemsToCompare[i][j].lastChild.style.marginBottom = ""; } } } }
      
      





子div要素を追加して、この瞬間に注意を引きます。 これは、最後の要素に簡単にアクセスできるようにすることを目的としており、この要素はメインコードを妨げることなくjavascriptを使用して簡単に編集できます。



また、最大と子の間に差があるように1pxを減算することにも注意してください。



elemsToCompare [i] [ j ]ではなく、elemsToCompare [i] [ 0 ]が使用されるコードのセクションがあります。 以前に、配列の要素をソートする関数を作成しました。 したがって、最初の値(インデックス0)は最大の次元を持ちます。



data-compareheightdo属性に応じて、値0/1/2/3があり、これに応じて、無視/上からのインデントのみ(中央揃え)/列の下端を最高値の下端に揃える/中央に揃えて下端を揃えます。



すべての関数を組み合わせた関数を作成します。



 //       function recountElems(){ checkUserScreenSize(); //     checkTheLargestElement(); //       (  data-compareheight="NAME") checkAllowedMovingOrNot(); // ,       makeElementsEqualHeight(); //  margin-top  margin-bottom   };
      
      





ページをロードするときに値を計算します。 ユーザーがブラウザウィンドウで操作しない場合、これらの値は変更されません。



 setBreakePointWidthMinusScrollWidth(); //          recountElems(); //    ,    
      
      





ユーザー画面のサイズが変更され、新しい値を考慮したときに起動するハンドラーを追加します。



 //         window.onresize = function(e){ recountElems(); }
      
      





以上で、スクリプトの開発が終了しました。準備は完了です。



全体としてのコード:



 //    var allowedWidthOfTheWindow = 992; //  ,        var elemsToCompare = [], // DOM    [[a,b,c],[a,b,c]] dataForCompareHeight = {}; //    (  localArrayForStaticElems) var localArrayForStaticElems = []; //       () var correctingHeights = false; //    allowedWidthOfTheWindow,  false var userScreenWidth, userScreenHeight; //     var elemsWithOurDataset = document.querySelectorAll("div[data-compareheight]"); //      var i = 0; while(true){ if (elemsWithOurDataset.length <= 1) break; if(!dataForCompareHeight[elemsWithOurDataset[i].dataset.compareheight]) { dataForCompareHeight[elemsWithOurDataset[i].dataset.compareheight] = ""; localArrayForStaticElems.push(elemsWithOurDataset[i].dataset.compareheight);}; dataForCompareHeight[elemsWithOurDataset[i].dataset.compareheight] += i + " "; i++; if (i == elemsWithOurDataset.length) break; } //    DOM  for (var i = 0; i < localArrayForStaticElems.length; i++){ var numberOfElems = dataForCompareHeight[localArrayForStaticElems[i]].split(" "); numberOfElems.pop(); if (numberOfElems.length < 2) continue; var localArr = []; for (var j = 0; j < numberOfElems.length; j++){ localArr.push(elemsWithOurDataset[numberOfElems[j]]); } elemsToCompare.push(localArr); } //    //       ()      function setBreakePointWidthMinusScrollWidth(){ allowedWidthOfTheWindow = allowedWidthOfTheWindow - window.innerWidth + document.body.clientWidth; } function checkUserScreenSize(){ userScreenWidth = document.documentElement.clientWidth; userScreenHeight = document.documentElement.clientHeight; } //     ,  -  //       function checkTheLargestElement(){ for (var i = 0; i < elemsToCompare.length; i++){ elemsToCompare[i].sort(compareNumericArray); } } //      numberic  function compareNumericArray(a, b) { return b.clientHeight + getComputedStyle(b).marginTop + getComputedStyle(b).marginBottom - a.clientHeight - getComputedStyle(a).marginTop - getComputedStyle(a).marginBottom; } //       margin-top   function getTotalHeightOfChildren(parent){ var heightNow = 0; for (var i = 0; i < parent.children.length; i++){ if(i == 0){ heightNow += parent.children[i].offsetHeight + parseInt(getComputedStyle(parent.children[i]).marginBottom); continue; } if(i == (parent.children.length - 1)){ heightNow += parent.children[i].offsetHeight + parseInt(getComputedStyle(parent.children[i]).marginTop); continue; } heightNow += parent.children[i].offsetHeight + parseInt(getComputedStyle(parent.children[i]).marginTop + getComputedStyle(parent.children[i]).marginBottom); } return heightNow; } //     margin-top (,  ) //   height function makeElementsEqualHeight(){ if(correctingHeights){ //           for(var i = 0; i < elemsToCompare.length; i++){ for (var j = 1; j < elemsToCompare[i].length; j++){ if (checkParams(elemsToCompare[i][j]) == 0) continue; if(checkParams(elemsToCompare[i][j]) == 1){ elemsToCompare[i][j].children[0].style.marginTop = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j]))/2) + "px"; } if(checkParams(elemsToCompare[i][j]) == 2){ if(!elemsToCompare[i][j].querySelector("div[class='notchange']")){ //        notchange var div = document.createElement("div"); //    ,   div.classList.add("notchange"); //       DOM  elemsToCompare[i][j].appendChild(div); //       } elemsToCompare[i][j].lastChild.style.marginBottom = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j])) - 1) + "px"; } if(checkParams(elemsToCompare[i][j]) == 3){ if(!elemsToCompare[i][j].querySelector("div[class='notchange']")){ var div = document.createElement("div"); div.classList.add("notchange"); elemsToCompare[i][j].appendChild(div); } elemsToCompare[i][j].children[0].style.marginTop = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j]))/2) + "px"; elemsToCompare[i][j].lastChild.style.marginBottom = parseInt((elemsToCompare[i][0].offsetHeight - getTotalHeightOfChildren(elemsToCompare[i][j]))/2 - 1) + "px"; } } } } else{ //           for(var i = 0; i < elemsToCompare.length; i++){ for (var j = 1; j < elemsToCompare[i].length; j++){ if (checkParams == 0) continue; elemsToCompare[i][j].children[0].style.marginTop = ""; elemsToCompare[i][j].lastChild.style.marginBottom = ""; } } } } //          -  function checkAllowedMovingOrNot(){ if (userScreenWidth < allowedWidthOfTheWindow){ if (!correctingHeights) return; correctingHeights = false; } else{ correctingHeights = true; } } // ,         //  ,  : // height // margin function checkParams(elem){ if (elem.getAttribute("data-compareheightdo")){ var a = elem.getAttribute("data-compareheightdo").toLowerCase(); if (a == "margin"){ return 1; } if (a == "height"){ return 2; } if ((a == "margin height") || (a == "height margin")){ return 3; } } return 0; } //       function recountElems(){ checkUserScreenSize(); //     checkTheLargestElement(); //       (  data-compareheight="NAME") checkAllowedMovingOrNot(); // ,       makeElementsEqualHeight(); //  margin-top   }; setBreakePointWidthMinusScrollWidth(); //          recountElems(); //    ,     //         window.onresize = function(e){ recountElems(); }
      
      





このコードを簡単な例で確認しましょう。 垂直方向の中央揃えマージンのみを使用します。 divを介して、float:leftのスタイルで2つの列を作成します。 取得するサイズを計算します。



 <head> <meta charset="UTF-8"> <style> .elem1{ width: 35%; border: 1px dashed #ccc; float: left; margin-left: 20px; } p{ padding: 0px; margin: 0px; } body{ padding: 0px; margin: 0px; } </style> </head> <body> <div class="parent"> <div class="elem1" data-compareheight="hello" data-compareheightdo="margin"><p>What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum</p></div> <div class="elem1" data-compareheight="hello" data-compareheightdo="margin"><p>What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's</p><p style="margin-top: 15px;">What is Lorem Ipsum? Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's</p></div> </div> <div style="clear: both"></div> <script src="compareHeight.js"></script> <!--    --> </body>
      
      





画面幅1100px。 大きい列の高さは198pxです。 小さい列の子の高さは、54px(行の高さ)+ 54px(行の高さ)+ 15px(2番目のPのマージン上部)です。 合計で、子要素123pxの高さを取得します。



垂直方向に中央揃えするには、差を2つに分割し、margin-topの形式で上に追加する必要があります。 (198px-123px)/ 2 =(75px)/ 2 = 37.5px(マージントップ値が必要)。 実際には、38pxがあります。 そうです。



また、data-compareheightdo = " margin "をdata-compareheightdo = " height "に置き換えることにより、高さをチェックします。



最大ブロックと最小ブロックの1pxの差。 (この1pxは、以前にmakeElementsEqualHeight関数で読み込んだときのものです。



垂直方向の中央揃えと列の高さの水平化の両方を行う場合は、別のオプションを確認しましょう。 置換:data-compareheightdo = " margin " with data-compareheightdo = " margin height "



取得するもの:





PS開発者ツールのChromeでこれらの値を取得しました(F12キー)。



PSSこれらのメソッドは、DIV要素(divセットによるセレクター)でのみ機能します。



ご清聴ありがとうございました!



All Articles