PageSourceSearch

https://grandawards.ru/wp-content/themes/npbk/assets/js/_1_tabs.js?ver=2.4.9

js grandawards.ru collected 2026-10-02 17:40:06 UTC 5,620 bytes, 128 lines download raw bytes

1// File#: _1_tabs
2// Usage: codyhouse.co/license
3(function() {
4    var Tab = function(element) {
5      this.element = element;
6      this.tabList = this.element.getElementsByClassName('js-tabs__controls')[0];
7      this.listItems = this.tabList.getElementsByTagName('li');
8      this.triggers = this.tabList.getElementsByTagName('a');
9      this.panelsList = this.element.getElementsByClassName('js-tabs__panels')[0];
10      this.panels = Util.getChildrenByClassName(this.panelsList, 'js-tabs__panel');
11      this.hideClass = 'is-hidden';
12      this.customShowClass = this.element.getAttribute('data-show-panel-class') ? this.element.getAttribute('data-show-panel-class') : false;
13      this.layout = this.element.getAttribute('data-tabs-layout') ? this.element.getAttribute('data-tabs-layout') : 'horizontal';
14      // deep linking options
15      this.deepLinkOn = this.element.getAttribute('data-deep-link') == 'on';
16      // init tabs
17      this.initTab();
18    };
19  
20    Tab.prototype.initTab = function() {
21      //set initial aria attributes
22      this.tabList.setAttribute('role', 'tablist');
23      for( var i = 0; i < this.triggers.length; i++) {
24        var bool = (i == 0),
25          panelId = this.panels[i].getAttribute('id');
26        this.listItems[i].setAttribute('role', 'presentation');
27        Util.setAttributes(this.triggers[i], {'role': 'tab', 'aria-selected': bool, 'aria-controls': panelId, 'id': 'tab-'+panelId});
28        Util.addClass(this.triggers[i], 'js-tabs__trigger'); 
29        Util.setAttributes(this.panels[i], {'role': 'tabpanel', 'aria-labelledby': 'tab-'+panelId});
30        Util.toggleClass(this.panels[i], this.hideClass, !bool);
31  
32        if(!bool) this.triggers[i].setAttribute('tabindex', '-1'); 
33      }
34  
35      //listen for Tab events
36      this.initTabEvents();
37  
38      // check deep linking option
39      this.initDeepLink();
40    };
41  
42    Tab.prototype.initTabEvents = function() {
43      var self = this;
44      //click on a new tab -> select content
45      this.tabList.addEventListener('click', function(event) {
46        if( event.target.closest('.js-tabs__trigger') ) self.triggerTab(event.target.closest('.js-tabs__trigger'), event);
47      });
48      //arrow keys to navigate through tabs 
49      this.tabList.addEventListener('keydown', function(event) {
50        ;
51        if( !event.target.closest('.js-tabs__trigger') ) return;
52        if( tabNavigateNext(event, self.layout) ) {
53          event.preventDefault();
54          self.selectNewTab('next');
55        } else if( tabNavigatePrev(event, self.layout) ) {
56          event.preventDefault();
57          self.selectNewTab('prev');
58        }
59      });
60    };
61  
62    Tab.prototype.selectNewTab = function(direction) {
63      var selectedTab = this.tabList.querySelector('[aria-selected="true"]'),
64        index = Util.getIndexInArray(this.triggers, selectedTab);
65      index = (direction == 'next') ? index + 1 : index - 1;
66      //make sure index is in the correct interval 
67      //-> from last element go to first using the right arrow, from first element go to last using the left arrow
68      if(index < 0) index = this.listItems.length - 1;
69      if(index >= this.listItems.length) index = 0;	
70      this.triggerTab(this.triggers[index]);
71      this.triggers[index].focus();
72    };
73  
74    Tab.prototype.triggerTab = function(tabTrigger, event) {
75      var self = this;
76      event && event.preventDefault();	
77      var index = Util.getIndexInArray(this.triggers, tabTrigger);
78      //no need to do anything if tab was already selected
79      if(this.triggers[index].getAttribute('aria-selected') == 'true') return;
80      
81      for( var i = 0; i < this.triggers.length; i++) {
82        var bool = (i == index);
83        Util.toggleClass(this.panels[i], this.hideClass, !bool);
84        if(this.customShowClass) Util.toggleClass(this.panels[i], this.customShowClass, bool);
85        this.triggers[i].setAttribute('aria-selected', bool);
86        bool ? this.triggers[i].setAttribute('tabindex', '0') : this.triggers[i].setAttribute('tabindex', '-1');
87      }
88  
89      // update url if deepLink is on
90      if(this.deepLinkOn) {
91        history.replaceState(null, '', '#'+tabTrigger.getAttribute('aria-controls'));
92      }
93    };
94  
95    Tab.prototype.initDeepLink = function() {
96      if(!this.deepLinkOn) return;
97      var hash = window.location.hash.substr(1);
98      var self = this;
99      if(!hash || hash == '') return;
100      for(var i = 0; i < this.panels.length; i++) {
101        if(this.panels[i].getAttribute('id') == hash) {
102          this.triggerTab(this.triggers[i], false);
103          setTimeout(function(){self.panels[i].scrollIntoView(true);});
104          break;
105        }
106      };
107    };
108  
109    function tabNavigateNext(event, layout) {
110      if(layout == 'horizontal' && (event.keyCode && event.keyCode == 39 || event.key && event.key == 'ArrowRight')) {return true;}
111      else if(layout == 'vertical' && (event.keyCode && event.keyCode == 40 || event.key && event.key == 'ArrowDown')) {return true;}
112      else {return false;}
113    };
114  
115    function tabNavigatePrev(event, layout) {
116      if(layout == 'horizontal' && (event.keyCode && event.keyCode == 37 || event.key && event.key == 'ArrowLeft')) {return true;}
117      else if(layout == 'vertical' && (event.keyCode && event.keyCode == 38 || event.key && event.key == 'ArrowUp')) {return true;}
118      else {return false;}
119    };
120    
121    //initialize the Tab objects
122    var tabs = document.getElementsByClassName('js-tabs');
123    if( tabs.length > 0 ) {
124      for( var i = 0; i < tabs.length; i++) {
125        (function(i){new Tab(tabs[i]);})(i);
126      }
127    }
128  }());

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.