diff --git a/docs/javascript.html b/docs/javascript.html index f6499f2f7..3185b07b2 100644 --- a/docs/javascript.html +++ b/docs/javascript.html @@ -183,6 +183,12 @@

Options

true Calculate if off canvas should be disabled for this viewport width on window resize. If your elements always gets hidden on window resize, try setting this to false. + + exclude + string + null + Set css selectors for elements, that have fixed positioning and that should not be moved when showing\hiding menu. + disableScrolling boolean @@ -197,6 +203,9 @@

Graceful degradation

For browsers that don't support transform (mainly IE8), the target option is ignored. In that case, the plugin will always slide the target element. In that case .canvas-slid will be added to the target element instead.

+

Two menus on the page

+ +

If there are two (or more) menus on the page, there can be only one opened at a time. When menu attempts to be opened, already opened one will be closed first. It's almost fully automated, accept that data-exclude option should be set for each menu, holding references to other menus. For example, if we have two menus #menu-left and #menu-right, then they should have the following option set, correspondingly: data-exclude="#menu-right" and data-exclude="#menu-left".

Methods

.offcanvas(options)

diff --git a/js/offcanvas.js b/js/offcanvas.js index d85096c80..2e4bd9cad 100644 --- a/js/offcanvas.js +++ b/js/offcanvas.js @@ -29,8 +29,9 @@ this.placement = null this.$calcClone = null + this.calcClone() + if (this.options.recalc) { - this.calcClone() $(window).on('resize', $.proxy(this.recalc, this)) } @@ -59,7 +60,8 @@ autohide: true, recalc: true, disableScrolling: true, - modal: false + modal: false, + exclude: null } OffCanvas.prototype.setWidth = function () { @@ -198,51 +200,75 @@ this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return - this.state = 'slide-in' - this.$element.css('width', '') - this.calcPlacement() - this.setWidth() + this.hideOthers($.proxy(function() { + this.state = 'slide-in' + this.$element.css('width', '') + this.calcPlacement() + this.setWidth() + + var elements = this.getCanvasElements() + var placement = this.placement + var opposite = this.opposite(placement) + var offset = this.offset() + + if (elements.index(this.$element) !== -1) { + $(this.$element).data('offcanvas-style', $(this.$element).attr('style') || '') + this.$element.css(placement, -1 * offset) + this.$element.css(placement); // Workaround: Need to get the CSS property for it to be applied before the next line of code + } - var elements = this.getCanvasElements() - var placement = this.placement - var opposite = this.opposite(placement) - var offset = this.offset() + elements.addClass('canvas-sliding').each(function() { + var $this = $(this) + if ($this.data('offcanvas-style') === undefined) $this.data('offcanvas-style', $this.attr('style') || '') + if ($this.css('position') === 'static' && !isIphone) $this.css('position', 'relative') + if (($this.css(placement) === 'auto' || $this.css(placement) === '0px') && + ($this.css(opposite) === 'auto' || $this.css(opposite) === '0px')) { + $this.css(placement, 0) + } + }) - if (elements.index(this.$element) !== -1) { - $(this.$element).data('offcanvas-style', $(this.$element).attr('style') || '') - this.$element.css(placement, -1 * offset) - this.$element.css(placement); // Workaround: Need to get the CSS property for it to be applied before the next line of code - } + if (this.options.disableScrolling) this.disableScrolling() + if (this.options.modal || this.options.backdrop) this.toggleBackdrop() + + var complete = function () { + if (this.state != 'slide-in') return + + this.state = 'slid' - elements.addClass('canvas-sliding').each(function() { - var $this = $(this) - if ($this.data('offcanvas-style') === undefined) $this.data('offcanvas-style', $this.attr('style') || '') - if ($this.css('position') === 'static' && !isIphone) $this.css('position', 'relative') - if (($this.css(placement) === 'auto' || $this.css(placement) === '0px') && - ($this.css(opposite) === 'auto' || $this.css(opposite) === '0px')) { - $this.css(placement, 0) + elements.removeClass('canvas-sliding').addClass('canvas-slid') + this.$element.trigger('shown.bs.offcanvas') } - }) - if (this.options.disableScrolling) this.disableScrolling() - if (this.options.modal || this.options.backdrop) this.toggleBackdrop() + setTimeout($.proxy(function() { + this.$element.addClass('in') + this.slide(elements, offset, $.proxy(complete, this)) + }, this), 1) + }, this)); + } - var complete = function () { - if (this.state != 'slide-in') return + //Hide other opened offcanvas menus, and then open this one + OffCanvas.prototype.hideOthers = function (callback) { + var doHide = false + var id = this.$element.attr('id') + var $clones = $('.offcanvas-clone:not([data-id="' + id + '"])') - this.state = 'slid' + if (!$clones.length) return callback() - elements.removeClass('canvas-sliding').addClass('canvas-slid') - this.$element.trigger('shown.bs.offcanvas') - } + $clones.each(function(index, clone) { + var id = $(clone).attr('data-id') + var $menu = $('#' + id) + doHide = $menu.hasClass('canvas-slid') - setTimeout($.proxy(function() { - this.$element.addClass('in') - this.slide(elements, offset, $.proxy(complete, this)) - }, this), 1) + if (!doHide) return + + $menu.one('hidden.bs.offcanvas', callback) + $menu.offcanvas('hide') + }) + + if (!doHide) callback() } - OffCanvas.prototype.hide = function (fast) { + OffCanvas.prototype.hide = function () { if (this.state !== 'slid') return var startEvent = $.Event('hide.bs.offcanvas') @@ -348,11 +374,14 @@ } OffCanvas.prototype.calcClone = function() { - this.$calcClone = $('.offcanvas-clone') + var id = this.$element.attr('id') + this.$calcClone = $('.offcanvas-clone[data-id="' + id + '"]') if (!this.$calcClone.length) { this.$calcClone = this.$element.clone() .addClass('offcanvas-clone') + .attr('data-id', id) + .removeAttr('id') .appendTo($('body')) .html('') }