bootstrap-twipsy.js 7.14 KiB
/* ==========================================================
 * bootstrap-twipsy.js v2.0.0
 * http://twitter.github.com/bootstrap/javascript.html#twipsy
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ==========================================================
 * Copyright 2011 Twitter, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */
!function( $ ) {
  "use strict"
 /* TWIPSY PUBLIC CLASS DEFINITION
  * ============================== */
  var Twipsy = function ( element, options ) {
    this.init('twipsy', element, options)
  Twipsy.prototype = {
    constructor: Twipsy
  , init: function ( type, element, options ) {
      var eventIn
        , eventOut
      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true
      if (this.options.trigger != 'manual') {
        eventIn  = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
        this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
  , getOptions: function ( options ) {
      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
      return options
  , enter: function ( e ) {
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
var self = $(e.currentTarget)[this.type](this._options).data(this.type) if (!self.options.delay || !self.options.delay.show) { self.show() } else { self.hoverState = 'in' setTimeout(function() { if (self.hoverState == 'in') { self.show() } }, self.options.delay.show) } } , leave: function ( e ) { var self = $(e.currentTarget)[this.type](this._options).data(this.type) if (!self.options.delay || !self.options.delay.hide) { self.hide() } else { setTimeout(function() { self.hoverState = 'out' if (self.hoverState == 'out') { self.hide() } }, self.options.delay.hide) } } , show: function () { var $tip , inside , pos , actualWidth , actualHeight , placement , tp if (this.hasContent() && this.enabled) { $tip = this.tip() this.setContent() if (this.options.animation) { $tip.addClass('fade') } placement = typeof this.options.placement == 'function' ? thing.call(this, $tip[0], this.$element[0]) : this.options.placement inside = /in/.test(placement) $tip .remove() .css({ top: 0, left: 0, display: 'block' }) .prependTo(inside ? this.$element : document.body) pos = this.getPosition(inside) actualWidth = $tip[0].offsetWidth actualHeight = $tip[0].offsetHeight switch (inside ? placement.split(' ')[1] : placement) { case 'bottom': tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} break case 'top': tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} break case 'left':