PageSourceSearch

https://www.monumenten.nl/themes/monumenten/src/scripts/limethemed-js-plugins/jquery.ltTabs.js?tm9b0r

js monumenten.nl collected 2026-10-02 06:42:04 UTC 7,615 bytes, 240 lines download raw bytes

1/**
2 * @file
3 * Tabs.
4 *
5 * Documentation, see https://kennis.limoengroen.nl/js-plugins/v1/
6 */
7
8(function ($) {
9
10  // Populate global object container "lt" with plugin specific object.
11  lt.data.Tabs = {};
12  lt.data.Tabs.usedID = {};
13
14  $.fn.ltTabs = function(options) {
15
16    // Default settings.
17    var settings = $.extend({
18      toggleMenuItems: false,
19      toggleMenuTitle: false,
20      toggleMenuLocation: false,
21      tabActive: 0,
22      tabAddition: false,
23      tablistAriaLabel: 'tabs',
24      removeHeading: false,
25      animationSpeed: 0,
26      responsive: false,
27      breakpointMin: '0',
28      breakpointMax: '999999'
29    }, options);
30
31    return $(once('tabs', this)).each(function() {
32      new lt.classes.Tabs($(this), settings);
33    });
34  };
35
36  lt.classes.Tabs = function(element, settings) {
37    this.status = false;
38    this.element = element;
39    this.settings = settings;
40    this.resizeTimer = null;
41
42    if (this.element.length && this.element.find(this.settings.toggleMenuItems).length > 1) {
43      this.toggle();
44
45      if (this.settings.responsive) {
46        var that = this;
47        var width = $(window).width();
48        var height = $(window).height();
49        $(window).resize(function (e) {
50          if ($(window).width() != width || $(window).height() != height) {
51            that.resizeTimer = setTimeout(function() {
52              that.toggle()
53            }, 250);
54          }
55        });
56        window.addEventListener("orientationchange", function (e) {
57          that.toggle();
58        });
59      }
60    }
61  };
62
63  lt.classes.Tabs.prototype.toggle = function() {
64    var minRes = this.settings.breakpointMin;
65    var maxRes = this.settings.breakpointMax;
66
67    var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
68    if (browserWidth > minRes && browserWidth < maxRes) {
69      if (!this.status) {
70        this.apply();
71      }
72    }
73    else {
74      if (this.status) {
75        this.destroy();
76      }
77    }
78  };
79
80  // Open from hash.
81  lt.classes.Tabs.prototype.openHash = function() {
82    var newHash = ('tab-' + location.hash.substr(1));
83    var tabLinks = $('[aria-controls="' + newHash + '"]').closest('.tabs-toggler').find('.tab-nav-link');
84    tabLinks.removeClass('active').attr({'aria-selected' : 'false', 'tabindex': -1 });
85    $('[aria-controls="' + newHash + '"]').addClass('active').attr({'aria-selected' : 'true', 'tabindex': 0 });
86    $('#' + newHash).show(this.settings.animationSpeed).siblings('.tab-content').hide(this.settings.animationSpeed);
87    location.hash = newHash.substr(4);
88  };
89
90  lt.classes.Tabs.prototype.apply = function() {
91    // Wrap elements and add id.
92    var that = this;
93
94    var currentHash = '';
95    if (location.hash.length > 0) {
96      currentHash = 'tab-' + location.hash.substr(1);
97    }
98
99    var tabHeading = this.element.find(this.settings.toggleMenuItems).each(function() {
100      // Add a sibling if desired. Only the first one will be added.
101      if (that.settings.tabAddition) {
102        $(this).siblings(that.settings.tabAddition + ':first').andSelf().wrapAll('<div></div>');
103      }
104      else {
105        $(this).wrapAll('<div></div>');
106      }
107      // Create title and prevent double id's.
108      var title = $(this).parent().find(that.settings.toggleMenuTitle).text();
109      $(this).parent().attr('id', 'tab-' + that.uniqueHtmlId(title));
110    });
111    // Define tab-content.
112    var tabContent = $(tabHeading).parent();
113
114    // Create the tabs-toggler.
115    var tabsToggler = $('<div class="tabs-toggler"><ul class="content-list" role="tablist" aria-label="' + this.settings.tablistAriaLabel + '"></ul></div>');
116    $(once('tabs', tabContent)).each(function(i) {
117      $(this).attr({
118        'class' : 'tab-content',
119        'role': 'tabpanel',
120        'aria-labelledby': 'tab' + (i + 1)
121      });
122      var tabName = $(this).attr('id');
123      if (tabName == currentHash) {
124        that.settings.tabActive = i;
125      }
126      var tabTitle = $(this).find(that.settings.toggleMenuTitle).text();
127
128      var tabLi = $('<li>').attr({
129        'class': 'tab',
130        'role': 'presentation'
131      }).css('cursor', 'pointer');
132      var tabLink = $('<a>').attr({
133        'href': '#' + tabName,
134        'id': 'tab' + (i + 1),
135        'class': 'tab-nav-link',
136        'role': 'tab',
137        'tabindex' : -1,
138        'aria-controls': tabName
139      }).text(tabTitle);
140      tabLink.appendTo(tabLi);
141      tabLi.appendTo(tabsToggler.children('ul'));
142    }).not(':eq(' + this.settings.tabActive + ')').hide();
143
144    tabsToggler.find('ul li:eq(' + this.settings.tabActive + ') a').attr('tabindex', 0);
145
146    // Remove headings if wanted.
147    if (this.settings.removeHeading) {
148      this.element.find(this.settings.toggleMenuTitle).remove();
149    }
150
151    // Place the tabs-toggler after the heading.
152    if (this.settings.toggleMenuLocation) {
153      this.element.children(this.settings.toggleMenuLocation).after(tabsToggler);
154    }
155    else {
156      this.element.prepend(tabsToggler);
157    }
158
159    var tabLinks = $(tabsToggler).find('.tab-nav-link');
160
161    // Make given item active.
162    $(tabsToggler).find('li:eq(' + this.settings.tabActive + ') .tab-nav-link').addClass('active').attr('aria-selected', 'true');
163    $(tabsToggler).find('li .tab-nav-link').not('[aria-selected="true"]').attr('aria-selected', 'false');
164
165    // Tabs-toggler behaviour.
166    tabLinks.click(function(e) {
167      // We only need to update the hash, the rest is done by
168      // lt.classes.Tabs.prototype.openHash via eventListener hashchange.
169      var target = $(this).attr('aria-controls');
170      location.hash = target.substr(4);
171      e.preventDefault();
172    });
173
174    // Respond to the Enter key on the tabs.
175    $(".tab-nav-link").keyup(function(event){
176      if (event.keyCode == 13) {
177        $(this).click();
178      }
179    });
180
181    // When tablinks have focus, make other items accessible via left and right key.
182    var tabLinksNumberOfItems = tabLinks.length - 1;
183    var tabLinksActiveItem = that.settings.tabActive;
184    tabLinks.each(function(i) {
185      this.addEventListener('keydown', function(e) {
186        // Left.
187        if (event.keyCode == 37) {
188          if (tabLinksActiveItem < 1) {
189            $(tabLinks[tabLinksNumberOfItems]).click().focus();
190            tabLinksActiveItem = tabLinksNumberOfItems;
191          } else {
192            $(tabLinks[tabLinksActiveItem - 1]).click().focus();
193            tabLinksActiveItem--;
194          }
195        }
196        // Right.
197        if (event.keyCode == 39) {
198          if (tabLinksActiveItem < tabLinksNumberOfItems) {
199            $(tabLinks[tabLinksActiveItem + 1]).click().focus();
200            tabLinksActiveItem++;
201          } else {
202            $(tabLinks[0]).click().focus();
203            tabLinksActiveItem = 0;
204          }
205        }
206      });
207    });
208
209    // On pageload openHash.
210    that.openHash();
211
212    // Act on hashchange.
213    window.addEventListener('hashchange', function() {
214      that.openHash();
215    });
216
217    this.status = true;
218  };
219
220  lt.classes.Tabs.prototype.destroy = function() {
221    this.element.find('.tabs-toggler').remove();
222    this.element.find('.tab-content').find('> *').unwrap();
223    this.status = false;
224    lt.data.Tabs.usedID = {};
225  };
226
227  lt.classes.Tabs.prototype.uniqueHtmlId = function(text) {
228    var id = lt.helpers.cleanAttrName(text);
229    if (lt.data.Tabs.usedID[id]) {
230      lt.data.Tabs.usedID[id].count++;
231      return id + '--tabs-' + lt.data.Tabs.usedID[id].count;
232    }
233    else {
234      lt.data.Tabs.usedID[id] = {};
235      lt.data.Tabs.usedID[id].count = 1;
236      return id + '--tabs';
237    }
238  };
239
240}(jQuery));

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.