簡體   English   中英

JQuery:檢查元素是否處於正常流程中

[英]JQuery: check if element is in normal flow

使用jQuery檢查元素是否在正常流程中的最優雅方法是什么?

根據CSS3規范

如果符合以下情況,則框屬於流程:

其“顯示”的使用值為“塊”,“列表項”,“表格”或模板

其'float'的使用值為'none'。

其“位置”的使用價值是“靜態”或“相對”。

它既可以是流根的子節點,也可以是屬於流的子節點。

我應該檢查所有這些條件,還是有更好的方法?

我懷疑這是一個更好的方式,但不同的方式是:

1)用包裝物包圍元件

2)將包裝材料的高度和寬度與包裹元件進行比較

例如:

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

我認為另一個“流程”要求是overflow設置為visible

從CSS2規范:

浮動,絕對定位元素,阻止不是塊框的容器(例如內聯塊,表格單元格和表格標題),以及“溢出”除“可見”之外的塊框(除非該值已傳播)到視口)為其內容建立新的塊格式化上下文。

根據您引用的要求和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()

該函數正在檢查elm是否在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));

您可以通過使用數據注釋來預防對此的需求,而不是追溯地查看它。 無論何時創建或定義元素,都應將其屬性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]')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM