PageSourceSearch

https://hougen.ajima.jp/js/jquery.rcrumbs.js

js ajima.jp collected 2026-10-02 07:04:48 UTC 9,310 bytes, 269 lines download raw bytes

1/* jQuery responsive breadcrumbs plugin jQuery plugin
2 * https://github.com/cm0s/jquery-rcrumbs
3 *
4 * Copyright (c) 2013, Nicolas Forney 
5 * Released under the MIT licence 
6 *
7 * version: 1.0.2 
8 * 2013/05/12
9 */
10(function ($, window, document, undefined) {
11  "use strict";
12
13  var rcrumbs = 'rcrumbs',
14      defaults = {
15        version: '1.0.2',
16        callback: {
17          preCrumbsListDisplay: $.noop, //A function which is executed before the crumbs list is rendered
18          preCrumbDisplay: $.noop, //A function which is executed before each crumb is rendered
19          postCrumbsListDisplay: $.noop, //A function which is executed after the crumbs list is rendered
20          postCrumbDisplay: $.noop //A function which is executed after each crumb is rendered
21        },
22        ellipsis: true, // Display ellipsis when only the last crumb remains with not enough space to be fully displayed
23        windowResize: true, // To activate/deactivate the resizing of the crumbs on window resize event
24        nbUncollapsableCrumbs: 2, // Number of crumbs which can not be collapsed.
25        animation: {
26          activated: true, // Activate an animation when crumbs are displayed/hidden on a window resize
27          speed: 400 // Animation speed (activated option must be set to true)
28        }
29      };
30
31  // Plugin constructor
32  function Plugin(element, options) {
33    this.element = element;
34    this.$element = $(element);
35
36    //Merge defaults with given  (use deep copy)
37    this.options = $.extend(true, {}, defaults, options);
38
39    this._defaults = defaults;
40    this._name = rcrumbs;
41    Plugin.prototype.plugin = this;
42    this._init();
43  }
44
45  Plugin.prototype = {
46
47    version: function () {
48      return this.options.version;
49    },
50
51    _init: function () {
52      //Ensure rcrumbs class is defined on the element in order to be able to correctly apply stylesheets
53      if (!this.$element.hasClass('rcrumbs')) {
54        this.$element.addClass('rcrumbs');
55      }
56
57      //Variables declaration
58      this.nbCrumbDisplayed = 0;
59      this.$crumbsList = $('ul', this.element);
60      this.$crumbs = $('li', this.$crumbsList);
61      this.$lastCrumb = this.$crumbs.last();
62      this.reversedCrumbs = $('li', this.$crumbsList).get().reverse();
63      this.lastNbCrumbDisplayed = 0;
64      this.totalCrumbsWidth = 0;
65
66      this._initCrumbs();
67
68      this._showOrHideCrumbsList(true);
69
70      if (this.options.windowResize) {
71        this._showOrHideCrumbsListOnWindowResize();
72      }
73    },
74
75    /**
76     * Get the width of a hidden DOM element without displaying it in the browser.
77     * @param element DOM element from which the width will be retrieved.
78     */
79    _getHiddenElWidth: function (element) {
80      var result,
81          elementClone = $(element).clone(false);
82
83      elementClone.css({
84        visibility: 'hidden',
85        position: 'absolute'
86      });
87
88      elementClone.appendTo(this.$crumbsList);
89
90      result = elementClone.width();
91
92      elementClone.remove();
93
94      return result;
95    },
96
97    _initCrumbs: function () {
98      var that = this;
99
100      //Remove text node in order to avoid displaying white spaces between li elements and thus make width
101      //calculation for the breadcrumbs resize easier.
102      $(this.$crumbsList).contents().filter(function () {
103        return this.nodeType === 3;  //3 => Text node
104      }).remove();
105
106      //For each li element save its width
107      $.each(this.$crumbs, function (key, value) {
108        var $crumb = $(this);
109        that._storeCrumbWidth($crumb);
110      });
111    },
112
113    /**
114     * Save width of the li element passed as parameter
115     * @param $crumb li element on which its width will be stored
116     * @return calculated crumb width
117     */
118    _storeCrumbWidth: function ($crumb) {
119      var crumbWidth = this._getHiddenElWidth($crumb);
120      $crumb.data('width', crumbWidth);
121      return crumbWidth;
122    },
123
124    /**
125     * @param disableAnimation used to disable the animation even if the animation.activated option is set to true.
126     */
127    _showOrHideCrumbsList: function (disableAnimation) {
128      var that = this;
129      this.remainingSpaceToDisplayCrumbs = this.$element.width();
130      this.nbCrumbDisplayed = 0;
131      this.totalCrumbsWidth = 0;
132      this.nextCrumbToShowWidth = undefined;
133
134      this.options.callback.preCrumbsListDisplay(this);
135
136      //It's important to loop through a reversed list in order to ensure we first try to display the last element
137      $.each(this.reversedCrumbs, function (key, value) {
138        var $crumb = $(this),
139            $nextCrumb = $(that.reversedCrumbs[key + 1]); //May return empty jQuery object
140
141        that._showOrHideCrumb($crumb, $nextCrumb, key, disableAnimation);
142      });
143
144      this.lastNbCrumbDisplayed = this.nbCrumbDisplayed;
145
146      this.options.callback.postCrumbsListDisplay(this);
147
148    },
149
150    _showOrHideCrumb: function ($crumb, $nextCrumb, crumbPosition, disableAnimation) {
151      this.options.callback.preCrumbDisplay($crumb);
152      var that = this;
153      this.remainingSpaceToDisplayCrumbs -= $crumb.data('width');
154
155      if (crumbPosition < this.options.nbUncollapsableCrumbs) {
156        showCrumbWithOrWithoutAnimation();
157
158        if (this.remainingSpaceToDisplayCrumbs < 0) {
159          enableEllipsis(this.$lastCrumb);
160        }
161
162        this.totalCrumbsWidth += $crumb.data('width');
163      } else {
164        if (this.remainingSpaceToDisplayCrumbs >= 0) {
165          showCrumbWithOrWithoutAnimation();
166          this.totalCrumbsWidth += $crumb.data('width');
167        } else {
168          if (this.lastNbCrumbDisplayed > this.nbCrumbDisplayed - 1 && this.options.animation.activated) {
169            hideCrumbWithAnimation();
170          } else {
171            $crumb.removeClass('show');
172          }
173
174          if (!this.nextCrumbToShowWidth) {
175            this.nextCrumbToShowWidth = $crumb.data('width');
176          }
177        }
178      }
179
180      function showCrumbWithOrWithoutAnimation() {
181        $crumb.addClass('show');
182
183        if (that.lastNbCrumbDisplayed < (that.nbCrumbDisplayed + 1) && that.options.animation.activated &&
184            !disableAnimation) {
185          $crumb.width(0);
186          $crumb.animate({width: $crumb.data('width')}, that.options.animation.speed, function () {
187            that.options.callback.postCrumbDisplay($crumb);
188          });
189        } else {
190          that.options.callback.postCrumbDisplay($crumb);
191        }
192        that.nbCrumbDisplayed += 1;
193      }
194
195      function hideCrumbWithAnimation() {
196        $crumb.animate({width: 0}, that.options.animation.speed, function () {
197          $crumb.removeClass('show');
198        });
199      }
200
201      function enableEllipsis($crumb) {
202        $crumb.css({
203          'width': (that.remainingSpaceToDisplayCrumbs + $crumb.data('width')) + 'px'
204        });
205        $crumb.addClass('ellipsis');
206      }
207
208      function disableEllipsis($crumb) {
209        $crumb.css({
210          'width': 'auto'
211        });
212        $crumb.removeClass('ellipsis');
213      }
214    },
215
216    _showOrHideCrumbsListOnWindowResize: function () {
217      var that = this;
218      $(window).resize(function () {
219        var rcrumbWidth = that.$element.width();
220        if (rcrumbWidth < that.totalCrumbsWidth || (that.totalCrumbsWidth + that.nextCrumbToShowWidth) < rcrumbWidth) {
221          $.each(that.reversedCrumbs, function (key, value) { //Stop all crumbs animations
222            var $currentCrumb = $(this);
223            $currentCrumb.stop(true, true);
224          });
225
226          that._showOrHideCrumbsList();
227        }
228        //Disable ellipsis on the last crumb when there is enough space
229        if (rcrumbWidth >= that.totalCrumbsWidth && that.$lastCrumb.hasClass('ellipsis')) {
230          that._disableEllipsis(that.$lastCrumb);
231        }
232      });
233    },
234
235    _disableEllipsis: function ($crumb) {
236      $crumb.css({
237        'width': 'auto'
238      });
239      $crumb.removeClass('ellipsis');
240    }
241  };
242
243
244  $.fn[rcrumbs] = function (methodNameOrObject) {
245    // When the function parameter is a string the value is used to call the corresponding plugin method. If the
246    // argument is an object or a falsy value the Plugin is instantiated
247    // Only public method (not prefixed with an underscore) can be called.
248    if (Plugin.prototype[methodNameOrObject] && (methodNameOrObject.indexOf('_') === -1)) {
249      var plugin = $.data(this[0], 'plugin_' + rcrumbs);
250      if (plugin) {
251        //slice is used to pass all argument following the method n
251ame
252        return Plugin.prototype[methodNameOrObject].apply(plugin, Array.prototype.slice.call(arguments, 1));
253      } else {
254        $.error('jquery.' + rcrumbs + ' plugin must be initialized first on the element');
255      }
256    } else if (typeof methodNameOrObject === 'object' || !methodNameOrObject) {
257      // Plugin wrapper around the constructor to prevent against multiple instantiations
258      return this.each(function () {
259        if (!$.data(this, 'plugin_' + rcrumbs)) {
260          $.data(this, 'plugin_' + rcrumbs, new Plugin(this, methodNameOrObject));
261        } else {
262          $.error('jquery.' + rcrumbs + ' plugin cannot be instantiated multiple times on same element');
263        }
264      });
265    } else {
266      $.error('Method ' + methodNameOrObject + ' does not exist on jquery.' + rcrumbs);
267    }
268  };
269})(jQuery, window, document);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.