2011-04-13 70 views
2

我有一個用於創建模板的HTML類。 我班的工作原理是這樣的:我有一個我想合併的css數組

<?php 
$page = \TEST\HTML::dispense(':html'); 
$page->mainWrapper(':div') //creates a child object by using __call() and sets the "div" model 
->id('mainWrapper') //sets id 
->style('background','red') //adds a style 
->text('blah') //adds a text 
->addClass('someClass'); //adds a class 
->someSpan(':span') 
->addClass('spanClass')->addClass('someClass') 
->style('font-size','12pt') 
->style('border-bottom','1pt dashed black') 
->style('background','red'); 
?> 

這讓我對HTML標記的快速發展,而不必擔心對缺少的字符或錯誤引用屬性。一切都得到緩存,我沒有任何性能問題。

現在我想更進一步。在生產模式下,一切工作正常,但對於最終的輸出,我想刪除所有內聯「樣式」屬性,並將它們最小化並將它們緩存在一個css文件中。 現在,我有一個循環遍歷所有HTML對象的函數,並根據標記,id和類聚合數據。 我的問題是:一旦我有這種形式我整齊的CSS陣列:

$style['tag']['.class']['#id']['styleKey'] = styleValue 

如何修剪掉冗餘值,所以我留下了一個相關的css文件?縮小和壓縮可以在稍後階段進行。我現在想要的是比較值並在轉儲之前對數組進行優化,以便將所有具有相同tag/id/class的元素共有的'styleKeys'分組在一起。因此,在上面的例子中,因爲兩個元素(div和span)共享樣式「background:red」和類「someClass」,所以我會有一個「someClass」CSS規則和「background :紅色的」

如果是任何利益,這是我的‘extractstyles’功能:

<?php 
public static function extractStyles($element, array &$styles=array()){ 
    if($element instanceof \TEST\HTML){$element = $element->htmlData();} 
    $tag = isset($element['#acronym']) ? $element['#acronym'] : NULL; 
    $id = isset($element['#id']) ? '#'.$element['#id'] : NULL; 
    $classes = isset($element['#class']) ? $element['#class'] : NULL; 
    if(isset($element['#style']) && ($tag || $id || $class)){ 
     $ref = &$styles; 
     if($id){if(!isset($ref[$id])){$ref[$id] = array();};$ref = &$ref[$id];} 
     if($classes){ 
      if(\is_array($classes)){$classes = '.'.implode('.',$classes);} 
      if(!isset($ref[$classes])){$ref[$classes] = array();};$ref = &$ref[$classes]; 
     } 
     if($tag){if(!isset($ref[$tag])){$ref[$tag] = array();};$ref = &$ref[$tag];} 
     foreach($element[self::ATTRIBUTES]['#style'] as $style=>$value){ 
      $ref[$style] = $value; 
     } 
    } 
    if(isset($element[self::CHILDREN]) && count($element[self::CHILDREN])){ 
     foreach($element[self::CHILDREN] as $child){ 
      self::extractStyles($child, $styles); 
     } 
    } 
    return $styles; 
} 
?> 

任何指針會更受歡迎...我真的失去了。我甚至不知道我在找什麼是可行的。

如上所述,性能現在不是問題。如果它有效,我會找到一種方法來優化它。 另外,請不要鏈接到xCSS和其他框架,因爲它們處理字符串,而我的CSS是作爲數組創建的。 在此先感謝您的幫助!

+0

「我該如何修剪掉多餘的值」,你能提供一個例子嗎?我有點困惑,爲什麼你會同時將類和樣式應用於同一個對象。 – 2011-04-13 23:19:01

回答

2

一階優化是構建一個層次樹。在這棵樹中的父母與子女的關係是一個孩子是父母的超集。這棵樹的根節點是一個空的樣式(你不會顯示)。

因此,如果你有

.parent { 
    background: red; 
} 

.childA { 
    background: red; 
    border: 1px solid black; 
} 

.childB { 
    background: red; 
    font-weight: 800; 
} 

父被設置爲在樹的最小公分母。然後可以用較少的文本壓縮成3個類。該子元素將所有的類路徑中,如果你原來有<span class="childA">你會再拿到<span class="parent childA">

的壓縮類的樣子:

