JQuery contextmenu不在附加元素上工作

时间:2016-05-18 01:45:56

标签: javascript jquery

JSFiddle Demo

在我的邮件侧导航中,我有一个自定义的右键单击劫持,我刚刚创建它,因此您可以添加一个新的子文件夹,如下所示;

if ($(this).hasClass('NewSubFolder')) {
    if($('ul.inbox-nav li.Clicked').find('ul').length) {
        $('ul.inbox-nav li.Clicked > ul').prepend("<li class='NewSubFolder'><input type='text'></li>");
    } else {
        $('ul.inbox-nav li.Clicked').append('<ul><li class="NewSubFolder"><input type="text"></li></ul>');
    }
    $("ul.inbox-nav li.Clicked").removeClass('Clicked');
}

这将添加另一个层,其中没有一个可以在前面添加一个输入字段。目前,你必须在为新文件夹名称键入内容后点击回车键,然后它才能发挥其魔力......

...但是,当您右键单击它时,这个新附加的列表项不起作用。

2 个答案:

答案 0 :(得分:0)

您可以使用.contextmenu()覆盖右侧行为。

$('.NewSubFolder').contextmenu(function() {
  console.log("Right clic detected!");
});

此处的文档:https://api.jquery.com/contextmenu/

我希望它有所帮助! :)

答案 1 :(得分:0)

希望这能满足您的需求。

如果评论不够明确,请告诉我。

修改

进行编辑以将两个on(contextmenu)调用合并为一个函数。无需冗余。

