JQuery:检查元素是否处于正常流程中

时间:2012-12-11 19:21:21

标签: javascript jquery html css

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

根据CSS3 specification

  

如果符合以下情况,则框属于流程

     
    

“显示”的使用值为“block”,“list-item”,“table”或模板

         

'float'的使用值是'none'。

         

其“位置”的使用值是“静态”或“相对”。

         

它是流根的子节点或属于该流的框的子节点。

  

我应该检查所有这些条件,还是有更好的方法?

3 个答案:

答案 0 :(得分:4)

我怀疑是更好的方式,但另一种方式是:

1)用包装器

包围元素

2)将包装纸的高度和宽度与包裹的元素进行比较

例如:

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

答案 1 :(得分:3)

我认为另一个“流程”要求是overflow设置为visible

From the CSS2 spec:

  

浮动,绝对定位的元素,阻止不是块框的容器(例如内联块,表格单元格和表格标题),以及除“可见”以外的“溢出”的块框(除非该值已传播到视口)为其内容建立新的块格式化上下文。

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

答案 2 :(得分: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]')
相关问题