.parent { 
    background: red; 
} 

.childA { 
    border: 1px solid black; 
} 

.childB { 
    font-weight: 800; 
} 

的說明上的ID,ID將永遠是個孩子最合適的班級。因此,如果你有

#menu { 
    background: red; 
    border: 1px solid black; 
    margin: 15px 40px; 
    color: white; 
} 

它將成爲ChildA的孩子,它的CSS將減少到

#menu { 
    margin: 15px 40px; 
    color: white; 
} 

,並顯示爲<ul id="menu" class="parent childA">

要創建樹,你將需要一個對象將存儲一個相同的子對象(遞歸)的數組而且一個函數,當給定兩個對象時,可以確定它們的CSS是否是子集,等於或超集,差異的數量,還是沒有共同性。

如果您不熟悉二叉搜索樹,那麼現在是時候瞭解這一點,儘管這會比這更復雜,它將是一個正確方向的良好開端。


二階優化是確定子元素的嵌套是否可以進一步減少對類的需求。例如,如果你所有的<li><ul id="#menu">進行類似的風格,將讓你可以創建#menu li

規則要做到這個意義上說,你需要去到每個節點,並分析其子女。如果同一節點類型的所有子節點共享一個公共樣式元素(使用上面的set比較器),請將公共set元素作爲父節點提取。差異成爲孩子。

比方說你有這個作爲一個例子(注意是已經通過通1已經走了):

<ul id="menu" class="parent childA"> 
    <li class="top menuli">Item</li> 
    <li class="menuli">Item</li> 
    <li class="menuli">Item</li> 
    <li class="menuli">Item</li> 
    <li class="bottom menuli">Item</li> 
</ul> 

我們注意到,所有的<li>有一個共同的元素.menuli,這意味着我們可以消除這種類這是通過1創建的,並用#menu li的平坦規則替換它。我們通過從每個孩子li中刪除menuli類,並用#menu li規則替換.menuli規則來做到這一點。

像我們的CSS變化:

#menu { 
    margin: 15px 40px; 
    color: white; 
} 

.menuli { 
    font-size: 30px; 
    font-weight: 800; 
    margin: 8px 0; 
} 

#menu { 
    margin: 15px 40px; 
    color: white; 
} 

#menu li { 
    font-size: 30px; 
    font-weight: 800; 
    margin: 8px 0; 
} 

和HTML失去類menuli

<ul id="menu" class="parent childA"> 
    <li class="top">Item</li> 
    <li>Item</li> 
    <li>Item</li> 
    <li>Item</li> 
    <li class="bottom">Item</li> 
</ul> 

記得使用廣度優先搜索向下搜索,當你節點樹而不是深度優先搜索。如果你是攻擊性的,你可以在許多路徑上繼續檢查第二級的相似標籤,普通的第二級搜索可能會揭示類似的類#menu li a#container div p等。如果允許無限深度搜索,這將成爲NP難題。

希望這會有所幫助。如果這是你想要去的方向,我很樂意提供更多關於集合比較器和可能的樹搜索器的代碼,儘管這更復雜。

+0

這是非常有趣的解決方案。然而,我不知道這是否有點挫敗了CSS的意圖,首先通過向DOM結構關係引入僵化的CSS。例如,你將如何處理:.parent {color:pink} .child1 {color:pink} .child2 {color:yellow}?子1不需要粉紅色的聲明,因爲它可以繼承.parent。但是,如果child1最終在child2容器中結束呢?然後它需要返回顏色聲明。我想這可以通過多次迭代來處理。 – 2011-04-13 23:45:09

+0

你有一個好點。在正常的CSS中,你會想保持'.child1 {color:pink; }'不過,我認爲問題是要獲取可以從樣式屬性中提取的最小css。我認爲每次html/styles更改時都必須再次生成css。 – ohmusama 2011-04-13 23:52:23

+0

是的,我相信。這當然是一個有趣的謎題。它確實有幫助,因爲.css文件將被緩存(主要目標)。但它確實意味着CSS不是獨立於HTML,所以是的,它似乎需要爲HTML的每次更改重新編譯。如果頻繁更新,可能會否定緩存.css的好處。我想這一切都取決於更新的性質。 – 2011-04-13 23:57:13

相關問題