[英]Determine whether element has fixed or percentage width using JavaScript
使用Mootools Element.Dimensions我可以獲得任何元素的計算大小(以像素為單位)。 但是,我無法確定元素是否已使用像素值或百分比值進行大小調整(除了具有內聯樣式的特殊情況)。
這樣做有明智的方法嗎? 我能想到的唯一解決方案(這是如此丑陋,幾乎不值得這個名字)是遍歷文檔樣式表,尋找與目標元素匹配的選擇器,然后查看目標屬性的聲明樣式。
背景
我試圖用CKEditor實例替換某個類的所有textareas。 理想情況下,100%寬度的textareas將被類似樣式的編輯器實例替換 - 因此它們可以在窗口調整大小上進行縮放 - 而固定大小的textareas將由固定大小的編輯器替換。
是的,我可以給他們一個不同的類(如果沒有好的解決方案,我將會這樣做),但理想情況下我希望能夠放入我的CKEditor腳本,並且無需調整HTML即可完成所有工作。
可以辦到。 看看這個問題( 為什么getComputedStyle在元素創建后立即返回'auto'作為像素值? )給出了提示。
如果將元素的樣式設置為display = none,然后調用getComputedStyle,您將獲得計算值(百分比寬度或'auto'或樣式表應用於元素的任何內容)而不是像素寬度。
工作代碼jsfiddle https://jsfiddle.net/wtxayrnm/1/
function getComputedCSSValue(ele, prop) {
var resolvedVal = window.getComputedStyle(ele)[prop];
//does this return a pixel based value?
if (/px/.test(resolvedVal)) {
var origDisplay = ele.style.display;
ele.style.display = 'none';
var computedVal = window.getComputedStyle(ele)[prop];
//restore original display
ele.style.display = origDisplay;
return computedVal;
} else {
return resolvedVal;
}
}
應該注意的是,這將導致布局重新呈現,但是,根據您的情況,它可能比遍歷所有樣式表規則或克隆元素(這可能導致某些級聯規則不應用)更簡單。
不熟悉Motools,但在jQuery中你可以做到。
點擊此處查看現場演示http://jsbin.com/ewuqa
或者檢查一下,它還處理多個匹配的CSS規則,但只返回正確的值(我唯一沒有理解的是if !important
設置)。
包括JS
http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
http://github.com/hafriedlander/jquery.concrete/raw/master/vendor/jquery.selector/jquery.class.js
http://github.com/hafriedlander/jquery.concrete/raw/master/vendor/jquery.selector/jquery.selector.js
http://github.com/hafriedlander/jquery.concrete/raw/master/vendor/jquery.selector/jquery.selector.specifity.js
自己的功能
function compare(as,bs) {
return (as[0] - bs[0]) || (as[1] - bs[1]) || (as[2] - bs[2]);
}
//selector should only match a single element
//property is a css style-name
//returns the set css value (if set) for matched element, not the computed value
//also handles multiple matching rules and only returns most specific match
//doesn't handle !important
function whatIsSet(selector, property) {
var se = $(selector);
var regex = new RegExp("(.*)-(.)(.*)","g");
var p = property;
if (/-/.test(p)) {
p = regex.exec(property);
p = p[1] + p[2].toUpperCase() + p[3];
}
if (se.get(0).style[p] != undefined && se.get(0).style[p] != '')
return se.get(0).style[p];
var matchers = new Object();
var mostSpecific = undefined;
for(var i = 0; i < document.styleSheets.length; i++) {
//IE support
var rules =
document.styleSheets[i].cssRules ?
document.styleSheets[i].cssRules :
document.styleSheets[i].rules;
for (var j=0; j < rules.length; j++)
if (rules[j].style[p])
if (jQuery.inArray(se, $(rules[j].selectorText)))
matchers[rules[j].selectorText] = rules[j].style[p];
}
for(var i in matchers) {
if(mostSpecific != undefined) {
var ms = $.selector(mostSpecific).specifity();
var is = $.selector(i).specifity();
mostSpecific = compare(ms, is) > 0 ? mostSpecific : i;
} else
mostSpecific = i;
}
return matchers[mostSpecific];
}
CSS
body { background-color: #000; font: 16px Helvetica, Arial; color: #fff; }
#myElement {background-color: yellow; width:10%}
div {background-color: green; width:200px}
div#myElement {background-color: blue; width:30%}
div.asd#myElement {background-color: red; width:50%;}
HTML
<div id="myElement" class="asd" style="width:91%">asd</div>
<input
type="button"
onclick="javascript:alert('width originally set to: '+
whatIsSet('#myElement', 'width'));"
value="Tell me original width!"><br>
<input
type="button"
onclick="javascript:alert('height originally set to: '+
whatIsSet('#myElement', 'height'));"
value="Tell me original height!"><br>
<input
type="button"
onclick="javascript:alert('background-color originally set to: '+
whatIsSet('#myElement', 'background-color'));"
value="Tell me original background-color!"><br>
我已經從一個封閉的副本中遷移並更新了我的答案:
不想走下掃描風格的路線我發現這有效...但不幸的是只有firefox :(對我而言,如果元素沒有任何東西可以計算它的寬度(即它不是它應該返回它的原始值 - 這就是FireFox的作用:
function isElementFluid(elm){
var clone = elm.cloneNode(false);
if( window.getComputedStyle ) {
value = window.getComputedStyle(clone,null).width;
} else if( clone.currentStyle ) {
value = clone.currentStyle.width;
}
return (value && String(value).indexOf('%') != -1 );
}
(尚未測試IE)
然而,Webkit和Opera返回一個空白值 - 這又是我同意FireFox實現的另一個例子,並且對其他人不屑一顧。
好吧,不是被計算機擊敗的粉絲;)所以提出了這個功能 - 完全超過頂部,但它似乎確實有效。 我還沒有在IE上測試這個,因為我現在還沒有Windows機器。 當原始的FireFox版本非常簡潔時,它很煩人,但這里的邏輯是合理的 - 它會回落到正常人類在測試某些東西是否有彈性時所做的事情。
function isElementFluid(elm){
var wrapper, clone = elm.cloneNode(false), ow, p1, p2;
if( window.getComputedStyle ) {
value = window.getComputedStyle(clone,null).width;
} else if( clone.currentStyle ) {
value = clone.currentStyle.width;
}
/// the browsers that fail to work as Firefox does
/// return an empty width value, so here we fall back.
if ( !value ) {
/// remove styles that can get in the way
clone.style.margin = '0';
clone.style.padding = '0';
clone.style.maxWidth = 'none';
clone.style.minWidth = 'none';
/// create a wrapper that we can control, my reason for
/// using an unknown element is that it stands less chance
/// of being affected by stylesheets - this could be improved
/// to avoid possible erroneous results by overriding more css
/// attributes with inline styles.
wrapper = document.createElement('wrapper');
wrapper.style.display = 'block';
wrapper.style.width = '500px';
wrapper.style.padding = '0';
wrapper.style.margin = '0';
wrapper.appendChild(clone);
/// insert the element in the same location as our target
elm.parentNode.insertBefore(wrapper,elm);
/// store the clone's calculated width
ow = clone.offsetWidth;
/// change the wrapper size once more
wrapper.style.width = '600px';
/// if the new width is the same as before, most likely a fixed width
if( clone.offsetWidth == ow ){
/// tidy up
elm.parentNode.removeChild(wrapper);
return false;
}
/// otherwise, calculate the percentages each time - if they
/// match then it's likely this is a fluid element
else {
p1 = Math.floor(100/500*ow);
p2 = Math.floor(100/600*clone.offsetWidth);
/// tidy up
elm.parentNode.removeChild(wrapper);
return (p1 == p2) ? Math.round(p1)+'%' : false;
}
}
else {
p1 = (value && String(value).indexOf('%') != -1);
return p1 ? value : false;
}
}
在IE中, element.currentStyle.width
。 在許多其他瀏覽器中, getComputedStyle(element, null).getPropertyValue('width')
。
我懷疑它可以做到。 您非常准確地描述了原因:只有在元素的樣式屬性中才能訪問此類信息。 我能想到的唯一方法是稍微擴大父容器,看看textarea的大小是否成比例增長,但這可能並不總是可行的,並且可能很難使跨瀏覽器功能化。
不過,我對更積極的答案非常感興趣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.