I have multiple sections with the class blockList li throughout each of these sections. How am I able to trigger only the current blockList li items for the ones that are in view? Currently, once any of the list items are in view they all fire throughout the page, even though they are not in view.
The snippet below illustrates the issue I am having.
$('.blockList').waypoint(function() {
$('.blockList li').each(function(index) {
setTimeout(()=>{
$(this).addClass('active');
}, 200*index);
});
}, {
offset: '60%'
});
#blue, #red {
width: 100%;
height: 100vh;
}
#blue {
background: blue;
}
#red {
background: red;
}
.blockList {
margin: 15px 0;
text-align: left;
}
.blockList li {
font-size: 1rem;
color: #FFF;
margin: 20px 0;
opacity: 0;
-webkit-transition: ease 0.4s;transition: ease 0.4s;
-webkit-transform: translateY(-15px);transform: translateY(-15px);
}
.blockList li.active {
opacity: 1;
-webkit-transform: translateY(0px);transform: translateY(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js"></script>
<section id="blue">
<ul class="blockList">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</section>
<section id="red">
<ul class="blockList">
<li>E</li>
<li>F</li>
<li>G</li>
<li>H</li>
</ul>
</section>
You are adding active class to li items for all of them.
$('.blockList li').each(function(index) {
setTimeout(()=>{
$(this).addClass('active');
}, 200*index);
});
TL:TR
In shorter terms. you are basicaly adding active class two times to each list element. Since you are adding it at the begging and then adding it at the 60% offset.
It loops trough all li and puts active class. So therefore it doesnt have to be in view, since its adding on load.
One solution might be getting position in browser of second object, or make a compact system that it checks all of them, places in array.
So it would check its position -> on scroll check if reached any of the elements -> if reached, add active class to the coresponding ID.
var p = $( "#red" ).position;
var Positions = {top: p.top};
Then get the your center window position
Something like:
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - $(this).outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - $(this).outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
Then compare them, if it reached the element.
Then get its id and add .active class to the #red li, not genaraly li.
What I would do in this situation:
var global_list = {}; var elemCount = 0;
$(document).ready(function() {
//call initFunc, after its complete, call elimination (so it would check on load) and then set on scroll.
initFunc(function() {
elimination();
$(document).on('scroll', function() { elimination() });
});
//This function is basicaly your startup.
function initFunc(int) {
$('.blockList').each(function() {
var p = $(this).position(); //Lets get its position.
var id = $(this).attr('id'); //Lets get its ID
global_list[id] = p.top; //Lets asign ID -> topPosition, so { first: 8 }...
elemCount++;
});
int();
}
//This assigns needed stuff for allready reached objects.
function elimination() {
if(elemCount != 0) { //Did we allready show all elements?
var cb = $(this).scrollTop() + ($(this).height()), ct = $(this).scrollTop(); //Gets top position, and bottom.
var cP = ct + ((cb - ct)/2); //Gets your center point of viewport - ad half screen size to top;
for(var k in global_list) { //Loop trough all element that are left and see if we did scroll.
if(global_list[k] <= cP) { //Lets check if user scolled to it.
var ic=0;
$('#'+k+' li').each(function() {
setTimeout(()=>{
$(this).addClass('active');
}, 200*ic);
ic++
});
delete global_list[k]; //Lets delete allready assigned classes
elemCount--; //Decreses elements count, so eventualy once all reached, it becomes 0;
}
}
}
}
});
#first {
height: 1000px;
}
#second {
height: 1000px;
}
.beatiful {
background: yellow;
}
.div_div li {
font-size: 1rem;
color: #000;
margin: 20px 0;
opacity: 0;
-webkit-transition: ease 0.4s;transition: ease 0.4s;
-webkit-transform: translateY(-15px);transform: translateY(-15px);
}
.div_div li.active {
opacity: 1;
-webkit-transform: translateY(0px);transform: translateY(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='div_div' id='first'>
<ul class="blockList" id='first'>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
<div class='div_div' id='second'>
<ul class="blockList" id='second'>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
Related
The thing is that I need to make a vertical images slider,so that when i press arrow down/arrow up every image changes it's position (the highest one goes bottom,the previous take it's place)
what it should look like:
what i have got so far:
$(function(){
var $vsliderboxes = $('#vsliderboxes'),
$vslidernav = $('#vslidernav'),
boxHeight = $vsliderboxes.height(),
current_index = 0;
function clickslide(){
clearInterval(intervalTimer);
clearTimeout(timeoutTimer);
timeoutTimer = setTimeout(function () {
intervalTimer = window.setInterval(autoslide, 2000);
}, 2500);
var index = $(this).index();
current_index = index;
$vsliderboxes.children().stop().animate({
top : (boxHeight * index * -1)
}, 500);
}
function autoslide(){
current_index++;
if (current_index >= $vsliderboxes.children().children().length) {
current_index = 0;
}
$vslidernav.find('a').eq(current_index).trigger('click');
}
$vslidernav.find('a').click(clickslide);
var intervalTimer = window.setInterval(autoslide, 2000),
timeoutTimer = null;
});
#vslidernav ul {
list-style: none;
padding: 0;
}
#vslidernav ul a {
padding: 0;
cursor: pointer;
height: 50px;
}
#vslidernav ul a:active {
color: #9C9A99;
}
#vslidernav ul a li {
height: 50px;
}
#vslidernav ul .active li {
}
.#vslidernav ul a:active {
background: transparent;
color: #9C9A99;
}
.vslider {
display: inline-block;
}
#vslidernav {
float: left;
width: 100px;
z-index: 1;
height: 250px;
}
#vsliderboxes {
position : relative;
overflow : hidden;
}
#vsliderboxes div {
height: 250px;
width: 900px;
}
#vsliderboxs-inner {
position : relative;
width : 900px;
height : 250px;
}
<div class="vslider">
<div id="vslidernav">
<ul>
<a id="1">
<li><img src="img/arrtop.gif"></li>
</a>
<a id="2">
<li><img src="img/arrdown.gif"></li>
</a>
<a id="3">
<li></li>
</a>
</ul>
</div>
<div id="vsliderboxes">
<div id="vsliderboxs-inner">
<div id="box1" class="active"><img src="img/slide1.gif"></div>
<div id="box2" class="inactive"><img src="img/slide2.gif"></div>
<div id="box3" class="inactive"><img src="img/slide3.gif"></div>
</div>
</div>
</div>
thanks for any advice
I think, that it isn't possible to solve this issue like you try to.
Because, when you work with the "top" property, you can't take one image from the top and append it to the other end because appending the image, will move the other images to another place --> the top property wouldn't be correct any more.
I think the contributed sliders (e.g. http://www.jssor.com/demos/vertical-slider.slider) work with the transform CSS property.
transform: translate3d()
Try to research about this property.
Roko C. Buljan answered on this page: loop carousel jquery
He uses a scrollTop loop for your problem.
I've also written a simple slider some time ago. I have now implemented the Roku C. Buljan method. Feel free to look at my code on Bitbucket.
https://bitbucket.org/d-stone/jqueryslider
An excerpt may help you:
value = prev_or_next == 'next' ? self.globals.slide_height : 0;
last = $('#container').find('> div:last');
first = $('#container').find('> div:first');
if(prev_or_next == 'prev') { // click on "next"-button
first.before(last); // put last element before first
settings.elements.inner.scrollTop(self.globals.slide_height); // set the scrollTop to 1 slide-height
}
// animation itself:
$('#container').stop().animate({scrollTop: value}, {
duration: settings.slide_speed,
done: function() {
if(prev_or_next == 'next') {
// put first item after last
last.after(first);
}
}
});
I'd advise you to validate your HTML (W3C Validator). There are some errors inside.
Invalid HTML can be the reason for some CSS and Javascript Errors.
Currently on click of next and prev, the height of the list is adjusting. Instead of increasing and decreasing the height, i want to replace the current content with new set of content.
Expectation:
if I click on next/ prev, current visible list should replace with the new set of items with some slide animation.
Also every time I need to display 3 items, in current scenario once the next/prev iteration is completed, only 2 items are getting visible.
This is what I tried:
JS:
$(document).ready(function () {
size_li = $("#list li").size();
x=3;
$('#list li:lt('+x+')').show();
$('#next').click(function () {
x= (x+3 <= size_li) ? x+3 : size_li;
$('#list li:lt('+x+')').show();
$('#prev').show();
if(x == size_li){
$('#next').hide();
}
});
$('#prev').click(function () {
x=(x-3<0) ? 3 : x-3;
$('#list li').not(':lt('+x+')').hide();
$('#next').show();
if(x < 3){
$('#prev').hide();
}
});
});
JS Fiddle:
Demo Link
I approached the problem a bit differently. Here's the fiddle.
The gist of my solution is that I've used jQuery's animate function to do the smooth scrolling effect:
$('ul').animate({
scrollTop: $('ul').scrollTop() + height_to_show
}, 500);
One catch, however, is that the ul and the li elements need to have fixed heights. These heights are calculated internally based on the following variables set by you:
/**
* Total number of elements in the list
* #type {Number}
*/
var num_of_elems = 8;
/**
* Static height of each element (in pixels)
* #type {Number}
*/
var height_of_elem = 25;
/**
* Number of elements you want to show in the page
* #type {Number}
*/
var num_of_elems_to_show = 3;
/**
* The visible height of the ul
* #type {Number}
*/
var height_to_show = 0; //calculated internally
UPDATE
Here's the updated fiddle.
I've added functionality to hide or show the prev and next button based on the current page being displayed.
/**
* Show or hide the prev and next button depending on the current_page
*/
var show_hide_buttons = function() {
if (current_page === Math.ceil(num_of_elems / num_of_elems_to_show) - 1) {
$('#next').hide();
} else {
$('#next').show();
}
if (current_page === 0) {
$('#prev').hide();
} else {
$('#prev').show();
}
};
I know you have a solution, just wanna leave this fiddle as this is another option and little different animation.
$(document).ready(function () {
$('#list li:lt(3)').show();
$('#next').click(function() {
$('#prev').show();
var last = $('#list').children('li:visible:last');
last.nextAll('#list li:lt(3)').toggle(200);
last.next().prevAll('#list li').hide(200);
var $this = $(this);
if ($('#list li').last().is(':visible')){
$this.hide();
}
});
$('#prev').click(function() {
$('#next').show();
var first = $('#list').children('li:visible:first');
first.prevAll('#list li:lt(3)').toggle(200);
first.prev().nextAll('#list li').hide(200)
var $this = $(this);
if ($('#list li').first().is(':visible')){
$this.hide();
}
});
});
ul,li,ol{
margin: 0;
padding: 0;
list-style-type: none;
}
.l_swiper{
border: 1px solid #333;
width: 50%;
padding: 20px;
}
#list{
overflow: hidden;
max-height: 117px;
}
#list li{
display: none;
padding : 10px;
border-bottom : 1px solid #333;
}
#list li:last-child{
margin-bottom: 39px;
}
#next{
float: right;
border: 1px solid #333;
padding: 10px;
margin-top : 20px;
cursor: pointer;
}
#prev{
float: left;
border: 1px solid #333;
padding: 10px;
margin-top : 20px;
cursor: pointer;
}
.clearfix{
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="l_swiper">
<ul id="list">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<li>Six</li>
<li>Seven</li>
<li>Eight</li>
</ul>
<div id="prev">prev</div>
<div id="next">Next</div>
<div class="clearfix"></div>
</div>
I have a Swiper slider and a counter position like "1/10". I would like to change that current slide number (the 1) with an animation. I know how to replace the number but with this animation, it's like another story:
As you can see on the gif, it's working nicely if I click moderately on my slider, but when I double-triple-or-crazy click on the next link, that totally breaks the counter, due to the clone made in this gif example.
Do you know how can I do that in a better way?
I made a jsfiddle, working for the first count change only:
— http://jsfiddle.net/asb39sff/1/
// Init
var $c_cur = $("#count_cur"),
$c_next = $("#count_next");
TweenLite.set($c_next, {y: 12, opacity: 0}, "count");
// Change counter function
function photos_change(swiper) {
var index = swiper.activeIndex +1,
$current = $(".photo-slide").eq(index),
dur = 0.8,
tl = new TimelineLite();
// Just a test
tl.to($c_cur, dur, {y: -12, opacity: 0}, "count")
.to($c_next, dur, {y: 0, opacity: 1}, "count")
//$c_cur.text(index);
//$c_next.text(index + 1);
}
While I agree with #Tom Sarduy approach and actually would recommend it since it is a one-time creation of HTML elements but just to provide you with another idea, here is what I have been able to create quickly.
CSS changes:
.counter .next, .counter .count {
position:absolute;
}
.counter .next {
transform:translateY(-12px);
left:0;
}
JavaScript changes:
//added before your [photos_change] method
var counter = $('.counter');
var currentCount = $('<span class="count">1<span/>');
counter.append(currentCount);
//
//and then inside your [photos_change] event handler
var prevCount = $('.count');
currentCount = $('<span class="count next">' + index + '<span/>');
counter.append(currentCount);
TweenMax.to(prevCount, dur, {
y: -12,
opacity: 0,
onCompleteParams: [prevCount],
onComplete: function (prevCount) {
prevCount.remove();
},
ease: Power2.easeOut
});
TweenMax.fromTo(currentCount, dur, {
y: 12,
opacity: 0
}, {
y: 0,
opacity: 1,
ease: Power2.easeOut
});
//
So I guess it is up to you to take whichever approach you like i.e. one-time creation of HTML elements on load or on click like the one I am proposing.
Apologies for the ugliness of the code, just something I cooked up in a hurry. Hope it helps in some way though.
I think your HTML structure is not good enough for the animation, so I created my own fiddle with another approach and custom html tags, the animation is done using CSS3 transitions and the numbers are precalculated to avoid fast clicking problems:
Jquery:
$('#change-button').click(function(){
//Getting current slide
var $current = $('.current');
//Remove the class to find next one
$current.removeClass('current');
if($current.is(':last-child')){
//Resetting the counter if is the last child
$('#counter ul li:first').addClass('current');
$('#counter ul').css('top','0px');
}
else{
$current = $current.next();
$current.addClass('current');
//Getting the next number to recalculate
//the new top position
var $num = parseInt($current.text());
$('#counter ul').css('top',-($num-1)*18+'px');
}
});
$('#change-button').click(function(){
var $current = $('.current');
$current.removeClass('current');
if($current.is(':last-child')){
//Resetting the counter
$('#counter ul li:first').addClass('current');
$('#counter ul').css('top','0px');
}
else{
$current = $current.next();
$current.addClass('current');
var $num = parseInt($current.text());
$('#counter ul').css('top',-($num-1)*18+'px');
}
});
.container{
background-color: #000;
padding: 10px;
color: #fff;
width: 300px;
float: left;
}
.container li{
display: inline-block;
vertical-align: middle;
}
#counter{
width: 16px;
height: 18px;
overflow: hidden;
position: relative;
}
#counter ul{
position: absolute;
padding: 0;
margin: 0;
height: 18px;
width: 16px;
transition: all .5s;
}
#counter ul li{
display: block;
clear: both;
text-align: right;
}
#change-button{
margin: 10px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<li>Graphics</li>
<li id="counter">
<ul>
<li class="current">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
</ul>
</li>
<li>/ 4</li>
</div>
<button id="change-button" href="#">Change!</button>
If the animation works for you you will have to integrate it with your code by generating the unordered list with all the values, knowing how many slides you have (should be easy).
My problem is this. I have a fixed left navigation bar and I have to change the list font color based on the background of the section under it. The code is like this fiddle. So if the section is black and is below a link, the text is not seen. I have to change each list based on the background of a section under it so that it can be readable.
html
<div class="content">
<div id="left_side">
<div id="static_menu" class="">
<div id="main_navigation" class="">
<ul class="menu mainLeft" id="mymenu">
<li>Nav list 1</li>
<li>Nav list 2</li>
<li>Nav list 3</li>
<li>Nav list 4</li>
<li>Nav list 5</li>
</ul>
</div>
</div>
</div>
<div id="wrapper">
<div class="section" id="section1">section1</div>
<div class="section" id="section2">section2</div>
<div class="section" id="section3">section3</div>
<div class="section" id="section4">section4</div>
<div class="section" id="section5">section5</div>
</div>
</div>
css
.content{
position:relative;
}
#left_side
{
position:fixed;
left: 20px;
right: 20px;
z-index:999;
}
.mainLeft
{
list-style-type:none;
margin-left:0px;
padding-left:0px;
}
.mainLeft li
{
padding:5px 0;
}
.mainLeft li a
{
color:#000;
margin-bottom:5px;
}
#wrapper
{
position:relative;
}
.section
{
width: 100%;
text-align:center;
padding:150px 0;
border:1px solid #666;
}
#section1
{
background: #fff;
}
#section2
{
background: #000;
color:#fff;
}
#section3
{
background: #fff;
}
#section4
{
background: #000;
color:#fff;
}
#section5
{
background: #fff;
}
Fiddel
To do what you asked for you can do this with jquery:
working fiddle
var _li, _sections;
$(function() {
_li = $("#mymenu").find("li");
_sections = $("#wrapper").find(".section");
$(window).on('scroll', liBgs);
});
function liBgs() {
for (var i = 0; i < _li.length ; i++) {
var _litop = _li.eq(i).offset().top;
for (var j = 0; j < _sections.length; j++) {
var $s = _sections.eq(j),
_sectop = $s.offset().top,
_secbottom = $s.offset().top+$s.height()-20;
if (_litop > _sectop && _litop > _secbottom) {
var _color = rgb2hex($s.css('background-color'));
_li.eq(i).find('a').css('color', (_color=="#ffffff") ? "#000000" : "#ffffff");
}
}
}
}
function rgb2hex(rgb) {
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
NOTE: rgb2hex() function was taken from this question: How to get hex color value rather than RGB value?
What this code does:
I'm basically comparing positions of the menu li's to the sections, checking under what
section each li is over everytime you scroll.. I'm not sure this is very efficient, but for something small scale it's ok.. if anyone knows how to make this even more efficient I'll be happy to learn.
Used jquery to do this. Found a reference here
HTML:
Added a extra attribute of color
<div class="section" id="section1" data-color="#333">section1</div>
JS:
$(window).on('scroll', function() {
var scrollTop = $(this).scrollTop();
$('.section').each(function() {
var topDistance = $(this).offset().top;
if ( (topDistance) < scrollTop ) {
$('#mymenu a').css('color',$(this).attr('data-color'));
}
});
});
DEMO
Can't you just give it a neutral colour to the fixed div and make it wrap around its content rather than have to resort to client scripts to dynamically change the colour? I have sanitized a bit the fixed element to make it look a bit more appealing...padding, margins, etc.
#left_side
{
position:fixed;
left: 20px;
top:10px;
z-index:999;
background-color:#eee;
padding:10px;
}
JS Fiddler Example
Something like this would work:
$(window).scroll(function() {
/* get current scroll-position within window */
var scroll = $(window).scrollTop();
$('.mainLeft li').each(function() {
/* get position of navigation-element (distance from top minus half of it's height, so that it changes color while it's half over black and half over white background) */
var elementPositionTop = parseFloat($(this).offset().top) + (parseFloat($(this).height() / 2));
/* change color for each background-change */
if (elementPositionTop >= 320 && elementPositionTop <= 640 || elementPositionTop >= 960 && elementPositionTop <= 1280) {
$(this).addClass('whiteText');
} else {
$(this).removeClass('whiteText');
}
});
});
Here's the additional CSS:
.mainLeft li.whiteText a {
color: #fff;
}
.section {
height: 18px;
overflow: hidden;
}
I gave the .section divs a fixed height because the JS I used works with fixed pixel values, and not all browsers interpret the height of elements the same if they're not defined...
Here's a fiddle: http://jsfiddle.net/Niffler/z34cG/
Updated.. see this fiddle
Do u Mean like this
$(document).scroll(function(){
var top=$(document).scrollTop()-322;
console.log(top)
if(top<0)
{
$('.mainLeft li a').css('color','black')
$('#li1 a').css('color',$('#section1').css('color'))
//$('#li1 a').css('color',"red")
}
if(top>0 && top<322)
{
$('.mainLeft li a').css('color','black')
$('#li2 a').css('color',$('#section2').css('color'))
//$('#li1 a').css('color',"red")
}
if(top>322 && top<644)
{
$('.mainLeft li a').css('color','black')
$('#li3 a').css('color',$('#section3').css('color'))
//$('#li1 a').css('color',"red")
}
if(top>644 && top<966)
{
$('.mainLeft li a').css('color','black')
$('#li4 a').css('color',$('#section4').css('color'))
//$('#li1 a').css('color',"red")
}
if(top>966 && top<1288)
{
$('.mainLeft li a').css('color','black')
$('#li5 a').css('color',$('#section5').css('color'))
//$('#li1 a').css('color',"red")
}
});
I have a horizontal tab menu. These tabs are all li elements. I show always 5 of them at once. To the left and right I have buttons which scrolls these tabs to either side. I am just not sure how to achieve that. Can I put the next 5 tabs in a different div which will be shown on click? That wouldnt be the best solution, would it? Can I do this somehow with JavaScript or jQuery?
Thanks.
You can do this w/ jQuery. Easier if all of the tabs are the same width. You can position the UL inside a DIV that has overflow: hidden and position: relative. Then the UL can slide around inside the DIV using the animate() method (or the css() method). Check them out on http://api.jquery.com.
Here's an example:
<!DOCTYPE HTML>
<html>
<head>
<style>
* { margin: 0; padding: 0; }
body { padding: 30px; }
div#tabs { width: 360px; height: 30px; overflow: hidden; position: relative; }
ul { display: block; float: left; width: 1080px; position: absolute; left: -360px; }
li { display: block; float: left; width: 70px; height: 30px; font-size: 12px; border: 1px solid #333; }
button { float: left; width: 100px; margin: 20px; }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script>
$(document).ready(function()
{
$("button").click(function()
{
var tabs_list = $("div#tabs > ul");
if($(this).is("#left"))
{
tabs_list.animate({ left: "-=360" }, 500);
}
else if($(this).is("#right"))
{
tabs_list.animate({ left: "+=360" }, 500);
}
});
});
</script>
</head>
<body>
<div id="tabs">
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<li>five</li>
<li>six</li>
<li>seven</li>
<li>eight</li>
<li>nine</li>
<li>ten</li>
<li>eleven</li>
<li>twelve</li>
<li>thirteen</li>
<li>fourteen</li>
<li>fifteen</li>
</ul>
</div>
<button id="left">scroll left</button>
<button id="right">scroll right</button>
</body>
</html>
This would need some more work in order to de-activate or hide the scroll buttons when you've reached the beginning or end of the tabs list, but this should get you started.
I like Elliot's solution. I have another one, which will work if the tabs are of different lengths. It does it by hiding and showing the individual "li"s as you click the "right" and "left" buttons. The code also takes care of moving the tabs 5 at a time, both left and right, and handles the end cases.
<!DOCTYPE HTML>
<html>
<head>
<style>
#left, #right {float: left; position: relative; margin: 0; padding: 0;}
#tabs {float: left; position: relative; list-style: none; margin: 0; padding: 0;}
#tabs li {float: left; display: none; border: 2px solid #000; width: 50px; text-align: center;};
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var tabs = $('#tabs li'), number_of_tabs = tabs.length;
var tabs_visible = Math.min(5, number_of_tabs), low_tab = 0, high_tab = (tabs_visible - 1);
$(tabs).filter(function(index){return (index < tabs_visible);}).show();
$('#left, #right').each(function(){
$(this).click(function(){
if ($(this).is('#right')) {
var high_tab_new = Math.min((high_tab + tabs_visible), (number_of_tabs - 1));
var low_tab_new = high_tab_new - tabs_visible + 1;
$(tabs).filter(function(index){
return (index >= low_tab) && (index < low_tab_new);
}).hide();
$(tabs).filter(function(index){
return (index > high_tab) && (index <= high_tab_new);
}).show();
low_tab = low_tab_new;
high_tab = high_tab_new;
} else {
var low_tab_new = Math.max((low_tab - tabs_visible), 0);
var high_tab_new = low_tab_new + tabs_visible - 1;
$(tabs).filter(function(index){
return (index > high_tab_new) && (index <= high_tab);
}).hide();
$(tabs).filter(function(index){
return (index >= low_tab_new) && (index < low_tab);
}).show();
low_tab = low_tab_new;
high_tab = high_tab_new;
}
});
});
</script>
</head>
<div id="nav3">
<button id="left">left</button>
<ul id="tabs">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
<li>F</li>
<li>G</li>
<li>H</li>
<li>I</li>
</ul>
<button id="right">right</button>
</div>
</body>
</html>
Though I am not sure how would the tab look like, I am assuming that with the 5 tabs you are showing different set of page content.
I am suggesting a simple solution (Design) with Javascript. See if it works.
Have a variable to store the current View index. e.g. _currentView.
Place the content of 5 tabs in 5 views (When I say views there are many ways to establish it, ranging from using div object to using .net multiview control).
By default keep their visibility off.
Create a method, that'll accept the _currentView as the parameter. In this method, just make the current view visible.
On the click of left and right arrow, increment or decrement the _currentView value and call the method that activates the current view.
Please see if this helps you.