Scrolling Tabs in Bootstrap 4 - javascript

I am working on scrolling tab. Below is my code. I am facing problem that I am not able to click middle tabs. On right button click tabs scrolls move it gradually. What should I do to move tabs gradually? Please help
var hidWidth;
var scrollBarWidths = 40;
var widthOfList = function() {
var itemsWidth = 0;
$('.list a').each(function() {
var itemWidth = $(this).outerWidth();
itemsWidth += itemWidth;
});
return itemsWidth;
};
var widthOfHidden = function() {
return (($('.wrapper').outerWidth()) - widthOfList() - getLeftPosi()) - scrollBarWidths;
};
var getLeftPosi = function() {
return $('.list').position().left;
};
var reAdjust = function() {
if (($('.wrapper').outerWidth()) < widthOfList()) {
$('.scroller-right').show().css('display', 'flex');
} else {
$('.scroller-right').hide();
}
if (getLeftPosi() < 0) {
$('.scroller-left').show().css('display', 'flex');
} else {
$('.item').animate({
left: "-=" + getLeftPosi() + "px"
}, 'slow');
$('.scroller-left').hide();
}
}
reAdjust();
$(window).on('resize', function(e) {
reAdjust();
});
$('.scroller-right').click(function() {
$('.scroller-left').fadeIn('slow');
$('.scroller-right').fadeOut('slow');
$('.list').animate({
left: "+=" + widthOfHidden() + "px"
}, 'slow', function() {
});
});
$('.scroller-left').click(function() {
$('.scroller-right').fadeIn('slow');
$('.scroller-left').fadeOut('slow');
$('.list').animate({
left: "-=" + getLeftPosi() + "px"
}, 'slow', function() {
});
});
Fiddle http://jsfiddle.net/vedankita/2uswn4od/13
Help me to scroll slowly on button click so that I can click on ease tab. Thanks

You should incrementally move the tabs "width of hidden", but no more than wrapper width...
var widthOfHidden = function(){
var ww = 0 - $('.wrapper').outerWidth();
var hw = (($('.wrapper').outerWidth())-widthOfList()-getLeftPosi())-scrollBarWidths;
if (ww>hw) {
return ww;
}
else {
return hw;
}
};
var getLeftPosi = function(){
var ww = 0 - $('.wrapper').outerWidth();
var lp = $('.list').position().left;
if (ww>lp) {
return ww;
}
else {
return lp;
}
};
And then "readjust" after each movement to determine whether or not the scroll arrows still need to show...
$('.scroller-right').click(function() {
$('.scroller-left').fadeIn('slow');
$('.scroller-right').fadeOut('slow');
$('.list').animate({left:"+="+widthOfHidden()+"px"},'slow',function(){
reAdjust();
});
});
$('.scroller-left').click(function() {
$('.scroller-right').fadeIn('slow');
$('.scroller-left').fadeOut('slow');
$('.list').animate({left:"-="+getLeftPosi()+"px"},'slow',function(){
reAdjust();
});
});
Demo: https://www.codeply.com/go/Loo3CqsA7T
Also, you can improve the position of the last tab by making sure it's right position is never less than wrapper width to keep it aligned to the right edge...
var widthOfHidden = function(){
var ww = 0 - $('.wrapper').outerWidth();
var hw = (($('.wrapper').outerWidth())-widthOfList()-getLeftPosi())-scrollBarWidths;
var rp = $(document).width() - ($('.nav-item.nav-link').last().offset().left + $('.nav-item.nav-link').last().outerWidth());
if (ww>hw) {
return (rp>ww?rp:ww);
}
else {
return (rp>hw?rp:hw);
}
};

https://embed.plnkr.co/NcdGqX/
Look at this example. this tabs move gradually. and also you can use bootstrap 4.
I hope it might be helpful.

Related

Issue with jQuery-based carousel and window resize

