Zurb foundation 基础6下拉

Zurb foundation 基础6下拉,zurb-foundation,Zurb Foundation,我正在尝试创建一个下拉列表,尽管在同一屏幕上有多个不同的锚,但其内容基本相同 因此,我不想创建大量重复内容,而是希望实际的下拉窗格在页脚中编码一次,并有几个锚引用它 下拉窗格: 这里下拉窗格中的一些内容,无论哪个锚触发它显示,大部分内容都是相同的。 这似乎是不可能的 Zurb已决定不再将多锚下拉作为一项功能: …但提出建议的用户(Thomas Higgins)提前创建了下拉模块的修改版本: 我没有亲自在生产现场使用它,因为我担心当基金会被更新时它会被改写,但它可能对你来说是用来吞食或替换Zu

我正在尝试创建一个下拉列表,尽管在同一屏幕上有多个不同的锚,但其内容基本相同

因此,我不想创建大量重复内容,而是希望实际的下拉窗格在页脚中编码一次,并有几个锚引用它

下拉窗格:


这里下拉窗格中的一些内容,无论哪个锚触发它显示,大部分内容都是相同的。

这似乎是不可能的

Zurb已决定不再将多锚下拉作为一项功能:

…但提出建议的用户(Thomas Higgins)提前创建了下拉模块的修改版本:

我没有亲自在生产现场使用它,因为我担心当基金会被更新时它会被改写,但它可能对你来说是用来吞食或替换Zurb股票模块。 (插件)

