日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php实现父子评论,关于php:将一系列父子关系转换为层次树?

發布時間:2024/9/27 php 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php实现父子评论,关于php:将一系列父子关系转换为层次树? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

s?

我感覺涉及到遞歸,但是我還沒有足夠清醒地思考它。

這需要一個非常基本的遞歸函數來將子/父對解析為樹結構,并需要另一個遞歸函數來將其打印出來。只有一個函數就足夠了,但是為了清楚起見,這里有兩個(可以在此答案的末尾找到一個組合函數)。

首先初始化子對/父對對的數組:

$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 '

';

foreach($tree as $node) {

echo '

'.$node['name'];

printTree($node['children']);

echo '

';

}

echo '

';

}

}

以及實際用法:

$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 '

';

foreach($tree as $child => $parent) {

if($parent == $root) {

unset($tree[$child]);

echo '

'.$child;

parseAndPrintTree($child, $tree);

echo '

';

}

}

echo '

';

}

}

您只會在這樣小的數據集上保存8次迭代,但在較大的數據集上可能會有所作為。

塔圖如何更改printTree函數以不直接回顯樹html,而是將所有輸出html保存到變量中并返回?謝謝

嗨,我認為函數聲明必須為parseAndPrintTree($ tree,$ root = null),遞歸調用應為parseAndPrintTree($ child,$ tree);最好的祝福

生成樹的另一個功能(不涉及遞歸,而是使用引用):

$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列表。

+1-非常聰明。盡管我發現遞歸解決方案更合乎邏輯。但我確實更喜歡您函數的輸出格式。

@Eric更合乎邏輯嗎?我不敢茍同。遞歸沒有邏輯性; OTOH在解析遞歸函數/調用時存在嚴重的認知開銷。如果沒有顯式的堆棧分配,則ID每天都會在遞歸上進行迭代。

將$tree中的平面結構轉換為層次結構的另一種更簡化的方法。只需一個臨時數組即可公開它:

好。

// add children to parents

$flat = array(); # temporary arrayforeach ($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"難題"。難題是,每個項目都不知道孩子是否會跟進或需要關閉多少個前面的元素。在另一個答案中,我已經通過使用RecursiveIteratorIterator并查找getDepth()和我自己編寫的Iterator提供的其他元信息來解決該問題:將嵌套集合模型放入

中,但隱藏"閉合"子樹。該答案還表明,使用迭代器可以使您非常靈活。

好。

但是,這是一個預先排序的列表,因此不適合您的示例。另外,我一直想為一種標準的樹形結構以及HTML的

元素解決此問題。

好。

我提出的基本概念如下:

好。

TreeNode-將每個元素抽象為簡單的TreeNode類型,可以提供其值(例如Name)以及是否具有子元素。

TreeNodesIterator-一個能夠遍歷這些TreeNodes的集合(數組)的RecursiveIterator。這非常簡單,因為TreeNode類型已經知道它是否有子級以及哪些子級。

RecursiveListIterator-一個RecursiveIteratorIterator,具有在任何RecursiveIterator上遞歸地迭代時所需的所有事件:

beginIteration / endIteration-主列表的開始和結束。

beginElement / endElement-每個元素的開始和結束。

beginChildren / endChildren-每個子級列表的開始和結束。

此RecursiveListIterator僅以函數調用的形式提供這些事件。子列表(在列表中很常見)在其父元素內打開和關閉。因此,在相應的endChildren事件之后觸發endElement事件。可以對其進行更改或使其可配置,以擴大此類的使用范圍。然后將事件作為對裝飾器對象的函數調用進行分發,以使事情分開。

好。

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

", $inset, $item->getName());

}

首先,讓我們看一下ListDecorator,它只是包裝

元素,并決定如何輸出列表結構:

好。

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

", $this->inset());

}

public function endElement()

