Разработка плагинов jQuery, справка по событиям кликов (раскрывающееся меню) - PullRequest
0 голосов
/ 11 февраля 2011

Я пытаюсь создать выпадающее меню в виде плагина.Я знаком с написанием сценариев для решений, но я никогда раньше не создавал плагин, поэтому я пытаюсь узнать, как это сделать, и поэтому повышаю свой уровень как разработчик jQuery.

Я пытаюсьсоздать базовую выпадающую функциональность.У вас есть ссылка.Вы нажимаете на нее, появляется выпадающий список ссылок.Вы щелкаете за пределами ссылки (документа), меню ссылок исчезает.

У меня проблемы с удалением.Я попытался привязать его к document.click, но, конечно, оно показывает меню, а затем скрывает его, так как нет ничего, обеспечивающего его показ в первую очередь.Как мне это сделать?

Как мне сделать так, чтобы меню скрывалось только после его показа, если вы щелкнете за его пределами?

application.js

jQuery(document).ready(function($){
  $("ul.drop-down").sillyDropDown();
  // failed attempt (shows and hides). Probably should go in plugin anyway.
  // $(document).click(function(){
  //   $("ul.drop-down").sillyDropDown('hide');
  // });
});

silly_drop_down.js

(function($){

  var methods = {

    init : function(options){
      return this.each(function(){
        var $this = $(this);
        var selector = $(this).children()[0];
        var link = $(selector);
        link.bind('click.silly', methods.show);
      });
    },
    show : function() {
      var $this = $(this);
      var menu = $this.siblings("ul");
      menu.slideDown("slow");
    },
    hide : function(){
      var $this = $(this);
      var menu = $this.children("ul");
      menu.slideUp("slow");
    }
  };

  $.fn.sillyDropDown = function(method){
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.sillyDropDown' );
    } 
  };

})(jQuery);

html, если это имеет значение

<ul id="project-settings" class="drop-down">
  <li>
    <a href="#">
      Settings
      <img src="/images/iconic/white/cog_alt_16x16.png" class="stale">
      <img src="/images/iconic/orange/cog_alt_16x16.png" class="hover">
    </a>
  </li>
  <ul style="display: none;">
    <div class="pointer"></div>
    <li class="first">
      <a href="#">Settings...</a>
    </li>
    <li>
      <a href="#">Collaborators...</a>
    </li>
    <li>
      <a href="#">Comments...</a>
    </li>
    <hr>
    <li>
      <a href="#">Delete Project</a>
    </li>
  </ul>
</ul>

edit (я понял, что задавал подобный вопрос в прошлом).Я сделал следующее в application.js

  $("ul.drop-down").sillyDropDown();
  $(document).bind("click.silly", function(e){
    var nav = $("ul.drop-down");
    var target = $(e.target);
    if (target.closest("ul.drop-down").length < 1){
      nav.sillyDropDown('hide');
      return;
    }
  });

Это делает работу.Однако это не выглядит элегантным в application.js - Как бы я справился с этим внутри плагина?

Примечание. Вероятно, у меня будет несколько экземпляров ul.drop-down - AmЯ что-то упустил в своей реализации, чтобы позаботиться об этом?Пока в моих тестах есть только один.

Кроме того, как бы я сделал так, чтобы, если я щелкну ссылку внутри выпадающего меню, я мог заставить меню скрыться (это было бы модальное всплывающее окнонапример).

добавил это сейчас в application.js

  $("ul.drop-down ul li a").click(function(e){
    $("ul.drop-down ul").hide();
    return;
  });

Чувствуется снова, очень не элегантно и, вероятно, должно быть помещено куда-то еще.Просветите меня пожалуйста!

Ответы [ 2 ]

0 голосов
/ 11 февраля 2011

Вот пример: http://jsfiddle.net/5tgGq/1/. Важная часть в init:

    init: function(options) {
        return this.each(function() {
            var self = this;
            $(this).click(methods.show);
            $(document).click(function(e) {
                if ($(self).has(e.target).length === 0) {
                    methods.hide.apply(self);
                }
            });
        });
    },

Надеюсь, это поможет. Я вполне уверен, что вы должны быть в порядке с несколькими элементами, так как вы используете только методы show и hide для элементов, которые вы уже each ed.

РЕДАКТИРОВАТЬ: вот пример с двумя списками: http://jsfiddle.net/5tgGq/3/

0 голосов
/ 11 февраля 2011

Я бы связал действие закрытия меню с $(window).click, затем в собственном событии щелчка выпадающего меню добавьте e.stopPropogation().Это предотвращает дальнейшее всплытие клика вверх по дереву DOM к элементу окна.

Или просто используйте событие меню blur.Думаю, это сработает даже для не входных элементов.

...