Page MenuHomeIn-Portal Phabricator

tab_scroller.js
No OneTemporary

File Metadata

Created
Thu, Oct 29, 6:27 AM

tab_scroller.js

var aTabScroller = null;
function TabScroller() {
this.tabs = [];
this.spacerWidth = $('td.tab-spacer:first').width();
this.viewPort = $('div.tab-viewport');
this.viewPortWidth = 0;
this.totalWidth = 0;
var $scroller = this;
$(window).resize(
function () {
$scroller.resize();
}
);
$('a.scroll-left').click(
function ($e) {
$scroller.scrollLeft();
$e.preventDefault();
}
)
$('a.scroll-right').click(
function ($e) {
$scroller.scrollRight();
$e.preventDefault();
}
)
}
TabScroller.prototype.resize = function ($affect_navigation) {
var $tab_measure = $('#tab-measure');
this.viewPort.hide();
var $width = $tab_measure.show().width();
$tab_measure.hide();
this.viewPort.show().width($width - 40); // 40 (2 margins with 20px width)
this.viewPortWidth = this.viewPort.outerWidth();
if ($affect_navigation === undefined || $affect_navigation === true) {
this.affectNavigation();
}
}
TabScroller.prototype.searchTabs = function () {
if (this.viewPort.length == 0) {
return ;
}
var $scroller = this;
$('a.tab-link', '.tabs').each (
function () {
var $link = $(this);
var $link_container = $link.parents(':first');
$scroller.addTab(
{
width: $link_container.outerWidth(),
active: $link_container.hasClass('tab-active')
}
);
}
);
// preselect tab
this.preselectTab();
}
TabScroller.prototype.preselectTab = function () {
var $total = 0;
for (var $i = 0; $i < this.tabs.length; $i++) {
$total += this.tabs[$i].width;
if (this.tabs[$i].active) {
var $new_start = $total - this.tabs[$i].width;
// move 1 tab left from selected tab (including spacers)
for (var $j = $i - 1; $j > $i - 3 && $j >= 0; $j--) {
$new_start -= this.tabs[$j].width;
}
this.viewPort.scrollLeft($new_start);
this.affectNavigation();
break;
}
}
}
TabScroller.prototype.addTab = function ($tab) {
$tab.width += this.spacerWidth;
this.tabs.push($tab);
this.totalWidth += $tab.width;
// console.log('adding tab: ', $tab);
}
TabScroller.prototype.affectNavigation = function () {
var $start = this.viewPort.scrollLeft();
var $prev = $('a.scroll-left');
var $next = $('a.scroll-right');
if ($start == 0) {
$prev.addClass('disabled');
}
else {
$prev.removeClass('disabled');
}
if ($start + this.viewPortWidth >= this.totalWidth) {
$next.addClass('disabled');
}
else {
$next.removeClass('disabled');
}
}
TabScroller.prototype.scrollLeft = function () {
var $total = 0;
var $start = this.viewPort.scrollLeft();
var $end = $start + this.viewPortWidth;
var $scroller = this;
for (var $i = 0; $i < this.tabs.length; $i++) {
$total += this.tabs[$i].width;
if ($total >= $start) {
var $new_start = $total - this.tabs[$i].width;
var $diff = Math.abs($new_start - $start);
if ($diff > 0 && $diff <= this.spacerWidth) {
// console.log('skipping left');
continue;
}
this.viewPort.animate(
{scrollLeft: $new_start}, 'slow',
function() {
$scroller.affectNavigation();
}
); // .scrollLeft($start);
break;
}
}
}
TabScroller.prototype.scrollRight = function () {
var $total = 0;
var $start = this.viewPort.scrollLeft();
var $end = $start + this.viewPortWidth;
var $scroller = this;
for (var $i = 0; $i < this.tabs.length; $i++) {
$total += this.tabs[$i].width;
if ($total > $end) {
var $new_start = $start + ($total - $end);
var $diff = Math.abs($new_start - $start);
if ($diff > 0 && $diff <= this.spacerWidth) {
// console.log('skipping right');
continue;
}
this.viewPort.animate(
{scrollLeft: $new_start}, 'slow',
function() {
$scroller.affectNavigation();
}
); // .scrollLeft($start);
break;
}
}
// console.groupEnd();
}
$(document).ready(
function () {
aTabScroller = new TabScroller();
aTabScroller.resize();
aTabScroller.searchTabs();
}
);
/*2.1.2. Занести все вкладки (ячейки таблицы с классами tab и tab-active) в регистр вкладок (их позиция и ширина).
При нажатии на кнопку next/prev прокручивать список вкладок на одну вкладку вправо/влево + на ширину одно
разделителя вкладок. Если некуда крутить, то прятать кнопки прокрутки. - 1 h*/

Event Timeline