{

printf("%s

", $this->inset());

}

public function beginChildren()

{

printf("%s

", $this->inset(-1));

}

public function endChildren()

{

printf("%s

", $this->inset(-1));

}

public function beginIteration()

{

printf("%s

", $this->inset());

}

public function endIteration()

{

printf("%s

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

", $inset, $item->getName());

}

如本示例所示,整個輸出邏輯封裝在ListDecorator類和單個foreach中。整個遞歸遍歷已完全封裝到提供堆棧過程的SPL遞歸迭代器中,這意味著在內部不執行任何遞歸函數調用。

好。

基于事件的ListDecorator允許您專門修改輸出并為同一數據結構提供多種類型的列表。甚至有可能更改輸入,因為數組數據已封裝到TreeNode中。

好。

完整的代碼示例:

好。

命名空間My;

$ tree = array('H'=>'G','F'=>'G','G'=>'D','E'=>'D','A'=>'E', 'B'=>'C','C'=>'E','D'=> null);

//將孩子添加到父母

$ flat = array(); #臨時數組

foreach($ tree作為$ name => $ parent)

{

$ flat [$ name] ['name'] = $ name; #自我

如果(NULL === $ parent)

{

#沒有父級,是根元素,將其分配給$ tree

$ tree =&$ flat [$ name];

}

其他

{

#有父母,將自己添加為孩子

$ flat [$ parent] ['children'] [] =&$ flat [$ name];

}

}

未設置($ flat);

TreeNode類

{

受保護的$ data;

公共功能__construct(array $ element)

{

如果(!isset($ element ['name']))

拋出新的InvalidArgumentException('Element無名字。');

if(isset($ element ['children'])&&!is_array($ element ['children']))

拋出新的InvalidArgumentException('元素具有無效的子代。');

$ this-> data = $ element;

}

公共函數getName()

{

返回$ this-> data ['name'];

}

公共函數hasChildren()

{

返回isset($ this-> data ['children'])&& count($ this-> data ['children']);

}

/ **

* @return子TreeNode元素數組

* /

公共功能getChildren()

{

$ children = $ this-> hasChildren()嗎? $ this-> data ['children']:array();

$ class = get_call_class();

foreach($ children as&$ element)

{

$ element =新的$ class($ element);

}

unset($ element);

返回$ children;

}

}

TreeNodesIterator類實現 recursiveIterator

{

私有$ nodes;

公共功能__construct(array $ nodes)

{

$ this-> nodes = new ?ArrayIterator($ nodes);

}

公共函數getInnerIterator()

{

返回$ this-> nodes;

}

公共功能getChildren()

{

返回新的TreeNodesIterator($ this-> nodes-> current()-> getChildren());

}

公共函數hasChildren()

{

返回$ this-> nodes-> current()-> hasChildren();

}

公共函數rewind()

{

$ this-> nodes-> rewind();

}

公共函數valid()

{

返回$ this-> nodes-> valid();

}

公共函數current()

{

返回$ this-> nodes-> current();

}

公共功能鍵()

{

返回$ this-> nodes-> key();

}

公共功能next()

{

返回$ this-> nodes-> next();

}

}

RecursiveListIterator類擴展 recursiveIteratorIterator

{

私人元素

/ **

* @var ListDecorator

* /

私人裝飾工;

公共功能addDecorator(ListDecorator $ decorator)

{

$ this-> decorator = $ decorator;

}

公共函數__construct($ iterator,$ mode = ?recursiveIteratorIterator :: SELF_FIRST,$ flags = 0)

{

父母:: __ construct($ iterator,$ mode,$ flags);

}

私有函數事件($ name)

{

//事件調試代碼:printf(" ---%'.- 20s ---(深度:%d,元素:%d) n",$ name,$ this-> getDepth(),@ $ this- > elements [$ this-> getDepth()]);

$ callback = array($ this-> decorator,$ name);

is_callable($ callback)&& call_user_func($ callback);

}

公共函數beginElement()

{

$ this-> event('beginElement');

}

公共函數beginChildren()

{

$ this-> event('beginChildren');

}

公共函數endChildren()

{

$ this-> testEndElement();

$ this-> event('endChildren');

}

私有函數testEndElement($ depthOffset = 0)

{

$ depth = $ this-> getDepth()+ $ depthOffset;

isset($ this-> elements [$ depth])|| $ this-> elements [$ depth] = 0;

$ this-> elements [$ depth] && $ this-> event('endElement');

}

公共功能nextElement()

{

$ this-> testEndElement();

$ this-> event('{nextElement}');

$ this-> event('beginElement');

$ this-> elements [$ this-> getDepth()] = 1;

}

公共函數beginIteration()

{

$ this-> event('beginIteration');

}

公共函數endIteration()

{

$ this-> testEndElement();

$ this-> event('endIteration');

}

}

ListDecorator類

{

私人$ iterator;

公共函數__construct(RecursiveListIterator $ iterator)

{

$ this-> iterator = $ iterator;

}

公共函數插入($ add = 0)

{

return str_repeat('',$ this-> iterator-> getDepth()* 2 + $ add);

}

公共函數beginElement()

{

printf("%s

n",$ this-> inset(1));

}

公共功能endElement()

{

printf("%s

n",$ this-> inset(1));

}

公共函數beginChildren()

{

printf("%s

n",$ this-> inset());

}

公共函數endChildren()

{

printf("%s

n",$ this-> inset());

}

公共函數beginIteration()

{

printf("%s

n",$ this-> inset());

}

公共函數endIteration()

{

printf("%s

n",$ this-> inset());

}

}

$ root = new TreeNode($ tree);

$ it =新的TreeNodesIterator(array($ root));

$ rit =新的RecursiveListIterator($ it);

$ decor =新的ListDecorator($ rit);

$ rit-> addDecorator($ decor);

foreach($ rit作為$ item)

{

$ inset = $ decor-> inset(2);

printf("%s%s ?n",$ inset,$ item-> getName());

}

code> pre>

輸出:

[cc lang="php"]

D

G

H

F

E

A

C

B

演示(PHP 5.2變體)

好。

一個可能的變體是迭代器,它迭代任何RecursiveIterator并為可能發生的所有事件提供迭代。然后,在foreach循環內的一個switch / case可以處理事件。

好。

有關:

好。

使用RecursiveArrayIterator的嵌套列表

RecursiveIteratorIterator類

好。

好。

此解決方案的設計精良-與前面的示例相比,"簡化方式"到底有多精確-似乎是針對同一問題的過度設計的解決方案

@Andre:按封裝IIRC的等級劃分。在另一個相關的答案中,我有一個完全未封裝的代碼片段,該片段非常小,因此可能會根據POV進行"更簡化"。

@hakre如何修改" ListDecorator"類以將ID添加到從樹數組中獲取的LI?

@Gangesh:使用節點訪問者最容易。 ^^開個玩笑,直截了當是擴展裝飾器并編輯beginElement(),獲取內部迭代器(有關示例,請參見inset()方法)以及具有id屬性的工作。

@hakre謝謝。虐待嘗試。

好吧,首先,我將鍵值對的直接數組轉換為層次結構數組

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

";

foreach ($item['children'] as $child) {

$out .="

".renderItem($child)."

";

}

$out .="

";

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)

這是我想出的:

$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

)

)

)

)

好吧,要解析為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 '

';

foreach ($array as $c => $p) ?{

if ($p != $parent) continue;

echo '

'.$c.'

';

recurse_uls ($array, $c);

}

echo '

';

}

但是我很樂意看到一個不需要您如此頻繁地遍歷數組的解決方案...

如何創建動態樹視圖和菜單

步驟1:首先,我們將在mysql數據庫中創建treeview表。該表包含四個column.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" ";

if ($currLevel == $prevLevel) echo"

";

echo '

'.$category['name'].' ';

if ($currLevel > $prevLevel) { $prevLevel = $currLevel; }

$currLevel++;

createTreeView ($array, $categoryId, $currLevel, $prevLevel);

$currLevel--;

}

}

if ($currLevel == $prevLevel) echo"

";

}

步驟3:創建索引文件以顯示樹視圖。

這是treeview示例的主文件,在這里,我們將使用必需的參數調用createTreeView()方法。

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']);

}

?>

if(mysql_num_rows($result)!=0)

{

?>

createTreeView($arrayCategories, 0); ?>

}

?>

步驟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 */ }

更多細節

總結

以上是生活随笔為你收集整理的php实现父子评论,关于php:将一系列父子关系转换为层次树?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。