disableScrolling |
boolean |
@@ -194,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 3eb948e69..5f4fc31a2 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))
}
@@ -200,51 +201,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')
@@ -350,11 +375,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('')
}
@@ -428,7 +456,7 @@
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
var $canvas = $(target)
var data = $canvas.data('bs.offcanvas')
- var option = data ? 'toggle' : $this.data()
+ var option = data ? 'toggle' : $.extend($this.data(), $canvas.data())
e.preventDefault();
e.stopPropagation()