JQuery:检查元素是否在正常流中 [英] JQuery: check if element is in normal flow
问题描述
使用jQuery检查元素是否在正常流程中的最优雅的方法是什么?
根据 CSS3规范,
/ p>
其'display'的使用值为'block','list-item','table'或 template 。
其'float'的使用值为'none'。
它的位置是静态或相对。
它是流根的子节点或属于流的子节点。 / p>
我应该检查所有这些条件,还是有更好的方法?
我认为另一个流的要求是 overflow
设置为可见
。
浮动,绝对定位的元素不是块的块(例如行内块,表格单元格和表字幕)以及除可见之外的溢出的块块(除非该值已经传播到视口)建立新的块格式
- 对相关问题的非常详细的答案。
- 关于块格式化上下文的YUI博客条目
- 我发现在过去有帮助的博文
ul>
根据你引用的要求和 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){
//未附加到DOM
return false;
}
if($ elm [0] === ctxRoot){
//遇到ctxRoot并已经
//流入整个时间
return true ;
}
}
//如果elm
//应该只在这里//不是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;
默认值:
return false;
}
switch($ elm.css('display')){
case'block':
case'list-item':
case'table' :
return true;
}
return false;
}
查看此 jsFiddle 测试用例。
我不确定是否会更好请使用 window.getComputedStyle()$ c $
此函数正在检查 elm
是否位于 ctxRoot
的流或块格式化上下文(以前称为,我想)。如果不提供 ctxRoot
,它将检查 body
元素。这不检查以确保 ctxRoot
在流程。因此,使用此HTML
< div id =bstyle =overflow:hidden;&
< div id =ba> ba
< p id =baa> baa< / p>
< span id =bab> bab< / span>
< span id =bacstyle =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));
What is the most elegant way to check whether an element is in the normal flow using jQuery?
According to the CSS3 specification,
A box belongs to the flow if:
The used value of its ‘display’ is ‘block’, ‘list-item’, ‘table’ or template.
The used value of its ‘float’ is ‘none’.
The used value of its ‘position’ is ‘static’ or ‘relative’.
It is either a child of the flow root or a child of a box that belong to the flow.
Should I just check for all these conditions, or is there a better way?
I think another "in flow" requirement is that overflow
is set to visible
.
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
- A very detailed answer to a related question.
- YUI blog entry about block formatting contexts.
- A blog post I've found helpful in the past.
Based on the requirements you quoted and the overflow
requirement, this is one way to do it with 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;
}
See this jsFiddle for test cases.
I'm not sure if it would be better to use window.getComputedStyle()
or not.
The function is checking to see if elm
is in ctxRoot
's flow or block formatting context (as it was previously called, I think). If ctxRoot
is not supplied, it will check against the body
element. This does not check to make sure ctxRoot
is in flow. So, with this 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>
The test cases are:
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));
这篇关于JQuery:检查元素是否在正常流中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!