I have a weird bug in my code that is causing my carousel to act funny if the window is resized.
I haven't been able to pin-point what may be causing the issue, but if you run the code and then resize the window, the carousel will start to move back and forth rapidly, avoiding the 10-second timer that I have placed on it.
Here is a link to my example fiddle: https://jsfiddle.net/zeropsi/ufvLn25b/
Any thoughts?
The trouble is when window is being resized, the window.resize gets triggered a number of times and because of that carousel keeps sliding rapidly. I searched for 'jquery window resize trigger once complete' and found help. This is how I modified your code from the fiddle.
<script>
$(document).ready(function() {
$(document).on("click", ".carousel-indicators li", function() {
$(".carousel-indicators li").removeClass("active");
var a = $(this).data("slide");
$(this).addClass("active");
$("div#billboards").animate({
"left": (a * -100) + "%"
});
$(".billboard").removeClass("active");
$(".billboard[data-billboard='" + a + "']").addClass("active");
return false;
});
// var resizeTimer;
//
// $(window).on("resize", function() {
// console.log("window resized");
//
// clearTimeout(resizeTimer);
// resizeTimer = setTimeout(function() {
// // run code here, resizing has stopped
// BillboardCarousel.init();
// },10000);
//
// });
var id;
$(window).on("resize", function() {
clearTimeout(id);
id = setTimeout(doneResizing, 500);
});
function doneResizing(){
BillboardCarousel.init();
}
if ($("section#carousel").length === 1) {
BillboardCarousel.init();
}
});
var BillboardCarousel = {
init: function() {
BillboardCarousel.resize();
},
imagesLoaded: function() {
var imagesLoaded = 0;
$(".billboard").each(function() {
var image = new Image();
image.src = $(this).data("image");
image.onload = function() {
imagesLoaded++;
if (imagesLoaded === $(".billboard").length) {
BillboardCarousel.startCarousel();
}
};
});
},
startCarousel: function() {
var interval = parseInt($("div#billboards").data('interval'));
window.setInterval(function() {
BillboardCarousel.timer();
}, 10000);
},
resize: function() {
var a = $(".billboard").length;
var b = $(window).width();
$(".billboard").css({
"width": b + "px",
"float": "left",
"display": "inline-block"
});
$("div#billboards").css({
"width": a * 100 + "%",
"left": "0%"
});
$("div#billboards").attr("data-interval", 10000);
BillboardCarousel.imagesLoaded();
},
timer: function() {
var a = $(".billboard.active").data("billboard");
a++;
if (a >= $(".billboard").length) {
a = 0;
}
$(".billboard").removeClass("active");
$(".carousel-indicators li").removeClass("active");
$(".billboard[data-billboard='" + a + "']").addClass("active");
$(".carousel-indicators li[data-slide='" + a + "']").addClass("active");
$("div#billboards").animate({ "left": (a * -100) + "%" });
}
};
</script>
These are a few helpful links -
JQuery: How to call RESIZE event only once it's FINISHED resizing?
http://jsfiddle.net/Zevan/c9UE5/1/
https://css-tricks.com/snippets/jquery/done-resizing-event/

Toggling height of single div in group of divs

I have a number of divs with the same class on one page. I would like them to have a fixed height which expands to full height when clicking a toggle button. So far I have assembled a script from the internet which sort of does that, but currently it expands ALL divs on the page, not just the one div associated with the expand buttons. Could someone help me fix the script so it only expands one div, possibly resets the other one if it is expanded and toggles it back when the expand button is click again?
jQuery(document).ready(function($) {
$.fn.toggleClick = function() {
var functions = arguments;
return this.click(function() {
var iteration = $(this).data('iteration') || 0;
functions[iteration].apply(this, arguments);
iteration = (iteration + 1) % functions.length;
$(this).data('iteration', iteration);
});
};
var $dscr = $(".textblock"),
$switch = $(".expand a"),
$initHeight = 130; // Initial height
$dscr.each(function() {
$.data(this, "realHeight", $(this).height()); // Create new property realHeight
}).css({ overflow: "hidden", height: $initHeight + 'px' });
$switch.toggleClick(function() {
$dscr.animate({ height: $dscr.data("realHeight") }, 300);
$switch.html("-");
}, function() {
$dscr.animate({ height: $initHeight}, 300);
$switch.html("+");
});
});
See my jsfiddle for the script so far:
http://jsfiddle.net/N9DfH/1/
http://jsfiddle.net/N9DfH/21/
jQuery(document).ready(function () {
$.fn.toggleClick = function () {
var functions = arguments;
return this.each(function () {
var divel = $(this);
$('.expand a', divel.parent()).click(function () {
var iteration = $(this).data('iteration') || 0;
functions[iteration].apply(divel, arguments);
iteration = (iteration + 1) % functions.length;
$(this).data('iteration', iteration);
});
});
};
var $dscr = $(".textblock"),
$initHeight = 130; // Initial height
$dscr.each(function () {
$.data(this, "realHeight", $(this).height()); // Create new property realHeight
}).css({
overflow: "hidden",
height: $initHeight + 'px'
}).toggleClick(function () {
this.animate({
height: this.data("realHeight")
}, 300);
}, function () {
this.animate({
height: $initHeight
}, 300);
});
});