/**
*下拉模块。
*@模块基础
*@需要基础。
*@需要基础。
*/
!函数($,基础){
"严格使用",;
/**
*创建下拉列表的新实例。
*@级
*@param{jQuery}element-要制作成手风琴菜单的jQuery对象。
*@param{Object}options-覆盖默认插件设置。
*/
功能下拉列表(元素、选项){
此.$element=元素;
this.options=$.extend({},Dropdown.defaults,this.$element.data(),options);
这个;
RealStPuthLin(这个“下拉”);
基金会键盘登记(下拉),{
'输入':'打开',
“空间”:“打开”,
“退出”:“关闭”,
“制表符”:“制表符转发”,
“SHIFT\u TAB”:“TAB\u backward”
});
}
Dropdown.defaults={
/**
*悬停事件时延迟打开子菜单的时间量。
*@选项
*@example 250
*/
悬停延迟:250,
/**
*允许在悬停事件时打开子菜单
*@选项
*@example-false
*/
悬停:错,
/**
*将鼠标悬停在下拉窗格上时不关闭下拉列表
*@选项
*@example-true
*/
悬停窗格:false,
/**
*打开时下拉窗格和触发元素之间的像素数。
*@选项
*@example 1
*/
沃夫特:1,
/**
*打开时下拉窗格和触发元素之间的像素数。
*@选项
*@example 1
*/
霍夫塞特:1,
/**
*类应用于调整打开位置。JS将测试并填写此项。
*@选项
*@example“top”
*/
职位类别:“”,
/**
*如果使用键盘命令打开,允许插件将焦点捕捉到下拉窗格。
*@选项
*@example-false
*/
trapFocus:错,
/**
*允许插件将焦点设置为窗格中的第一个可聚焦元素,而不考虑打开方法。
*@选项
*@example-true
*/
自动对焦:错误,
/**
*允许单击主体以关闭下拉列表。
*@选项
*@example-true
*/
closeOnClick:false
};
/**
*通过设置/检查选项和属性、添加辅助变量和保存锚来初始化插件。
*@函数
*@私人
*/
prototype.\u init=function(){
var$id=this.$element.attr('id');
这是.$anchors=$('[data TORGET=“'+$id+']”])|$('[data open=“'+$id+']”]);
这是$anchors.attr({
“aria控件”:$id,
“数据是焦点”:false,
“数据雪人盒”:$id,
“aria haspopup”:没错,
“aria expanded”:错误
//“数据调整大小”:$id
});
this._setCurrentAnchor(this.$anchors.first());
this.options.positionClass=this.getPositionClass();
这个计数器=4;
this.usedPositions=[];
这是$element.attr({
“隐藏的咏叹调”:“正确”,
“数据雪人盒”:$id,
“数据调整大小”:$id
});
这个;
};
/**
*用于设置当前定位点的辅助函数
*@函数
*@私人
*/
Dropdown.prototype.\u setCurrentAnchor=函数($anchor){
这。$current_anchor=$anchor;
这是$element.attr({
'ARILabelDeBu':这个.CurrnTr.Actudio。Atr(“ID”)基础。GETYODIGITS(6,DD锚点)
});
};
/**
*帮助器函数,用于确定下拉窗格的当前方向。
*@函数
*@返回position类的{String}position字符串值。
*/
Dropdown.prototype.getPositionClass=函数(){
var position=this.$element[0].className.match(/(上|左|右)/g);
位置=位置?位置[0]:'';
返回位置;
};
/**
*通过添加/删除定位类来调整下拉窗格的方向。
*@函数
*@私人
*@param{String}position-要删除的位置类。
*/
Dropdown.prototype.\u重新定位=功能(位置){
这个.usedPositions.push(位置?位置:'bottom');
//默认情况下,尝试切换到另一侧
if(!position&&(this.usedPositions.indexOf('top')<0)){
此.element.addClass('top');
}else if(position==='top'&&(this.usedPositions.indexOf('bottom')<0)){
此.$element.removeClass(位置);
}else if(position==='left'&&(this.usedPositions.indexOf('right')<0)){
此.$element.removeClass(位置)
.addClass(“右”);
}else if(position==='right'&&(this.usedPositions.indexOf('left')<0)){
此.$element.removeClass(位置)
.addClass(“左”);
}
//如果默认更改不起作用,请先尝试底部或左侧
如果(!position&&(this.usedPositions.indexOf('top')>-1)和(&(this.usedPositions.indexOf('left')<0)){
此.element.addClass('left');
}else if(position==='top'&&(this.usedPositions.indexOf('bottom')>-1)&(this.usedPositions.indexOf('left')<0)){
此.$element.removeClass(位置)
.addClass(“左”);
}否则,如果(位置)==
/**
 * Dropdown module.
 * @module foundation.dropdown
 * @requires foundation.util.keyboard
 * @requires foundation.util.box
 */
!function($, Foundation){
  'use strict';
  /**
   * Creates a new instance of a dropdown.
   * @class
   * @param {jQuery} element - jQuery object to make into an accordion menu.
   * @param {Object} options - Overrides to the default plugin settings.
   */
  function Dropdown(element, options){
    this.$element = element;
    this.options = $.extend({}, Dropdown.defaults, this.$element.data(), options);
    this._init();

    Foundation.registerPlugin(this, 'Dropdown');
    Foundation.Keyboard.register('Dropdown', {
      'ENTER': 'open',
      'SPACE': 'open',
      'ESCAPE': 'close',
      'TAB': 'tab_forward',
      'SHIFT_TAB': 'tab_backward'
    });
  }

  Dropdown.defaults = {
    /**
     * Amount of time to delay opening a submenu on hover event.
     * @option
     * @example 250
     */
    hoverDelay: 250,
    /**
     * Allow submenus to open on hover events
     * @option
     * @example false
     */
    hover: false,
    /**
     * Don't close dropdown when hovering over dropdown pane
     * @option
     * @example true
     */
    hoverPane: false,
    /**
     * Number of pixels between the dropdown pane and the triggering element on open.
     * @option
     * @example 1
     */
    vOffset: 1,
    /**
     * Number of pixels between the dropdown pane and the triggering element on open.
     * @option
     * @example 1
     */
    hOffset: 1,
    /**
     * Class applied to adjust open position. JS will test and fill this in.
     * @option
     * @example 'top'
     */
    positionClass: '',
    /**
     * Allow the plugin to trap focus to the dropdown pane if opened with keyboard commands.
     * @option
     * @example false
     */
    trapFocus: false,
    /**
     * Allow the plugin to set focus to the first focusable element within the pane, regardless of method of opening.
     * @option
     * @example true
     */
    autoFocus: false,
    /**
     * Allows a click on the body to close the dropdown.
     * @option
     * @example true
     */
    closeOnClick: false
  };
  /**
   * Initializes the plugin by setting/checking options and attributes, adding helper variables, and saving the anchor.
   * @function
   * @private
   */
  Dropdown.prototype._init = function(){
    var $id = this.$element.attr('id');

    this.$anchors = $('[data-toggle="' + $id + '"]') || $('[data-open="' + $id + '"]');
    this.$anchors.attr({
      'aria-controls': $id,
      'data-is-focus': false,
      'data-yeti-box': $id,
      'aria-haspopup': true,
      'aria-expanded': false
      // 'data-resize': $id
    });

    this._setCurrentAnchor(this.$anchors.first());

    this.options.positionClass = this.getPositionClass();
    this.counter = 4;
    this.usedPositions = [];
    this.$element.attr({
      'aria-hidden': 'true',
      'data-yeti-box': $id,
      'data-resize': $id
    });
    this._events();
  };
  /**
   * Helper function to set the current anchor
   * @function
   * @private
   */
  Dropdown.prototype._setCurrentAnchor = function($anchor){
      this.$current_anchor = $anchor;
      this.$element.attr({
        'aria-labelledby': this.$current_anchor.attr('id') || Foundation.GetYoDigits(6, 'dd-anchor')
      });
  };
  /**
   * Helper function to determine current orientation of dropdown pane.
   * @function
   * @returns {String} position - string value of a position class.
   */
  Dropdown.prototype.getPositionClass = function(){
    var position = this.$element[0].className.match(/(top|left|right)/g);
        position = position ? position[0] : '';
    return position;
  };
  /**
   * Adjusts the dropdown panes orientation by adding/removing positioning classes.
   * @function
   * @private
   * @param {String} position - position class to remove.
   */
  Dropdown.prototype._reposition = function(position){
    this.usedPositions.push(position ? position : 'bottom');
    //default, try switching to opposite side
    if(!position && (this.usedPositions.indexOf('top') < 0)){
      this.$element.addClass('top');
    }else if(position === 'top' && (this.usedPositions.indexOf('bottom') < 0)){
      this.$element.removeClass(position);
    }else if(position === 'left' && (this.usedPositions.indexOf('right') < 0)){
      this.$element.removeClass(position)
          .addClass('right');
    }else if(position === 'right' && (this.usedPositions.indexOf('left') < 0)){
      this.$element.removeClass(position)
          .addClass('left');
    }

    //if default change didn't work, try bottom or left first
    else if(!position && (this.usedPositions.indexOf('top') > -1) && (this.usedPositions.indexOf('left') < 0)){
      this.$element.addClass('left');
    }else if(position === 'top' && (this.usedPositions.indexOf('bottom') > -1) && (this.usedPositions.indexOf('left') < 0)){
      this.$element.removeClass(position)
          .addClass('left');
    }else if(position === 'left' && (this.usedPositions.indexOf('right') > -1) && (this.usedPositions.indexOf('bottom') < 0)){
      this.$element.removeClass(position);
    }else if(position === 'right' && (this.usedPositions.indexOf('left') > -1) && (this.usedPositions.indexOf('bottom') < 0)){
      this.$element.removeClass(position);
    }
    //if nothing cleared, set to bottom
    else{
      this.$element.removeClass(position);
    }
    this.classChanged = true;
    this.counter--;
  };
  /**
   * Sets the position and orientation of the dropdown pane, checks for collisions.
   * Recursively calls itself if a collision is detected, with a new position class.
   * @function
   * @private
   */
  Dropdown.prototype._setPosition = function(){
    if(this.$current_anchor.attr('aria-expanded') === 'false'){ return false; }
    var position = this.getPositionClass(),
        $eleDims = Foundation.Box.GetDimensions(this.$element),
        $anchorDims = Foundation.Box.GetDimensions(this.$current_anchor),
        _this = this,
        direction = (position === 'left' ? 'left' : ((position === 'right') ? 'left' : 'top')),
        param = (direction === 'top') ? 'height' : 'width',
        offset = (param === 'height') ? this.options.vOffset : this.options.hOffset;

    if(($eleDims.width >= $eleDims.windowDims.width) || (!this.counter && !Foundation.Box.ImNotTouchingYou(this.$element))){
      this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$current_anchor, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
        'width': $eleDims.windowDims.width - (this.options.hOffset * 2),
        'height': 'auto'
      });
      this.classChanged = true;
      return false;
    }

    this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$current_anchor, position, this.options.vOffset, this.options.hOffset));

    while(!Foundation.Box.ImNotTouchingYou(this.$element) && this.counter){
      this._reposition(position);
      this._setPosition();
    }
  };
  /**
   * Adds event listeners to the element utilizing the triggers utility library.
   * @function
   * @private
   */
  Dropdown.prototype._events = function(){
    var _this = this;
    this.$element.on({
      'open.zf.trigger': this.open.bind(this),
      'close.zf.trigger': this.close.bind(this),
      'toggle.zf.trigger': this.toggle.bind(this),
      'resizeme.zf.trigger': this._setPosition.bind(this)
    });

    if(this.options.hover){
      this.$anchors.off('mouseenter.zf.dropdown mouseleave.zf.dropdown')
          .on('mouseenter.zf.dropdown', function(event){
            clearTimeout(_this.timeout);
            _this.timeout = setTimeout(function(){
              _this.open(event, [this]);
              $(this).data('hover', true);
            }.bind(this), _this.options.hoverDelay);
          }).on('mouseleave.zf.dropdown', function(){
            clearTimeout(_this.timeout);
            _this.timeout = setTimeout(function(){
              _this.close();
              _this.$anchors.data('hover', false);
            }, _this.options.hoverDelay);
          });
      if(this.options.hoverPane){
        this.$element.off('mouseenter.zf.dropdown mouseleave.zf.dropdown')
            .on('mouseenter.zf.dropdown', function(){
              clearTimeout(_this.timeout);
            }).on('mouseleave.zf.dropdown', function(){
              clearTimeout(_this.timeout);
              _this.timeout = setTimeout(function(){
                _this.close();
                _this.$anchors.data('hover', false);
              }, _this.options.hoverDelay);
            });
      }
    }
    this.$anchors.add(this.$element).on('keydown.zf.dropdown', function(e) {

      var $target = $(this),
        visibleFocusableElements = Foundation.Keyboard.findFocusable(_this.$element);

      Foundation.Keyboard.handleKey(e, 'Dropdown', {
        tab_forward: function() {
          if (_this.$element.find(':focus').is(visibleFocusableElements.eq(-1))) { // left modal downwards, setting focus to first element
            if (_this.options.trapFocus) { // if focus shall be trapped
              visibleFocusableElements.eq(0).focus();
              e.preventDefault();
            } else { // if focus is not trapped, close dropdown on focus out
              _this.close();
            }
          }
        },
        tab_backward: function() {
          if (_this.$element.find(':focus').is(visibleFocusableElements.eq(0)) || _this.$element.is(':focus')) { // left modal upwards, setting focus to last element
            if (_this.options.trapFocus) { // if focus shall be trapped
              visibleFocusableElements.eq(-1).focus();
              e.preventDefault();
            } else { // if focus is not trapped, close dropdown on focus out
              _this.close();
            }
          }
        },
        open: function() {
          if ($target.is(_this.$anchors)) {
            _this.open();
            _this.$element.attr('tabindex', -1).focus();
            e.preventDefault();
          }
        },
        close: function() {
          _this.close();
          _this.$anchors.focus();
        }
      });
    });
  };
  /**
   * Adds an event handler to the body to close any dropdowns on a click.
   * @function
   * @private
   */
  Dropdown.prototype._addBodyHandler = function(){
     var $body = $(document.body).not(this.$element),
         _this = this;
     $body.off('click.zf.dropdown')
          .on('click.zf.dropdown', function(e){
            if(_this.$current_anchor.is(e.target) || _this.$current_anchor.find(e.target).length) {
              return;
            }
            if(_this.$element.find(e.target).length) {
              return;
            }
            _this.close();
            $body.off('click.zf.dropdown');
          });
  };
  /**
   * Opens the dropdown pane, and fires a bubbling event to close other dropdowns.
   * @function
   * @fires Dropdown#closeme
   * @fires Dropdown#show
   */
  Dropdown.prototype.open = function(event, togglers){
    if (togglers) { this._setCurrentAnchor($(togglers).first()); }
    // var _this = this;
    /**
     * Fires to close other open dropdowns
     * @event Dropdown#closeme
     */
    this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id'));
    this.$current_anchor.addClass('hover')
        .attr({'aria-expanded': true});
    // this.$element/*.show()*/;
    this._setPosition();
    this.$element.addClass('is-open')
        .attr({'aria-hidden': false});

    if(this.options.autoFocus){
      var $focusable = Foundation.Keyboard.findFocusable(this.$element);
      if($focusable.length){
        $focusable.eq(0).focus();
      }
    }

    if(this.options.closeOnClick){ this._addBodyHandler(); }

    /**
     * Fires once the dropdown is visible.
     * @event Dropdown#show
     */
     this.$element.trigger('show.zf.dropdown', [this.$element]);
    //why does this not work correctly for this plugin?
    // Foundation.reflow(this.$element, 'dropdown');
    // Foundation._reflow(this.$element.attr('data-dropdown'));
  };

  /**
   * Closes the open dropdown pane.
   * @function
   * @fires Dropdown#hide
   */
  Dropdown.prototype.close = function(){
    if(!this.$element.hasClass('is-open')){
      return false;
    }
    this.$element.removeClass('is-open')
        .attr({'aria-hidden': true});

    this.$anchors.removeClass('hover')
        .attr('aria-expanded', false);

    if(this.classChanged){
      var curPositionClass = this.getPositionClass();
      if(curPositionClass){
        this.$element.removeClass(curPositionClass);
      }
      this.$element.addClass(this.options.positionClass)
          /*.hide()*/.css({height: '', width: ''});
      this.classChanged = false;
      this.counter = 4;
      this.usedPositions.length = 0;
    }
    this.$element.trigger('hide.zf.dropdown', [this.$element]);
    // Foundation.reflow(this.$element, 'dropdown');
  };
  /**
   * Toggles the dropdown pane's visibility.
   * @function
   */
  Dropdown.prototype.toggle = function(event, togglers){
    if(this.$element.hasClass('is-open')){
      if(this.$current_anchor.data('hover')) return;
      this.close();
    }else{
      this.open(event, togglers);
    }
  };
  /**
   * Destroys the dropdown.
   * @function
   */
  Dropdown.prototype.destroy = function(){
    this.$element.off('.zf.trigger').hide();
    this.$anchors.off('.zf.dropdown');

    Foundation.unregisterPlugin(this);
  };

  Foundation.plugin(Dropdown, 'Dropdown');
}(jQuery, window.Foundation);
const dropdown = new Foundation.Dropdown($('#dropdown'))

$(document).on('mouseenter', '[data-multitoggle]', e => {
  dropdown.$currentAnchor = $(e.currentTarget)
  dropdown.open()
}).on('mouseleave', '[data-multitoggle]', () => dropdown.close())