2011-04-13 5 views
2

템플릿을 만드는 데 사용하는 HTML 클래스가 있습니다. 내 클래스는 다음과 같이 작동이 누락 된 문자 나 잘못 인용 속성에 대한 걱정없이 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'); 
?> 

. 모든 것이 캐시되고 성능 문제는 없습니다.

이제이 단계를 더 진행하고 싶습니다. 프로덕션 모드에서는 모든 것이 정상적으로 작동하지만 최종 출력을 위해 모든 인라인 "스타일"속성을 제거하고 CSS 파일에서이를 최소화하고 캐시하고 싶습니다. 이제 모든 HTML 객체를 반복하고 태그, ID 및 클래스에 따라 데이터를 집계하는 함수가 있습니다. 내 질문은 : 그 형태로 내 깔끔한 CSS를 배열을 일단 : 나는 관련 CSS 파일 왼쪽하고 그래서

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

가 어떻게 중복 값을 잘라합니까? 축소 및 gzipping은 나중에 나올 수 있습니다. 이제는 값을 비교하고 덤프하기 전에 배열을 최적화하여 동일한 태그/id/클래스를 가진 모든 요소에 공통된 '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

"중복 값을 어떻게 제거합니까?"예제를 제공 할 수 있습니까? 나는 왜 당신이 같은 객체에 클래스와 스타일을 모두 적용하는지 혼란스러워합니다. –

답변

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">

얻을 것 경로에있는 모든 클래스를해야합니다 : ID를

.parent { 
    background: red; 
} 

.childA { 
    border: 1px solid black; 
} 

.childB { 
    font-weight: 800; 
} 

메모를, 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

에 대한 규칙을 만들 수 있습니다 나을 각 노드로 이동하여 아이를 분석 할 필요가있다. 동일한 노드 유형의 모든 하위 요소가 공통 스타일 요소를 공유하면 (위의 집합 비교기 사용) 공통 세트 요소를 부모로 추출하십시오. 그 차이가 아이들이됩니다.

은 (주 이미 통과 한을 거친 경우) 예를 들어이 있다고 가정하자 :

<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 클래스를 제거하고 .menuli 규칙을 #menu li 규칙으로 대체하여이 작업을 수행합니다. 에서와 같은

우리의 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 문제가됩니다.

희망이 도움이됩니다. 이것이 당신이 가고자하는 방향이라면, 나는 훨씬 더 복잡하지만, set comparator와 아마도 tree searcher에 관한 더 많은 코드를 도와 드리겠습니다.

+0

그건 아주 흥미로운 해결책입니다. 그러나 이것이 CSS 구조의 목적을 무시하고 DOM 구조 관계에 강건한 CSS를 도입하는 것이 아닌지 궁금합니다.예를 들어, .parent {color : pink} .child1 {color : pink} .child2 {color : yellow}? 자식 1은 .parent에서 상속받을 수 있으므로 분홍색 선언이 필요하지 않습니다. 그러나 child1이 결국 child2 컨테이너에서 끝나면 어떨까요? 그런 다음 색을 다시 선언해야합니다. 여러 반복을 통해 처리 될 수 있다고 생각합니다. –

+0

좋은 지적이 있습니다. 보통의 CSS에서는'.child1 {color : pink; }'그러나, 문제는 스타일 속성에서 추출 할 수있는 가장 작은 CSS를 얻는 것이라고 생각합니다. html/styles가 바뀔 때마다 CSS를 다시 생성해야한다고 생각합니다. – ohmusama

+0

예, 그렇게 생각합니다. 확실히 재미있는 퍼즐입니다. .css 파일이 캐시 될 것이라는 점을 고려하면 도움이됩니다 (주요 목표). 그러나 CSS가 HTML과 독립적이지 않다는 것을 의미합니다. 예, HTML을 변경할 때마다 '다시 컴파일'해야 할 것 같습니다. 자주 업데이트되는 경우 .css 캐싱의 이점을 무효화 할 수 있습니다. 나는 그것이 업데이트의 성격에 달려 있다고 생각합니다. –