2012-12-11 13 views
19

jQueryを使用して要素が通常のフローにあるかどうかをチェックする最もエレガントな方法は何ですか? CSS3 specificationによればJQuery:要素が通常のフローにあるかどうかを確認する

ボックスが流れに属している場合:

その「表示」の使用される値は、「ブロック」、「リスト項目」、「表であります'またはテンプレート

'float'の使用値は 'none'です。

'position'の使用値は 'static'または 'relative'です。

フロールートの子か、フローに属するボックスの子のいずれかです。

私はこれらすべての条件を確認したり、より良い方法はありますでしょうか?

+3

あなたはなぜ私の最初の質問は、ありますこれを知る必要がありますか?実際のアプリケーションでは、これらの品質のいずれかをテストするだけで済みます。 – Blazemonger

+0

これが仕様でのみ使用されている定義の場合は、実際の条件をチェックするのが最良です。 – pimvdb

+0

私は、ブラウザでスタイル付きのコンテンツをコピーして貼り付けることを含む個人的なサイドプロジェクトに取り組んでいます。フローの最初の要素の上マージンと最後の要素の下マージンを削除したい。 – sbichenko

答えて

3

は、私が思うには、別の「流れの中で」の要件は、そのです210はvisibleに設定される。

From the CSS2 spec:

フロート以外の「オーバーフロー」と絶対配置の要素、ボックスをブロックされていない(例えば、インラインブロック、テーブル細胞、および表キャプションなど)ブロックコンテナ、及びブロックボックス'visible'(その値がビューポートに伝播されている場合を除く)、その内容の新しいブロック書式設定コンテキストを確立します。あなたが引用された要件とoverflow要件に基づいて

、これはjQueryを使ってそれを行うための一つの方法である:

function isInFlow(elm, ctxRoot) { 

    ctxRoot = ctxRoot || document.body; 

    var $elm = $(elm), 
     ch = -1, 
     h; 

    if (!$elm.length) { 
     return false; 
    } 

    while ($elm[0] !== document.body) { 
     h = $elm.height(); 
     if (h < ch || !okProps($elm)) { 
      return false; 
     } 
     ch = h; 
     $elm = $elm.parent(); 

     if (!$elm.length) { 
      // not attached to the DOM 
      return false; 
     } 
     if ($elm[0] === ctxRoot) { 
      // encountered the ctxRoot and has been 
      // inflow the whole time 
      return true; 
     } 
    } 
    // should only get here if elm 
    // is not a child of ctxRoot 
    return false; 
} 

function okProps($elm) { 

    if ($elm.css('float') !== 'none'){ 
     return false;  
    } 
    if ($elm.css('overflow') !== 'visible'){ 
     return false;  
    } 
    switch ($elm.css('position')) { 
     case 'static': 
     case 'relative': 
      break; 
     default: 
      return false; 
    } 
    switch ($elm.css('display')) { 
     case 'block': 
     case 'list-item': 
     case 'table': 
      return true; 
    } 
    return false; 
} 
​ 

テストケースについてはjsFiddleを参照してください。

window.getComputedStyle()を使用する方がよいかどうかわかりません。

ctxRootのフローまたはブロックの書式設定のコンテキストにあるかどうかをチェックしています(前回と同じです)。 ctxRootが指定されていない場合は、body要素と照合します。これは、ctxRootが流れていることを確認するためのチェックではありません。このHTML

<div id="b" style="overflow: hidden;"> 
    <div id="ba">ba 
     <p id="baa">baa</p> 
     <span id="bab">bab</span> 
     <span id="bac" style="display:block;">bac</span> 
    </div> 
</div> 

でテストケースがあるので、:

var b = $('#b')[0]; 
console.log('no ',isInFlow(b)); 
console.log('no ',isInFlow('#ba')); 
console.log('yes ',isInFlow('#ba', b)); 
console.log('no ',isInFlow('#baa')); 
console.log('yes ',isInFlow('#baa', b)); 
console.log('no ',isInFlow('#bab')); 
console.log('no ',isInFlow('#bab', b)); 
console.log('no ',isInFlow('#bac')); 
console.log('yes ',isInFlow('#bac', b)); 
+0

詳細な分析とテストケースで受け入れられます。もう1つの解決策は場合によっては間違っていることが判明しています。 – sbichenko

4

私は疑うより良い方法をtheresのが、別の方法は、次のようになります。

1)はラッパー

2で要素を囲み)ラップ要素

とラッパーの高さと幅を比較たとえば

$('#elementToTest').clone().addClass('clone').wrap('<div></div>') 
if($('#elementToTest.clone').height()>$('#elementToTest.clone').parent().height()){ 
    //outside the normal flow 
} 
+0

これがどのくらい正確に機能するかを詳しく説明できますか? – sbichenko

+0

例を加えました –

+0

申し訳ありませんが、私は:要素が正常な流れにあるかどうかをチェックしますか? – sbichenko

0

の代わりにさかのぼってそれを見て、あなたはデータアノテーションを使用することによって、この必要性を横取りできます。要素を作成または定義するたびに、属性data-flowをtrueまたはfalseに設定します。例えば

var newDiv = document.createElement("div"); 
newDiv.style.position = "absolute"; 
newDiv.setAttribute("data-flow","false"); 

またはHTMLで

<div style="position:absolute;" data-flow="false"></div> 

そして、あなたは単にセレクタと、これらの要素を選択することができます:

$('*[data-flow=false]') 
関連する問題