为什么这个jQuery不会影响从PHP输出的元素,只有HTML中定义的元素?
I'm trying to make a dynamic nav menu similar to this. The javascript is here and worked perfectly when I tested it with:
<div id='nav'>
<ul>
<li class="navHeader">OOC</li>
<li><a href='#'>Home</a></li>
<li class='active'><a href='#'>Products</a>
<ul>
<li><a href='#'>Product 1</a>
<ul>
<li><a href='#'>Sub Product</a></li>
<li><a href='#'>Sub Product</a></li>
</ul>
</li>
<li><a href='#'>Product 2</a>
<ul>
<li><a href='#'>Sub Product</a></li>
<li><a href='#'>Sub Product</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
However, I tried to switch the content of the nav to this:
<div id='nav'>
<ul>
<li class="navHeader">OOC</li>
<?php echo getNav(); ?>
</ul>
</div>
PHP:
function formatNav($navPg){
$navLine = "<li><a href='?pg=".$navPg['url']."'>".$navPg['name']."</a></li>";
if ($navPg['subPgs'] > 0) {
$navLine .= "<ul>";
foreach($navPg['subPgs'] as $subPg) {
$navLine .= formatNav($subPg);
}
$navLine .= "</ul>";
}
return $navLine;
}
function getNav(){
$navPgs = array(array(
'name'=>'profile',
'url'=>'profile',
'subPgs'=>array(
array(
'name'=>'subaccounts',
'url'=>'profile&cat=subs',
'subPgs'=>''
),
array(
'name'=>'options',
'url'=>'profile&cat=opts',
'subPgs'=>''
)
)
)
);
$finalNav = "";
foreach($navPgs as $navPg){
$finalNav .= formatNav($navPg);
}
return $finalNav;
}
And none of the Javascript runs on it.
The JS doesn't add the class has-sub
to the li
elements that have submenus. Elements with has-sub
added in the PHP display their CSS properly but don't perform the dropdown event. I debugged the list of <ul>
elements found after cssmenu.find('li ul').parent().addClass('has-sub');
in the JS, and it doesn't include the PHP-generated ones.
I debugged the PHP output, and it's a perfect set of li and ul elements as if I'd formatted them by hand. The JS works fine by itself, the PHP works fine by itself, but when I try to combine them, the JS fails.
Somebody had the same problem here, but the answers aren't helpful. I can change my implementation to build the list elements dynamically in javascript based on a JSON list of qualities about it, but I want to know why I have to do that instead of echoing them out from PHP directly, especially if there's a more direct workaround.
Is the PHP running after $(document).ready
fires somehow even though it runs server-side?
JS runs client-side, but valid DOM elements outputted from server-side scripts should be indistinguishable from ones created client-side. Right?
Why isn't this?
edit: Pictures of output from the PHP by itself. Nothing seems wrong with it.
The function is not generating the same structure, which could be the issue.
I've tweaked your function to return the same structure, as your working one.
Give it a try.
<?php
function formatNav($navPg){
$navLine = "<li><a href='".$navPg['url']."'>".$navPg['name']."</a>";
if (is_array($navPg['subPgs']) && count($navPg['subPgs']) > 0) {
$navLine .= "<ul>";
foreach($navPg['subPgs'] as $subPg) {
$navLine .= formatNav($subPg);
}
$navLine .= "</ul>";
} else {
$navLine .= "</li>";
}
if (is_array($navPg['subPgs']) && count($navPg['subPgs']) > 0) {
$navLine .= "</li>";
}
return $navLine;
}
function getNav(){
$navPgs = array(
array(
'name'=>'Home',
'url'=>'#',
'subPgs'=>array()
),
array(
'name'=>'Products',
'url'=>'#',
'subPgs'=>array(
array(
'name'=>'Product 1',
'url'=>'#',
'subPgs'=>array(
array(
'name'=>'Sub Product',
'url'=>'#',
'subPgs'=>array()
),array(
'name'=>'Sub Product',
'url'=>'#',
'subPgs'=>array()
),
)
),
array(
'name'=>'Product 2',
'url'=>'#',
'subPgs'=>array(
array(
'name'=>'Sub Product',
'url'=>'#',
'subPgs'=>array()
),array(
'name'=>'Sub Product',
'url'=>'#',
'subPgs'=>array()
),
)
)
)
)
);
$finalNav = "";
foreach($navPgs as $navPg){
$finalNav .= formatNav($navPg);
}
return $finalNav;
}
<div id='nav'>
<ul>
<li class="navHeader">OOC</li>
<li><a href='#'>Home</a></li>
<li>
<a href='#'>Products</a>
<ul>
<li>
<a href='#'>Product 1</a>
<ul>
<li><a href='#'>Sub Product</a></li>
<li><a href='#'>Sub Product</a></li>
</ul>
</li>
<li>
<a href='#'>Product 2</a>
<ul>
<li><a href='#'>Sub Product</a></li>
<li><a href='#'>Sub Product</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>