单击<p:子菜单>本身时,立即导航到第一个<p:menuitem> </p:submenu> </p:menuitem>

时间:2014-04-04 21:00:16

标签: javascript jquery jsf primefaces

我有一个动态<p:menubar>如下。

<p:menubar style="position: relative; height: 30px; visibility: visible;">
    <p:submenu label="Category" icon="ui-icon-document" styleClass="mainMenu">
        <c:forEach var="row" items="#{parentMenuManagedBean.category}">
            <p:submenu label="#{row.catName}" icon="ui-icon-contact" styleClass="subMenu">
                <c:forEach var="subRow" items="#{row.subCategoryList}">
                    <p:menuitem value="#{subRow.subCatName}" url="ProductDetails.jsf?subCatId=#{subRow.subCatId}"/>
                </c:forEach>
            </p:submenu>
        </c:forEach>
    </p:submenu>
</p:menubar>
<{1}}内的</p:submenu>不可点击。

有一些CSS类绑定到JavaScript函数。单击这些</p:menubar>时,将调用以下函数。

<p:submenu>

但是当点击最内层$(function(){ $(".mainMenu").bind("click", function(){ alert("mainMenu was clicked"); }); }); $(function(){ $(".subMenu").bind("click", function(){ alert("subMenu was clicked"); }); }); 时,这两个函数都被调用,不应该发生。

如何在点击每个<p:submenu>时唯一标识每个<p:submenu>

有没有办法传递一些值,以便可以唯一地识别它们,就像追加到URL的查询字符串一样?

2 个答案:

答案 0 :(得分:5)

  

但是当点击最内层<p:submenu>时,这两个函数都被调用,不应该发生。

您是event bubbling的受害者。在所有浏览器中,当DOM元素接收事件时,这是在对传播给其所有父节点的当前元素进行处理之后。它们的所有事件侦听器(如果有的话)也会被调用,除非您从当前侦听器函数中return false,或者通过调用event.stopPropagation()显式停止传播并像往常一样从函数返回。与return false的区别在于仍然会执行当前元素(转到给定URL)的click事件的默认操作。


  

如何在点击每个<p:submenu>时唯一标识每个this

负责触发事件的DOM元素位于$()可用的侦听器中。您只需使用<p:submenu>构建它,就可以将其进一步包装到jQuery对象中。如果是<li>,则该<{1}}元素将成为子<a>元素。


  

有没有办法传递一些值,以便可以唯一地识别它们,就像追加到URL的查询字符串一样?

通常,您可以更好地探索DOM元素本身。例如,通过检查子<a>元素的文本内容。


总而言之,这里是重写,请注意event对象可用作第一个函数参数:

$(document).on("click", ".mainMenu", function() {
    console.log("mainMenu was clicked");
});
$(document).on("click", ".subMenu", function(event) {
    event.stopPropagation(); // Stop event bubbling.
    var $this = $(this); // That's the <li> element.
    var $link = $this.children("a"); // That's the immediate child <a> element.
    var label = $link.text(); // You could use it to identify the submenu.
    // ...
    console.log("subMenu with label " + label + " was clicked");
});

(请注意,我还将$(function(){})$.bind()替换为$(document).on(),这样可以安全地防止ajax请求中的DOM更新;您不需要然后重新执行整个脚本)


更新:根据评论,具体的功能要求,从最初的问题(我现在已经改进了问题标题)开始并不清楚,是单击子菜单本身时,导航到与菜单的第一项相同的URL。在这种情况下,您最好直接通过<a>选择器连接子菜单的.subMenu>a元素,并在菜单的网址上执行window.location&#39} ; s第一个<a>元素。这是另一个重写:

$(document).on("click", ".subMenu>a", function() {
    var $this = $(this); // That's the submenu's <a> element itself.
    var $link = $this.next().find("a:first"); // That's menu's first <a> element.
    var url = $link.attr("href"); // The URL of that link.
    // ...
    window.location = url; // It'll change the document immediately. No need to stop propagation.
});

答案 1 :(得分:1)

你需要使用stopPropagation

$( ".subMenu").click(function( event ) {
    event.stopPropagation();
    // Do something
});

这将阻止家长收到有关该事件的通知。

选中此http://api.jquery.com/event.stoppropagation/