$(document).ready(function() {

  // Trigger action when the contexmenu is about to be shown
  $('#inbox-nav').on("contextmenu", 'a', function(event) {

    event.preventDefault();
    $('.clicked').removeClass('clicked'); //Gets rid of all other clicked elements
    $(this).closest('li').addClass('clicked');
    //Clicks the closest li element
    var menu = ($(this).is('#inbox-nav>li>a')) ? 'MailMenuFirstTier' : 'MailMenuSecondTier';
    /*This is an inline if statement, read in words it goes like this:
      if this element is a direct level link, then we're going to need to use the first menu tier.
      else we're going to need use the second menu tier.
    */

    $("#" + menu).finish().show(100)
      //dynamically calls the menu we're using.
      .css({
        left: event.pageX,
        top: event.pageY
      }); //Moves the first mail menu to the event position

  });
  /*
    check the element to see which menut to show instead of using two different things.
  */
  $(document).on('mousedown', function(e) {
    //Mouse down events!
    if ($('.custom-menu').is(':visible') && !$(e.target).parent().hasClass('custom-menu')) {
      /*
      In English:
        if a custom menu is visible, AND the target of the click DOES NOT have the custom-menu class, hide the custom menu.
      */
      $('.custom-menu').finish().hide();
    }

    if ($(e.target).parent().hasClass('custom-menu')) {
      //Figure out what to do since your element is a child of the custom menu
      $('.custom-menu').finish().hide();

      var action = $(e.target).data('action');
      //Gets our action element
      var clicked = $('.clicked');
      //gets the clicked element we will be working on.
      switch (action) {
        case 'new-folder':
          //If the clicked element does not have a child ul element, add one.
          $('input.rename').focusout();
          //Any current input.renames will have their focus out method called
          if (clicked.children('ul').length == 0) {

            clicked.append($('<ul></ul>'))
          }
          var ul = clicked.children('ul');
          //Either this child element existed before or we just made it the step before. 
          var input = $('<input />', {
            type: 'text',
            value: 'New Sub Folder',
            class: 'rename',
            'data-start': 'New Sub Folder',
            focusout: function() {
              var value = ($(this).val() == '') ? $(this).data('start') : $(this).val();
              $(this).siblings('a').html(value).show();
              $(this).remove();
            },
            autofocus: true
          });
          //Creates an input tag of type text, with class rename, a placeholder value, and a focusout function.
          var anchor = $('<a>', {
            href: '#',
            css: {
              display: 'none'
            }
          });
          //Creates an anchor tag that is originally hidden
          ul.append($('<li>').append([input, anchor]));
          ul.find('input').click();
          //Adds the (should be selected) element and the anchor
          //The input element takes care of things from there

          break; // end new-folder case
        case 'rename-folder':
          $('input.rename').focusout();
          //any current input.rename items will have their focusout method called
          var anchor = clicked.find('a');
          //get our closest anchor of our clicked element
          anchor.before($('<input />', {
            type: 'text',
            value: anchor.html(),
            class: 'rename',
            'data-start': anchor.html(),
            focusout: function() {
              var value = ($(this).val() == '') ? $(this).data('start') : $(this).val();
              $(this).siblings('a').html(value).show();
              $(this).remove();
            },
            autofocus: true
          })).hide();

          //Creates an input element, adds it before the anchor element, 
          //hides anchor element. the newly created input element takes care of things from there
          break;
          /*
          ADD NEW ACTIONS HERE
          */
        default:
          return;
          break;
      }
    }
  }).on('keyup', 'input.rename', function(e) {
    //Used for laziness. If a user hits enter in the input.rename tag, we fire the focusout target
    e.preventDefault();
    if (e.keyCode == 13) {
      $(e.target).focusout();
    }
  });
});
.custom-menu {
  display: none;
  z-index: 1000;
  position: absolute;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: hidden;
  border: 1px solid #CCC;
  white-space: nowrap;
  font-family: sans-serif;
  background: #FFF;
  color: #333;
  border-radius: 5px;
  font-size: 12px;
}
.custom-menu li {
  padding: 8px 12px;
  cursor: pointer;
}
.custom-menu li:hover {
  background-color: #DEF;
}
menu {
  position: absolute;
}
.custom-menu .divider {
  content: " ";
  height: 1px;
  margin: 4px 10px;
  background: #929292;
}
#MailBodyList.custom-menu li.Title {
  color: #929292;
}
#MailBodyList.custom-menu li.Title:hover {
  background: #FFF;
  cursor: default;
}
#MailBodyList.custom-menu li.ForThisSenderMore {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="inbox-nav" id="inbox-nav">
  <li class="active">
    <a href="javascript:;" data-type="inbox" data-title="Inbox">
      <div class="Arrow"></div>Inbox
    </a>
    <ul>
      <li><a href="javascript:;" data-type="inbox" data-title="Sub_1">Sub-Folder 1</a>
      </li>
      <li><a href="javascript:;" data-type="inbox" data-title="Sub_2">Sub-Folder 2</a>
      </li>
      <li>
        <a href="javascript:;" data-type="inbox" data-title="Sub_3">Sub-Folder 3</a>
        <ul>
          <li><a href="javascript:;" data-type="inbox" data-title="Sub_1">Sub-Folder 1</a>
          </li>
          <li><a href="javascript:;" data-type="inbox" data-title="Sub_2">Sub-Folder 2</a>
          </li>
        </ul>
      </li>
      <li><a href="javascript:;" data-type="inbox" data-title="Sub_4">Sub-Folder 4</a>
      </li>
      <li><a href="javascript:;" data-type="inbox" data-title="Sub_5">Sub-Folder 5</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="javascript:;" data-type="important" data-title="Inbox"> Important </a>
  </li>
  <li>
    <a href="javascript:;" data-type="sent" data-title="Sent"> Sent </a>
  </li>
  <li>
    <a href="javascript:;" data-type="draft" data-title="Draft"> Draft
            <span class="badge badge-danger">8</span>
        </a>
  </li>
  <li>
    <a href="javascript:;" class="sbold uppercase" data-title="Trash"> Trash
            <span class="badge badge-info">23</span>
        </a>
  </li>
  <li>
    <a href="javascript:;" data-type="inbox" data-title="Promotions"> Promotions
            <span class="badge badge-warning">2</span>
        </a>
  </li>
  <li>
    <a href="javascript:;" data-type="inbox" data-title="News"> News </a>
  </li>
</ul>

<ul id="MailMenuFirstTier" class="custom-menu">
  <li>Mark All As Read</li>
  <li>Empty Folder</li>
</ul>

<ul class="custom-menu" id="MailMenuSecondTier">
  <li class="NewSubFolder" data-action="new-folder">New Sub-Folder</li>
  <li class="Rename" data-action="rename-folder">Rename</li>
  <li class="Delete" data-action="delete-folder">Delete</li>
  <li>Mark All As Read</li>
  <li>Empty Folder</li>
</ul>