jQuery animate() doesn't correctly animate height the second time

I have built a toggle that will slide down a div to reveal content. I am not using the normal toggle() function of jQuery because I wanted to show the top 300px of content and then slide to reveal the rest.
Anyways, I have a script setup that animates the height of the container div, which reveals the content inside.
function slideCut() {
var revertHeight = 300;
var finalHeight = 0;
var s = 1000;
$('.cutBottom a').click(function() {
event.stopPropagation();
var p = $(this).parent().parent();
var h = p.css('height', 'auto').height();
var cut = $(this).parent().find('.cutRepeat');
// Fix height
if (finalHeight == 0) {
p.css('height', 'auto');
finalHeight = p.height();
p.height(revertHeight);
}
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
p.animate({height:revertHeight}, {
duration: s
});
cut.fadeIn('fast');
} else {
$(this).addClass('toggled');
p.animate({height:finalHeight}, {
duration: s,
complete: function() {
cut.fadeOut('fast');
}
});
}
return false;
});
}//end
The problem is, the second time it animates the height to the full size (sliding the div to reveal content) it does not animate, it just jumps to the full height. Why is this happening?
Working example: http://jsfiddle.net/6xp2Y/3/
After all that hard work and fiddle being broken, all we had to do was remove one line from your code:
function slideCut() {
var revertHeight = 300;
var finalHeight = 0;
var s = 1000;
$('.cutBottom a').click(function() {
event.stopPropagation();
var p = $(this).parent().parent();
//var h = p.css('height', 'auto').height(); //REMOVE THIS LINE
var cut = $(this).parent().find('.cutRepeat');
// Fix height
if (finalHeight == 0) {
p.css('height', 'auto');
finalHeight = p.height();
p.height(revertHeight);
}
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
p.animate({height:revertHeight}, {
duration: s
});
cut.fadeIn('fast');
} else {
$(this).addClass('toggled');
p.animate({height:finalHeight}, {
duration: s,
complete: function() {
cut.fadeOut('fast');
}
});
}
return false;
});
}//end
slideCut();
Updated your fiddle: http://jsfiddle.net/brandonscript/6xp2Y/5/
Updated answer!
The proplem lies here
if (finalHeight == 0) {
parent.css('height', 'auto');
finalHeight = parent.height();
parent.height(revertHeight);
console.log('finalHeight:'+finalHeight);
}
This is only running at the beginning, because finalHeight is not 0 anymore after first run.
You can fix this by setting finalHeight back to 0 after closing it again, like so
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
parent.animate({height:revertHeight}, {
duration: speed
});
cut.fadeIn('fast');
finalHeight = 0;
} else { [...]

How can I make a div appear over specific area tags on an image on mouseover?

I have some javascript that moves an image continuously left. When you mouseover the image, I want the scrolling to stop, and I want a slightly transparent div with some custom text to appear over whatever area tag your mouse is over.
Here is the JS I'm using, and I commented out where things should happen. How would I do this?
$(document).ready(function() {
var date = new Date();
var style = "day"
if (date.getHours() >= 17 && date.getHours() <=5) {
style="night";
}
setInterval(wells_fancy_slider, 50);
$('area').hover(function() {
// here is where the code should go
paused = true;
}, function() {
// here is where you hide the div
paused = false;
})
})
function wells_fancy_slider() {
if (!paused) {
if (parseInt($('#pic1').css('left')) < -2770) {
$('#pic1').css('left', '5586');
}
if (parseInt($('#pic2').css('left')) < -2770) {
$('#pic2').css('left', '5586');
}
if (parseInt($('#pic3').css('left')) < -2770) {
$('#pic3').css('left', '5586');
}
$('#pic1, #pic2, #pic3').css('left', '-=5');
}
}
Not sure it will fit your needs:
CSS:
#mydiv{position:absolute;display:none}
$('area').hover(function() {
$('mydiv').offset({ top: $(this).offset().top, left: $(this).offset().left}).fadeIn();
paused = true;
}, function() {
$('#mydiv').hide();
paused = false;
})
Try this one..
t = setInterval(wells_fancy_slider, 50);
$('#area').hover(function(e) {
clearInterval(t);
var parentOffset = $(this).offset(); // or $(this).parent().offset();
var x = e.pageX - parentOffset.left;
var y = e.pageY - parentOffset.top;
paused = true;
}, function() {
clearInterval(t);
t = setInterval(wells_fancy_slider, 50);
paused = false;
});

Drag and Drop -JQuery

Im creating myself a drag functions just for my personal use so I can drag elements around. I'm having a problem. At the moment trying to make the drag so one you pick up the element you can drag it but once you drop it, it goes back to the original position. This is not working as you can see here. When I let go of #drag2 or #drag3 then it goes to the position of #drag1.
My Function:
function drag(el) {
var position = $(el).position();
var ptop = position.top;
var pleft = position.left;
var down = false;
$(el).mousedown(function(event) {
down = true;
$(this).css({
cursor: 'crosshair',
});
$(this).mousemove(function(event) {
if (down == true) {
$(this).css({
cursor: 'crosshair',
});
var w = $(this).width();
var h = $(this).height();
var left3 = (w / 2) + 7;
var top3 = (h / 2) + 7;
$(this).css({
cursor: 'crosshair',
left: (event.clientX) + (3 * 3) - left3,
top: (event.clientY) + (3 * 3) - top3
});
}
}).mouseup(function() {
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: ptop,
left: pleft
}, 300);
});
});
}
I have to get the old position:
var position = $(el).position();
var ptop = position.top;
var pleft = position.left;
So should it not get the position of all of them and bring them self back to where they were? Any help will be appreciated.
EDIT: I DO NOT WANT TO USE ANY PLUGIN OR JQUERY UI, THANKS ANYWAYS
The solution is very simple
See this fiddle: http://jsfiddle.net/BggPn/4/
you define 1 var for left and 1 for top. All 3 the elements use the same variables. If you loop through the elements then you make a new scope where each element has it's own vars.
Working code:
$(document).ready(function() {
drag('#drag, #drag2, #drag3')
});
function drag(el) {
$(el).each(function(){
var position = $(this).position();
var ptop = position.top;
var pleft = position.left;
var down = false;
$(this).mousedown(function(event) {
down = true;
$(this).css({
cursor: 'crosshair',
});
$(this).mousemove(function(event) {
if (down == true) {
$(this).css({
cursor: 'crosshair',
});
var w = $(this).width();
var h = $(this).height();
var left3 = (w / 2) + 7;
var top3 = (h / 2) + 7;
$(this).css({
cursor: 'crosshair',
left: (event.clientX) + (3 * 3) - left3,
top: (event.clientY) + (3 * 3) - top3
});
}
}).mouseup(function() {
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: ptop,
left: pleft
}, 300);
});
});
});
}
Make it a plugin:
$.fn.drag = function drag(){
return this.each(function(){
var position = $(this).position();
var ptop = position.top;
var pleft = position.left;
var down = false;
$(this).mousedown(function(event) {
down = true;
$(this).css({
cursor: 'crosshair',
});
$(this).mousemove(function(event) {
if (down == true) {
$(this).css({
cursor: 'crosshair',
});
var w = $(this).width();
var h = $(this).height();
var left3 = (w / 2) + 7;
var top3 = (h / 2) + 7;
$(this).css({
cursor: 'crosshair',
left: (event.clientX) + (3 * 3) - left3,
top: (event.clientY) + (3 * 3) - top3
});
}
}).mouseup(function() {
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: ptop,
left: pleft
}, 300);
});
});
});
}
Now you can call it by:
$("#drag1, #drag2").drag();
2 thoughts:
1.) Why don't you use jQuery UI (draggable)?
2.) The idea of giving a selector in stead of an element is wrong, a selector can lead to multiple elements, and that's the first reason why it's failing. If you start with
function drag(selector) {
$(selector).each(function() {
var el = $(this);
//rest of code
}
}
it would be better. But I think you'll run into a few other problems eventually
The problem is whenever you're sending in the list of selectors '#drag, #drag2. #drag3' and your position variable only cares about the first one (try changing the order and you'll see they snap to the first in the list). If you want to go about it this way then you'll want to perform an each iteration over them to get the right values.
get the current position of div after drag and set via this
.mouseup(function() {
var position = $(this).position();
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: position.top,
left: position.left
}, 300);
DEMO
why don't you use drag and drop plugin. see this article
http://viralpatel.net/blogs/2009/05/implement-drag-and-drop-example-jquery-javascript-html.html
or this one
http://plugins.jquery.com/project/dragndrop

Categories