관계의 부모-자식 관계를 계층 적 트리로 변환 하시겠습니까?
가능한 한 약간의 약간의 계층 구조 트리 구조로 바꾸고 싶은 이름-부모 이름 쌍이 많이 있습니다. 예를 들어 다음과 같은 쌍이 될 수 있습니다.
Child : Parent
H : G
F : G
G : D
E : D
A : E
B : C
C : E
D : NULL
(a) 계층 적 트리로 변환해야합니다.
D
├── E
│ ├── A
│ │ └── B
│ └── C
└── G
├── F
└── H
내가 원하는 최종 결과는 <ul>
추가 <li>
의 이름을 포함 하는 중첩 된 요소 집합입니다 .
쌍에는 불일치가 내부 (하위는 자신의 부모, 부모는 마이너스 등) 많은 최적화를 수행 할 수 있습니다.
PHP에서 어떻게 child => parent 쌍을 포함하는 배열에서 중첩 세트로 몇 개의 <ul>
서열을 가지고 있습니까?
재귀가 관련되어 있다고 생각합니다.
어느 쪽이든 / 부모 쌍을 트리 구조로 구문 분석하는 매우 기본적인 재귀 함수와이를 인쇄하기 또위한 재귀 함수가 있습니다. 하나의 기능만으로 충분하지만 명확성을 위해 두 가지 기능이 있습니다.
먼저 먼저 / 부모 쌍의 배열을 초기화합니다.
$tree = array(
'H' => 'G',
'F' => 'G',
'G' => 'D',
'E' => 'D',
'A' => 'E',
'B' => 'C',
'C' => 'E',
'D' => null
);
그런 다음 해당 배열을 계층 트리 구조로 구문 분석하는 함수 :
function parseTree($tree, $root = null) {
$return = array();
# Traverse the tree and search for direct children of the root
foreach($tree as $child => $parent) {
# A direct child is found
if($parent == $root) {
# Remove item from tree (we don't need to traverse this again)
unset($tree[$child]);
# Append the child into result array and parse its children
$return[] = array(
'name' => $child,
'children' => parseTree($tree, $child)
);
}
}
return empty($return) ? null : $return;
}
그리고 그 트리를 순회하여 정렬되지 않은 목록을 출력하는 함수 :
function printTree($tree) {
if(!is_null($tree) && count($tree) > 0) {
echo '<ul>';
foreach($tree as $node) {
echo '<li>'.$node['name'];
printTree($node['children']);
echo '</li>';
}
echo '</ul>';
}
}
그리고 실제 사용 :
$result = parseTree($tree);
printTree($result);
의 내용은 다음과 가변 $result
됩니다.
Array(
[0] => Array(
[name] => D
[children] => Array(
[0] => Array(
[name] => G
[children] => Array(
[0] => Array(
[name] => H
[children] => NULL
)
[1] => Array(
[name] => F
[children] => NULL
)
)
)
[1] => Array(
[name] => E
[children] => Array(
[0] => Array(
[name] => A
[children] => NULL
)
[1] => Array(
[name] => C
[children] => Array(
[0] => Array(
[name] => B
[children] => NULL
)
)
)
)
)
)
)
)
좀 더 효율성을 원하면 함수를 하나로 결합하여 반복 횟수를 수 있습니다.
function parseAndPrintTree($root, $tree) {
$return = array();
if(!is_null($tree) && count($tree) > 0) {
echo '<ul>';
foreach($tree as $child => $parent) {
if($parent == $root) {
unset($tree[$child]);
echo '<li>'.$child;
parseAndPrintTree($child, $tree);
echo '</li>';
}
}
echo '</ul>';
}
}
이만큼 작은 데이터 세트에 8 번의 반복 만 저장하지만 더 큰 세트에서는 차이를 만들 수 있습니다.
트리를 만드는 또 다른 함수 (재귀가 필요하지 않고 대신 참조를 사용함) :
$array = array('H' => 'G', 'F' => 'G', ..., 'D' => null);
function to_tree($array)
{
$flat = array();
$tree = array();
foreach ($array as $child => $parent) {
if (!isset($flat[$child])) {
$flat[$child] = array();
}
if (!empty($parent)) {
$flat[$parent][$child] =& $flat[$child];
} else {
$tree[$child] =& $flat[$child];
}
}
return $tree;
}
다음과 같은 계층 적 배열을 반환합니다.
Array(
[D] => Array(
[G] => Array(
[H] => Array()
[F] => Array()
)
...
)
)
재귀 함수를 사용하여 HTML 목록으로 쉽게 인쇄 할 수 있습니다.
의 플랫 구조를 $tree
계층 구조로 변환하는 더 간단한 또 다른 방법 입니다. 노출 비용 임시 배열이 하나만 필요합니다.
// add children to parents
$flat = array(); # temporary array
foreach ($tree as $name => $parent)
{
$flat[$name]['name'] = $name; # self
if (NULL === $parent)
{
# no parent, is root element, assign it to $tree
$tree = &$flat[$name];
}
else
{
# has parent, add self as child
$flat[$parent]['children'][] = &$flat[$name];
}
}
unset($flat);
이것이 계층 구조를 다차원 배열로 가져 오는 것입니다.
Array
(
[children] => Array
(
[0] => Array
(
[children] => Array
(
[0] => Array
(
[name] => H
)
[1] => Array
(
[name] => F
)
)
[name] => G
)
[1] => Array
(
[name] => E
[children] => Array
(
[0] => Array
(
[name] => A
)
[1] => Array
(
[children] => Array
(
[0] => Array
(
[name] => B
)
)
[name] => C
)
)
)
)
[name] => D
)
재귀를 피하려는 경우 덜 간단합니다 (큰 구조의 경우 부담이 될 수 있음).
저는 어레이 출력에 대한 UL / LI "딜레마"를 항상 해결하고 싶었습니다. 딜레마는 각 항목이 마이너스가 조치를하거나 또는 종료 아야하는 선행 요소의 수를 알지 수단은 것입니다. 또 다른 대답에서 나는 이미 a를 사용하고 내가 다른 메타 정보를 RecursiveIteratorIterator
찾아서 해결했습니다 . 중첩 된 세트 모델을 "닫힌"하위 트리 로 가져 오기 . 그 대답 은 반복적으로 사용하면 매우 유연하다는 것을 보여줍니다.getDepth()
Iterator
<ul>
귀하의 승인을받지 않을 것입니다. 또한 나는 항상 표준 트리 구조와 HTML <ul>
및 <li>
요소에 대해 해결하고 싶었습니다 .
내가 생각 해낸 기본 개념은 다음과 가변합니다.
TreeNode
-각 요소를TreeNode
값 (예 :)Name
과 마이너스가 있는지 여부를 제공 할 수 있는 간단한 유형으로 추상화합니다 .TreeNodesIterator
-RecursiveIterator
이 세트 (배열)를 반복 할 수 있습니다TreeNodes
.TreeNode
어떤 종류가 이미 존재하는지, 어떤 것이 있는지 알고 있기 때문에 매우 간단 합니다.RecursiveListIterator
-다음RecursiveIteratorIterator
과 같은 유형을 반복적으로 반복 할 때 필요한 모든 이벤트가 있는 A 입니다RecursiveIterator
.beginIteration
/endIteration
-기본 목록의 시작과 끝.beginElement
/endElement
-각 요소의 시작과 끝.beginChildren
/endChildren
-각 어린이 목록의 시작과 끝. 이RecursiveListIterator
함수 호출의 형태로만 이러한 이벤트를 제공합니다. 목록에서 일반적으로 사용되는 마이너스 목록은<ul><li>
부모<li>
요소 내에서 열리고 닫힘 . 따라서endElement
이벤트는 해당 이벤트가 시작endChildren
됩니다. 이 클래스의 사용을 확대하기 위해 변경하거나 구성 할 수 있습니다. 이벤트는 데코레이터 객체에 대한 함수 호출로 배포되어 사물을 분리합니다.
ListDecorator
-의 이벤트를 수신하는 "장식 자"클래스입니다RecursiveListIterator
.
메인 출력부터 시작합니다. 이제 계층 적 $tree
배열을 취하면 최종 코드는 다음과 달라집니다.
$root = new TreeNode($tree);
$it = new TreeNodesIterator(array($root));
$rit = new RecursiveListIterator($it);
$decor = new ListDecorator($rit);
$rit->addDecorator($decor);
foreach($rit as $item)
{
$inset = $decor->inset(1);
printf("%s%s\n", $inset, $item->getName());
}
먼저 및 요소 ListDecorator
를 단순히 래핑 하고 목록 구조가 출력되는 방식을 결정 하는를 살펴 보겠습니다.<ul>
<li>
class ListDecorator
{
private $iterator;
public function __construct(RecursiveListIterator $iterator)
{
$this->iterator = $iterator;
}
public function inset($add = 0)
{
return str_repeat(' ', $this->iterator->getDepth()*2+$add);
}
생성자는 작업중 인 목록을 사용합니다. inset
출력의 좋은 들여 쓰기를위한 도우미 함수입니다. 나머지는 각 이벤트에 대한 출력 함수입니다.
public function beginElement()
{
printf("%s<li>\n", $this->inset());
}
public function endElement()
{
printf("%s</li>\n", $this->inset());
}
public function beginChildren()
{
printf("%s<ul>\n", $this->inset(-1));
}
public function endChildren()
{
printf("%s</ul>\n", $this->inset(-1));
}
public function beginIteration()
{
printf("%s<ul>\n", $this->inset());
}
public function endIteration()
{
printf("%s</ul>\n", $this->inset());
}
}
여기서는 다음과 같이 주요 출력 마무리 / 루프 단계별로 진행합니다.
$root = new TreeNode($tree);
TreeNode
반복을 시작하는 데 사용할 루트 를 만듭니다 .
$it = new TreeNodesIterator(array($root));
이것은 단일 노드 에 대한 재귀 적 반복을 가능하게 TreeNodesIterator
하는 것 RecursiveIterator
입니다 $root
. 이 클래스는 반복 할 수 있기 때문에 필요하고 TreeNode
요소 의 배열이기도 한 하위 집합과 함께 할 수 있기 때문에 배열로 전달 됩니다.
$rit = new RecursiveListIterator($it);
이것은 RecursiveListIterator
는 RecursiveIteratorIterator
상기 이벤트를 제공한다. 그것을 사용하기 위해 하나만 ListDecorator
제공되고 (위의 클래스) 다음과 같이 할당됩니다 addDecorator
:
$decor = new ListDecorator($rit);
$rit->addDecorator($decor);
그런 다음 모든 것이 설정되어 각 foreach
노드를 출력합니다.
foreach($rit as $item)
{
$inset = $decor->inset(1);
printf("%s%s\n", $inset, $item->getName());
}
이 예제에서 볼 수 전체 출력 논리는 ListDecorator
클래스 와이 단일 foreach
. 전체 재귀 순회는 스택 프로 시저를 제공하는 SPL 재귀 반복으로 캡슐화되었습니다. 이는 내부적으로 재귀 호출 함수가 수행되지 않음을 의미합니다.
이벤트 기반을 ListDecorator
사용하면 예시에 대해 수정하고 동일한 데이터 구조를 제공 할 수 있습니다. 배열 데이터가에 캡슐화되어 있습니다 TreeNode
.
전체 코드 예 :
<?php
namespace My;
$tree = array('H' => 'G', 'F' => 'G', 'G' => 'D', 'E' => 'D', 'A' => 'E', 'B' => 'C', 'C' => 'E', 'D' => null);
// add children to parents
$flat = array(); # temporary array
foreach ($tree as $name => $parent)
{
$flat[$name]['name'] = $name; # self
if (NULL === $parent)
{
# no parent, is root element, assign it to $tree
$tree = &$flat[$name];
}
else
{
# has parent, add self as child
$flat[$parent]['children'][] = &$flat[$name];
}
}
unset($flat);
class TreeNode
{
protected $data;
public function __construct(array $element)
{
if (!isset($element['name']))
throw new InvalidArgumentException('Element has no name.');
if (isset($element['children']) && !is_array($element['children']))
throw new InvalidArgumentException('Element has invalid children.');
$this->data = $element;
}
public function getName()
{
return $this->data['name'];
}
public function hasChildren()
{
return isset($this->data['children']) && count($this->data['children']);
}
/**
* @return array of child TreeNode elements
*/
public function getChildren()
{
$children = $this->hasChildren() ? $this->data['children'] : array();
$class = get_called_class();
foreach($children as &$element)
{
$element = new $class($element);
}
unset($element);
return $children;
}
}
class TreeNodesIterator implements \RecursiveIterator
{
private $nodes;
public function __construct(array $nodes)
{
$this->nodes = new \ArrayIterator($nodes);
}
public function getInnerIterator()
{
return $this->nodes;
}
public function getChildren()
{
return new TreeNodesIterator($this->nodes->current()->getChildren());
}
public function hasChildren()
{
return $this->nodes->current()->hasChildren();
}
public function rewind()
{
$this->nodes->rewind();
}
public function valid()
{
return $this->nodes->valid();
}
public function current()
{
return $this->nodes->current();
}
public function key()
{
return $this->nodes->key();
}
public function next()
{
return $this->nodes->next();
}
}
class RecursiveListIterator extends \RecursiveIteratorIterator
{
private $elements;
/**
* @var ListDecorator
*/
private $decorator;
public function addDecorator(ListDecorator $decorator)
{
$this->decorator = $decorator;
}
public function __construct($iterator, $mode = \RecursiveIteratorIterator::SELF_FIRST, $flags = 0)
{
parent::__construct($iterator, $mode, $flags);
}
private function event($name)
{
// event debug code: printf("--- %'.-20s --- (Depth: %d, Element: %d)\n", $name, $this->getDepth(), @$this->elements[$this->getDepth()]);
$callback = array($this->decorator, $name);
is_callable($callback) && call_user_func($callback);
}
public function beginElement()
{
$this->event('beginElement');
}
public function beginChildren()
{
$this->event('beginChildren');
}
public function endChildren()
{
$this->testEndElement();
$this->event('endChildren');
}
private function testEndElement($depthOffset = 0)
{
$depth = $this->getDepth() + $depthOffset;
isset($this->elements[$depth]) || $this->elements[$depth] = 0;
$this->elements[$depth] && $this->event('endElement');
}
public function nextElement()
{
$this->testEndElement();
$this->event('{nextElement}');
$this->event('beginElement');
$this->elements[$this->getDepth()] = 1;
}
public function beginIteration()
{
$this->event('beginIteration');
}
public function endIteration()
{
$this->testEndElement();
$this->event('endIteration');
}
}
class ListDecorator
{
private $iterator;
public function __construct(RecursiveListIterator $iterator)
{
$this->iterator = $iterator;
}
public function inset($add = 0)
{
return str_repeat(' ', $this->iterator->getDepth()*2+$add);
}
public function beginElement()
{
printf("%s<li>\n", $this->inset(1));
}
public function endElement()
{
printf("%s</li>\n", $this->inset(1));
}
public function beginChildren()
{
printf("%s<ul>\n", $this->inset());
}
public function endChildren()
{
printf("%s</ul>\n", $this->inset());
}
public function beginIteration()
{
printf("%s<ul>\n", $this->inset());
}
public function endIteration()
{
printf("%s</ul>\n", $this->inset());
}
}
$root = new TreeNode($tree);
$it = new TreeNodesIterator(array($root));
$rit = new RecursiveListIterator($it);
$decor = new ListDecorator($rit);
$rit->addDecorator($decor);
foreach($rit as $item)
{
$inset = $decor->inset(2);
printf("%s%s\n", $inset, $item->getName());
}
출력 :
<ul>
<li>
D
<ul>
<li>
G
<ul>
<li>
H
</li>
<li>
F
</li>
</ul>
</li>
<li>
E
<ul>
</li>
<li>
A
</li>
<li>
C
<ul>
<li>
B
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
변형은 가능한 RecursiveIterator
모든 이벤트를 반복하고 발생할 수있는 모든 이벤트에 대해 반복을 제공하는 반복기입니다 . 그러면 foreach 루프 내의 스위치 / 케이스가 이벤트를 처리 할 수 있습니다.
관련 :
음, 먼저 키-값 쌍의 직선 배열을 배열로 바꿉니다.
function convertToHeiarchical(array $input) {
$parents = array();
$root = array();
$children = array();
foreach ($input as $item) {
$parents[$item['id']] = &$item;
if ($item['parent_id']) {
if (!isset($children[$item['parent_id']])) {
$children[$item['parent_id']] = array();
}
$children[$item['parent_id']][] = &$item;
} else {
$root = $item['id'];
}
}
foreach ($parents as $id => &$item) {
if (isset($children[$id])) {
$item['children'] = $children[$id];
} else {
$item['children'] = array();
}
}
return $parents[$root];
}
그러면 parent_id 및 id가있는 플랫 배열을 계층 구조로 변환 할 수 있습니다.
$item = array(
'id' => 'A',
'blah' => 'blah',
'children' => array(
array(
'id' => 'B',
'blah' => 'blah',
'children' => array(
array(
'id' => 'C',
'blah' => 'blah',
'children' => array(),
),
),
'id' => 'D',
'blah' => 'blah',
'children' => array(
array(
'id' => 'E',
'blah' => 'blah',
'children' => array(),
),
),
),
),
);
그런 다음 함수를 만듭니다.
function renderItem($item) {
$out = "Your OUtput For Each Item Here";
$out .= "<ul>";
foreach ($item['children'] as $child) {
$out .= "<li>".renderItem($child)."</li>";
}
$out .= "</ul>";
return $out;
}
하지만 알렉산더-콘스탄티노 프 의 솔루션은 처음에는 쉽게 읽을 수 없습니다 수도 있습니다, 그것은 천재 기하 급수적으로 더 나은 성능의도에서,이 있었어야 최고의 답변으로 투표를 모두입니다.
감사합니다 친구,이 게시물에 제시된 두 가지 솔루션을 비교하기 위해 벤치 마크를 만들었습니다.
나는 변환해야하는 6 개의 레벨을 가진 250k 플랫 트리를 가지고 더 나은 방법을 찾고 재귀 반복을 피했습니다.
재귀 대 참조 :
// Generate a 6 level flat tree
$root = null;
$lvl1 = 13;
$lvl2 = 11;
$lvl3 = 7;
$lvl4 = 5;
$lvl5 = 3;
$lvl6 = 1;
$flatTree = [];
for ($i = 1; $i <= 450000; $i++) {
if ($i % 3 == 0) { $lvl5 = $i; $flatTree[$lvl6] = $lvl5; continue; }
if ($i % 5 == 0) { $lvl4 = $i; $flatTree[$lvl5] = $lvl4; continue; }
if ($i % 7 == 0) { $lvl3 = $i; $flatTree[$lvl3] = $lvl2; continue; }
if ($i % 11 == 0) { $lvl2 = $i; $flatTree[$lvl2] = $lvl1; continue; }
if ($i % 13 == 0) { $lvl1 = $i; $flatTree[$lvl1] = $root; continue; }
$lvl6 = $i;
}
echo 'Array count: ', count($flatTree), PHP_EOL;
// Reference function
function treeByReference($flatTree)
{
$flat = [];
$tree = [];
foreach ($flatTree as $child => $parent) {
if (!isset($flat[$child])) {
$flat[$child] = [];
}
if (!empty($parent)) {
$flat[$parent][$child] =& $flat[$child];
} else {
$tree[$child] =& $flat[$child];
}
}
return $tree;
}
// Recursion function
function treeByRecursion($flatTree, $root = null)
{
$return = [];
foreach($flatTree as $child => $parent) {
if ($parent == $root) {
unset($flatTree[$child]);
$return[$child] = treeByRecursion($flatTree, $child);
}
}
return $return ?: [];
}
// Benchmark reference
$t1 = microtime(true);
$tree = treeByReference($flatTree);
echo 'Reference: ', (microtime(true) - $t1), PHP_EOL;
// Benchmark recursion
$t2 = microtime(true);
$tree = treeByRecursion($flatTree);
echo 'Recursion: ', (microtime(true) - $t2), PHP_EOL;
출력은 다음과 같이.
Array count: 255493
Reference: 0.3259289264679 (less than 0.4s)
Recursion: 6604.9865279198 (almost 2h)
UL 및 LI로 구문 분석 예측 다음과 같습니다.
$array = array (
'H' => 'G'
'F' => 'G'
'G' => 'D'
'E' => 'D'
'A' => 'E'
'B' => 'C'
'C' => 'E'
'D' => 'NULL'
);
recurse_uls ($array, 'NULL');
function recurse_uls ($array, $parent)
{
echo '<ul>';
foreach ($array as $c => $p) {
if ($p != $parent) continue;
echo '<li>'.$c.'</li>';
recurse_uls ($array, $c);
}
echo '</ul>';
}
하지만 어레이를 자주 반복 할 필요가없는 솔루션을보고 싶습니다.
내가 생각하는 것은 다음과 가변적이다.
$arr = array(
'H' => 'G',
'F' => 'G',
'G' => 'D',
'E' => 'D',
'A' => 'E',
'B' => 'C',
'C' => 'E',
'D' => null );
$nested = parentChild($arr);
print_r($nested);
function parentChild(&$arr, $parent = false) {
if( !$parent) { //initial call
$rootKey = array_search( null, $arr);
return array($rootKey => parentChild($arr, $rootKey));
}else { // recursing through
$keys = array_keys($arr, $parent);
$piece = array();
if($keys) { // found children, so handle them
if( !is_array($keys) ) { // only one child
$piece = parentChild($arr, $keys);
}else{ // multiple children
foreach( $keys as $key ){
$piece[$key] = parentChild($arr, $key);
}
}
}else {
return $parent; //return the main tag (no kids)
}
return $piece; // return the array built via recursion
}
}
출력 :
Array
(
[D] => Array
(
[G] => Array
(
[H] => H
[F] => F
)
[E] => Array
(
[A] => A
[C] => Array
(
[B] => B
)
)
)
)
동적 트리보기 및 메뉴를 만드는 방법
1 단계 : 먼저 mysql 데이터베이스에 트 리뷰 테이블을 생성합니다. 이 테이블에는 4 개의 열이 있습니다. .id는 작업 ID이고 이름은 작업 이름입니다.
-
-- Table structure for table `treeview_items`
--
CREATE TABLE IF NOT EXISTS `treeview_items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`title` varchar(200) NOT NULL,
`parent_id` varchar(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
--
-- Dumping data for table `treeview_items`
--
INSERT INTO `treeview_items` (`id`, `name`, `title`, `parent_id`) VALUES
(1, 'task1', 'task1title', '2'),
(2, 'task2', 'task2title', '0'),
(3, 'task3', 'task1title3', '0'),
(4, 'task4', 'task2title4', '3'),
(5, 'task4', 'task1title4', '3'),
(6, 'task5', 'task2title5', '5');
2 단계 : 트리 뷰 재귀 메서드 아래에 트리 createTreeView () 메서드를 만들었습니다.이 메서드는 현재 작업 ID가 이전 작업 ID보다 크면 재귀를 호출합니다.
function createTreeView($array, $currentParent, $currLevel = 0, $prevLevel = -1) {
foreach ($array as $categoryId => $category) {
if ($currentParent == $category['parent_id']) {
if ($currLevel > $prevLevel) echo " <ol class='tree'> ";
if ($currLevel == $prevLevel) echo " </li> ";
echo '<li> <label for="subfolder2">'.$category['name'].'</label> <input type="checkbox" name="subfolder2"/>';
if ($currLevel > $prevLevel) { $prevLevel = $currLevel; }
$currLevel++;
createTreeView ($array, $categoryId, $currLevel, $prevLevel);
$currLevel--;
}
}
if ($currLevel == $prevLevel) echo " </li> </ol> ";
}
3 단계 : 보안 파일을 만들어 트리보기를 표시합니다. 이것은 트 리뷰 예제의 메인 파일입니다. 여기에서 필요한 매개 변수로 createTreeView () 메소드를 호출합니다.
<body>
<link rel="stylesheet" type="text/css" href="_styles.css" media="screen">
<?php
mysql_connect('localhost', 'root');
mysql_select_db('test');
$qry="SELECT * FROM treeview_items";
$result=mysql_query($qry);
$arrayCategories = array();
while($row = mysql_fetch_assoc($result)){
$arrayCategories[$row['id']] = array("parent_id" => $row['parent_id'], "name" =>
$row['name']);
}
?>
<div id="content" class="general-style1">
<?php
if(mysql_num_rows($result)!=0)
{
?>
<?php
createTreeView($arrayCategories, 0); ?>
<?php
}
?>
</div>
</body>
4 단계 : CSS 파일 style.css 만들기 여기에서는 모든 CSS 관련 클래스를 작성합니다. 현재 주문 목록을 사용하여 트리보기를 만들 수 있습니다. 여기에서 이미지 경로를 설명 수도 있습니다.
img { border: none; }
input, select, textarea, th, td { font-size: 1em; }
/* CSS Tree menu styles */
ol.tree
{
padding: 0 0 0 30px;
width: 300px;
}
li
{
position: relative;
margin-left: -15px;
list-style: none;
}
li.file
{
margin-left: -1px !important;
}
li.file a
{
background: url(document.png) 0 0 no-repeat;
color: #fff;
padding-left: 21px;
text-decoration: none;
display: block;
}
li.file a[href *= '.pdf'] { background: url(document.png) 0 0 no-repeat; }
li.file a[href *= '.html'] { background: url(document.png) 0 0 no-repeat; }
li.file a[href $= '.css'] { background: url(document.png) 0 0 no-repeat; }
li.file a[href $= '.js'] { background: url(document.png) 0 0 no-repeat; }
li input
{
position: absolute;
left: 0;
margin-left: 0;
opacity: 0;
z-index: 2;
cursor: pointer;
height: 1em;
width: 1em;
top: 0;
}
li input + ol
{
background: url(toggle-small-expand.png) 40px 0 no-repeat;
margin: -0.938em 0 0 -44px; /* 15px */
height: 1em;
}
li input + ol > li { display: none; margin-left: -14px !important; padding-left: 1px; }
li label
{
background: url(folder-horizontal.png) 15px 1px no-repeat;
cursor: pointer;
display: block;
padding-left: 37px;
}
li input:checked + ol
{
background: url(toggle-small.png) 40px 5px no-repeat;
margin: -1.25em 0 0 -44px; /* 20px */
padding: 1.563em 0 0 80px;
height: auto;
}
li input:checked + ol > li { display: block; margin: 0 0 0.125em; /* 2px */}
li input:checked + ol > li:last-child { margin: 0 0 0.063em; /* 1px */ }
'IT' 카테고리의 다른 글
React Router 4에서 인증 된 경로를 구현하는 방법은 무엇입니까? (0) | 2020.08.26 |
---|---|
Rails에 대한 착각의 최첨단은 무엇입니까? (0) | 2020.08.26 |
임시 분산 쿼리를 활성화하는 방법 (0) | 2020.08.26 |
할당 왼쪽의 자바 개체 대괄호 표기법 ({Navigation} =) (0) | 2020.08.26 |
Objective-C에서 클래스의 인스턴스를 @protocol로 캐스트 (0) | 2020.08.26 |