2012-11-28 117 views
1

我想要計算一個隱藏父元素的寬度。因爲元素不可見,所以它返回一個零寬度。所以我寫了這個小函數:如何僅使用jQuery從內聯樣式獲取css屬性?

/** 
    * Compute the width of an element if it were to be visible. 
    * 
    * $element: The element you want to compute the width of 
    * $hiddenParent: A parent (ancestor) of $element which is currently hidden 
    * 
    * Returns: the width of $element if it were to be visible. 
    */ 
var getDisplayedWidth = function($element, $hiddenParent) { 
    var oldDisplay = $hiddenParent.css("display"); 
    $hiddenParent.show(); 
    var displayedWidth = $element.width(); 
    $hiddenParent.css("display",oldDisplay); 
    return displayedWidth; 
}; 

它的工作原理和返回顯示的寬度。但問題是,「oldDisplay」的值不是內聯顯示屬性的真實值。這是顯示屬性的計算值。 (這不是一個錯誤 - 這完全是我期望基於jQuery文檔的東西)。

這個微小的差異意味着該方法在以下用例中發生故障 - 我們有一個初始爲display:none的元素,但它是受控的通過一個類而不是內聯風格。所以oldDisplay被設置爲「無」。現在,當顯示屏恢復時,display:none成爲內聯樣式。在稍後的執行過程中,當其他一些javascript添加一個類使其可見時,內聯樣式優先,並且該元素不會出現。

我在這種情況下真正想要做的只是提取「顯示」屬性的內聯樣式版本。如果元素沒有內聯「顯示」屬性(如上例),那麼我想oldDisplay被設置爲一個空字符串。

現在我已經解釋了背景,簡單地說就是這個問題 - 我如何從內聯樣式獲取CSS屬性?

(PS:我知道我可以通過手動解析「style」屬性做到這一點,但我覺得必須有一個更好的辦法,尤其是使用jQuery。)

+4

也許觸發一類設置顯示器是更好的方式去?完全避免內聯? – Selosindis

+0

爲什麼當顯示屏恢復'display:none'變爲內聯樣式? –

+0

@Selosindis只有在我能保證該類優先於目前在那裏的任何類時纔會起作用。如果有問題的元素已經有內聯樣式,我會完全擰緊。 – Kidburla

回答

1

如果樣式被設置爲display: none樣式表,不能你剛纔獲得的寬度是這樣的:

function getElWidth(el, elParent){ 
    elParent.show() // inline display: block 
    var w = el.width(); 
    elParent.attr('style', ''); 
    return w; 
} 

我想這使用style屬性,但只是一個想法。

+0

是的,我可以,但是這是假設樣式表中樣式被設置爲'display:none'。我想要做的是創建一個通用的方法,不管用例如何。我給出的例子只是一個例子來說明「直觀的方式」不起作用。爲了使用你的代碼,我必須找出是否真的在樣式表中設置了「display:none」而不是內聯樣式。這相當於找出顯示的內聯樣式值。順便提一下,我還會設置'elParent.css(「display」,「」)',以免影響其他不相關的CSS屬性。 – Kidburla

0

一些代碼在json每個樣式屬性中獲取單獨的樣式。

$(selector,this).each(function(index) 
{ 
    var styletag=$(this).attr('style'); 
    var stylestemp=styletag.split(';'); 
    var styles={}; 
    var c=''; 
    for (var x in stylestemp) { 
    c=stylestemp[x].split(':'); 
    styles[$.trim(c[0])]=$.trim(c[1]); 
    } 
    // do whatever with the styles json here. 
}); 

或嘗試這個問題,以及:

$(".someSelector[style*=inline]").attr("myAttribute"); //給出任何選擇用方括號將過濾掉那些帶有內嵌樣式的條件。

+0

謝謝,這就是我的意思是「手動解析樣式屬性」。但我想知道是否有一些更原生的jQuery方法來做到這一點,或做我想要實現的。 – Kidburla

+0

我忘了補充,我查了一下。你不能沒有做就不能離開。 –

+0

順便說一句,我發現了另一個jQuery選擇器語法,請檢查您是否可以在此處使用它。 –

2

這樣做的問題是,如果父元素設置爲顯示:none,那麼所有孩子也將顯示display:none作爲他們的計算風格。因此,除非您知道所有父母都可見,否則在相關元素上可見的設置顯示可能無效。另外,您不希望影響元素樣式,可以通過覆蓋之前的內聯顯示模式,也可以通過覆蓋樣式表聲明來影響元素樣式。

我寫了這個小寶石來解決這兩個問題:

jQuery.fn.locate = function() { 
var o = this, a = [], 
    n = o.filter(':hidden').parents(':hidden').addBack() 
     .each(function(i){ a[i] = $(this).get(0).style.display || '' }) 
     .css('display','block'), 
    xy = o.offset(), p = [ xy.left - parseInt(o.css('margin-left'),10), o.width(), xy.top - parseInt(o.css('margin-top'),10), o.height() ] 
    n.each(function(i){ $(this).get(0).style.display = a[i] }) 
    return {'left':p[0], 'right':p[0] + p[1], 'width':p[1], 'top':p[2], 'bottom':p[2] + p[3], 'height':p[3]} 
} 

這將搜索包括原始元素的所有父元素,記錄他們的內嵌樣式屬性,它們都設置爲display:block,記錄你的原元素絕對定位信息,恢復所有受影響元素的內聯樣式,然後返回帶有定位數據的對象。您可以修改它以更改它返回的數據。

var t = $(elem).locate() 
alert(t.width) 

這是一個更復雜的版本,它允許您存儲包含多個元素的jQuery對象的定位數據。它將信息存儲到每個元素的.data()屬性,並返回原始對象以維持鏈接。

jQuery.fn.markLocation = function() { 
var o = this, a = [], 
    n = o.filter(':hidden').parents(':hidden').addBack() 
     .each(function(i){ a[i] = $(this).get(0).style.display || '' }) 
     .css('display','block') 
    o.each(function(){ 
     var t = $(this), xy = t.offset(), 
      p = [ xy.left - parseInt(t.css('margin-left'),10), t.width(), xy.top - parseInt(t.css('margin-top'),10), t.height() ] 
     t.data({'left':p[0], 'right':p[0] + p[1], 'width':p[1], 'top':p[2], 'bottom':p[2] + p[3], 'height':p[3]}) 
    }) 
    n.each(function(i){ $(this).get(0).style.display = a[i] }) 
    return o 
} 

要使用它:

var t = $('elems').markLocation() 
var d = t.find(singleElement).data() 
alert(d.width) 

是的,我故意代碼異端混亂的方式,從不打算改變:)

享受

相關問題