Animate my scrollTop function in this code - javascript

I have this function to scroll through a div. The function at this point does exactly what I want it do except for one thing. I want the scrolling to happen animated. How can I implement this in this code?
$(function() {
var ele = $('#scroller');
var scroll = 20;
$('.scroller-btn-up').click(function() {
// Scroll the element up
ele.scrollTop(ele.scrollTop() - scroll);
});
$('.scroller-btn-down').click(function() {
// Scroll the element down
ele.scrollTop(ele.scrollTop() + scroll);
});
$('.scroller-btn-up, .scroller-btn-down').bind({
click: function(e) {
// Prevent the default click action
e.preventDefault();
}
});
});

$(function() {
var ele = $('#scroller');
var scroll = 20;
$('.scroller-btn-up').click(function() {
// Scroll the element up
ele.animate({scrollTop : ele.scrollTop() - scroll});
});
$('.scroller-btn-down').click(function() {
// Scroll the element down
ele.animate({scrollTop : ele.scrollTop() + scroll});
});
$('.scroller-btn-up, .scroller-btn-down').bind({
click: function(e) {
// Prevent the default click action
e.preventDefault();
}
});
});

Related

Item soft rejected due to Proper Event Binding issue

An item I've submitted to themeforest.net got soft rejected with the following message:
PROPER EVENT BINDING: Consider using the preferred .on() method rather than .click(), .bind(), .hover(), etc. For best performance and concise code use event delegation whenever possible
I have no idea what to do actually and would appreciate some help.
This is my code (it’s quite long sorry):
jQuery(document).ready(function($) {
"use strict";
// PRELOADER
$(window).load(function() {
$('#preloader').fadeOut('slow', function() {
$(this).remove();
});
});
// NAV BR RESIZING
$(document).on("scroll", function() {
if ($(document).scrollTop() > 50) {
$("header").removeClass("large").addClass("small");
} else {
$("header").removeClass("small").addClass("large");
}
});
// MOBILE MENU TRIGGER
$('.menu-item').addClass('menu-trigger');
$('.menu-trigger').click(function() {
$('#menu-trigger').toggleClass('clicked');
$('.container').toggleClass('push');
$('.pushmenu').toggleClass('open');
});
// SEARCH
$('.search').click(function(e) {
$(".search-overlay").addClass("visible");
e.preventDefault();
});
$('.close-search').click(function(e) {
$(".search-overlay").removeClass("visible");
e.preventDefault();
});
// FOUNDATION INITIALIZER
$(document).foundation();
// LIGHTCASE
$('a[data-rel^=lightcase]').lightcase({
showSequenceInfo: false,
});
// CONTDOWN
$('[data-countdown]').each(function() {
var $this = $(this),
finalDate = $(this).data('countdown');
$this.countdown(finalDate, function(event) {
$this.html(event.strftime('' +
'<span class="time">%D <span>days</span></span> ' +
'<span class="time">%H <span>hr</span></span> ' +
'<span class="time">%M <span>min</span></span> ' +
'<span class="time">%S <span>sec</span></span>'));
});
});
// SCROLLDOWN BUTTON
$(".show-scrolldown-btn").append("<div class='scrolldown-btn reveal-from-bottom'></div>")
$('.scrolldown-btn').on('click', function() {
var ele = $(this).closest("div");
// this will search within the section
$("html, body").animate({
scrollTop: $(ele).offset().top + 70
}, 500);
return false;
});
// ISOTOPE MASONRY
$(window).load(function() {
var $container = $('.grid');
$container.isotope({
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
});
var $optionSets = $('.filter'),
$optionLinks = $optionSets.find('a');
$optionLinks.click(function() {
var $this = $(this);
if ($this.hasClass('active')) {
return false;
}
var $optionSet = $this.parents('.filter');
$optionSet.find('.active').removeClass('active');
$this.addClass('active');
// make option object dynamically, i.e. { filter: '.my-filter-class' }
var options = {},
key = $optionSet.attr('data-option-key'),
value = $this.attr('data-option-value');
value = value === 'false' ? false : value;
options[key] = value;
if (key === 'layoutMode' && typeof changeLayoutMode === 'function') {
changeLayoutMode($this, options);
} else {
$container.isotope(options);
}
return false;
});
});
//BACK TO TOP
var offset = 300,
offset_opacity = 1200,
scroll_top_duration = 700,
$back_to_top = $('.backtotop');
$(window).scroll(function() {
($(this).scrollTop() > offset) ? $back_to_top.addClass('is-visible'): $back_to_top.removeClass('is-visible fade-out');
if ($(this).scrollTop() > offset_opacity) {
$back_to_top.addClass('fade-out');
}
});
$back_to_top.on('click', function(event) {
event.preventDefault();
$('body,html').animate({
scrollTop: 0,
}, scroll_top_duration);
});
});
So you would change event listener assignments like the following:
$('.search').click(function(e) {
$(".search-overlay").addClass("visible");
e.preventDefault();
});
...to use the corresponding on method instead, passing the event name as an argument:
$('.search').on("click", function(e) {
$(".search-overlay").addClass("visible");
e.preventDefault();
});
Event delegation is avoiding adding several event listeners to specific nodes and instead adding a single event listener to a common parent element, which then looks to see which child element was clicked on.
There's a good article here:
https://www.google.co.uk/amp/s/davidwalsh.name/event-delegate/amp

jQuery menu in need of additional functionality

I wanted to create a small and lean as possible menu that hides itself on scroll at certain viewport height, shows itself after You click a button, and I did, but I have 2 problems with it:
Here is a Fiddle for You to follow along.
When you show the menu by clicking the button it appears, but the only way for it to go away is if You scroll down or up. How can I make it dissapear if I click somewhere out of the #sideBar container e.g. the site.
When You refresh the page using a soft-refresh (F5) the menu appears because the browser understands that as if the page have been scrolled. Is there a way to bypass this as well?
Here is some code, just because the fiddle requires it:
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 400) {
$('#sideBar').slideUp("fast");
$('#menuButton').fadeIn();
} else {
$('#sideBar').slideDown("slow");
$('#menuButton').fadeOut();
}
});
$(document).ready(function(){
$('#menuButton').click(function(){
$('#sideBar').slideDown();
})
});
Thanks in advance!
Test the target:
DEMO
function hideIt() {
$('#sideBar').slideUp("fast");
$('#menuButton').fadeIn();
}
function showIt() {
$('#sideBar').slideDown("slow");
$('#menuButton').fadeOut();
}
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 400) {
hideIt()
} else {
showIt();
}
});
$(function(){
if ($(document).scrollTop() < 400) showIt(); // show at start
$('#menuButton').click(function(){
$('#sideBar').slideDown();
});
$(document).on("click",function(e) {
var target = $(e.target);
var show = target.is("#sideBar") ||
target.is("#menuButton") ||
target.parent().is("#menuButton");
if (!show) hideIt();
});
});
Here is a shorter version
DEMO
function toggleIt(show) {
if (show) {
$('#sideBar').slideDown("slow");
$('#menuButton').fadeOut();
}
else {
$('#sideBar').slideUp("fast");
$('#menuButton').fadeIn();
}
}
$(document).scroll(function () {
var y = $(this).scrollTop();
toggleIt(y > 400);
});
$(function(){
toggleIt($(document).scrollTop()<400);
$('#menuButton').click(function(){
$('#sideBar').slideDown();
});
$(document).on("click",function(e) {
var target = $(e.target);
var show = target.is("#sideBar") ||
target.is("#menuButton") ||
target.parent().is("#menuButton");
if (!show) toggleIt(false);
});
});
I can help with the first question, you can change your JQuery code below so that when the parent 'content' container is clicked the menu slides up.
$(document).ready(function(){
$('#menuButton').click(function(){
$('#sideBar').slideDown();
})
$('#content').click(function(){
$('#sideBar').slideUp();
})
});
I'm not sure I follow the second question? Please can you provide more information on what you mean.
For Question 1, Just put the following code in ready function
$('#content').click(function(){
$('#sideBar').slideUp();
});
EDITED
For Question 2, put following code in ready function
$(document).trigger('scroll');
In short, your ready function should look like
$(document).ready(function(){
$(document).trigger('scroll');
$('#menuButton').click(function(){
$('#sideBar').slideDown();
})
$('#content').click(function(){
$('#sideBar').slideUp();
})
});
A child, combination of #mplungjan and #Gagan Jaura's responses seems to do the job:
function hideIt() {
$('#sideBar').slideUp("fast");
$('#menuButton').fadeIn();
}
function showIt() {
$('#sideBar').slideDown("slow");
$('#menuButton').fadeOut();
}
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 400) {
hideIt()
} else {
showIt();
}
});
$(function(){
showIt(); // show at start
$('#menuButton').click(function(){
$('#sideBar').slideDown();
});
$(document).on("click",function(e) {
var target = $(e.target);
var show = target.is("#sideBar") ||
target.is("#menuButton") ||
target.parent().is("#menuButton");
if (!show) hideIt();
});
});
$(document).ready(function(){
$(document).trigger('scroll');
$('#menuButton').click(function(){
$('#sideBar').slideDown();
})
$('#content').click(function(){
$('#sideBar').slideUp();
})
});

Scroll Div Left and Right on click with JS

I have the following script to scroll a div up and down. I wanted to know if there is a way it can be amended to now go left and right. I did what seemed obvious, which was to change the ele.scrollTop to ele.scrollRight. What would be the correct amendment to the script?
JS Fiddle: http://jsfiddle.net/swQ7J/5/
Original (Top/Bottom) Script:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script>
$(function() {
var ele = $('#scroll');
var speed = 25, scroll = 5, scrolling;
$('#scroll-up').click(function() {
// Scroll the element up
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() - scroll );
}, speed);
});
$('#scroll-down').click(function() {
// Scroll the element down
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() + scroll );
}, speed);
});
$('#scroll-up, #scroll-down').bind({
click: function(e) {
// Prevent the default click action
e.preventDefault();
},
mouseleave: function() {
if (scrolling) {
window.clearInterval(scrolling);
scrolling = false;
}
}
});
});
</script>

How to stop window.scroll() after specific event?

I want to make the sticky-nav to act similar(scroll is off when the menu is expanded) to this website's nav(http://amandagerhardsen.com/#cloudbusting/4) when expanded.
How do I do it?
var Boxlayout = (function () {
var $el = $('#sticky-nav'),
$sections = $el.children('section'),
// work panels
$workPanelsContainer = $('#bl-panel-work-items'),
// close work panel trigger
$closeWorkItem = $workPanelsContainer.find('nav > span.hidemenu'),
transEndEventNames = {
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition': 'transitionend',
'OTransition': 'oTransitionEnd',
'msTransition': 'MSTransitionEnd',
'transition': 'transitionend'
},
// transition end event name
transEndEventName = transEndEventNames[Modernizr.prefixed('transition')],
// support css transitions
supportTransitions = Modernizr.csstransitions;
function init() {
initEvents();
}
function initEvents() {
$sections.each(function () {
var $section = $(this);
// expand the clicked section and scale down the others
$section.on('click', function () {
if (!$section.data('open')) {
$section.data('open', true).addClass('bl-expand bl-expand-top');
$el.addClass('bl-expand-item');
}
}).find('span.hidemenu').on('click', function () {
// close the expanded section and scale up the others
$section.data('open', false).removeClass('bl-expand').on(transEndEventName, function (event) {
if (!$(event.target).is('section')) return false;
$(this).off(transEndEventName).removeClass('bl-expand-top');
});
if (!supportTransitions) {
$section.removeClass('bl-expand-top');
}
$el.removeClass('bl-expand-item');
return false;
});
});
// clicking on a work item: the current section scales down and the respective work panel slides up
$workItems.on('click', function (event) {
// scale down main section
$sectionWork.addClass('bl-scale-down');
// show panel for this work item
$workPanelsContainer.addClass('bl-panel-items-show');
var $panel = $workPanelsContainer.find("[data-panel='" + $(this).data('panel') + "']");
currentWorkPanel = $panel.index();
$panel.addClass('bl-show-work');
return false;
});
// navigating the work items: current work panel scales down and the next work panel slides up
$nextWorkItem.on('click', function (event) {
if (isAnimating) {
return false;
}
isAnimating = true;
var $currentPanel = $workPanels.eq(currentWorkPanel);
currentWorkPanel = currentWorkPanel < totalWorkPanels - 1 ? currentWorkPanel + 1 : 0;
var $nextPanel = $workPanels.eq(currentWorkPanel);
$currentPanel.removeClass('bl-show-work').addClass('bl-hide-current-work').on(transEndEventName, function (event) {
if (!$(event.target).is('div')) return false;
$(this).off(transEndEventName).removeClass('bl-hide-current-work');
isAnimating = false;
});
if (!supportTransitions) {
$currentPanel.removeClass('bl-hide-current-work');
isAnimating = false;
}
$nextPanel.addClass('bl-show-work');
return false;
});
// clicking the work panels close button: the current work panel slides down and the section scales up again
$closeWorkItem.on('click', function (event) {
// scale up main section
$sectionWork.removeClass('bl-scale-down');
$workPanelsContainer.removeClass('bl-panel-items-show');
$workPanels.eq(currentWorkPanel).removeClass('bl-show-work');
return false;
});
}
return {
init: init
};
})();
Here is a fiddle: http://jsfiddle.net/77P2e/
Be careful to unlock scrolling again when done, or this could be very annoying for the user!
Setup code
var $window = $(window), previousScrollTop = 0, scrollLock = false;
$window.scroll(function(event) {
if(scrollLock) {
$window.scrollTop(previousScrollTop);
}
previousScrollTop = $window.scrollTop();
});
To lock scroll position:
scrollLock = true;
And to unlock again...
scrollLock = false;
As an example use, you could lock the window scroll position when the mouse enters the navigation area, and unlock it again when the mouse leaves:
$("nav")
.mouseenter(function(){ scrollLock = true; })
.mouseleave(function(){ scrollLock = false; });
In my opinion the accepted answer is not what should be achieved, as the window.scroll() function will be still running (endlessly), even if the 'event' has occured.
The window.scroll() function is an event handler. So use on() to bind the event and off() to unbind it (after the 'event' has occured).
$(window).on('scroll', function() { // bind event handler
var offset = $(window).scrollTop();
console.log("page Y-Offset: ", offset); // just to see it working
if(offset >= 100) $(window).off('scroll'); // unbind the event handler when the condition is met
});
The Javascript solution is a little janky for me, on mobile. It's like it scrolls a little bit and then snaps back into place.
However, I figured out a way to do it much more cleanly, without any jank, just by changing CSS's overflow property on the part you don't want to scroll. Here's the code in d3 but the concept should be pretty clear:
var body = d3.select('body');
var preventScroll = function () {
body.style('overflow', 'hidden');
},
allowScroll = function () {
body.style('overflow', 'scroll');
};
d3.select('#sticky-nav')
.on('touchmove', preventScroll)
.on('touchstart', preventScroll)
.on('touchend', allowScroll)
.on('touchcancel', allowScroll);
As I was using jquery animation,
if ($(window).scrollTop() >= $('.btn').offset().top + $('.btn').outerHeight() - window.innerHeight)
{
$(".tab").stop();
}
I did this and it worked.
.btn is the button. That .tab div would stop if it scrolls to that position.
If you're using jquery animation you can try using the stop() function on the animated object.

slideToggle is creating a wobble at the end of an accordion

Creating an accordion - on the slide - the elements underneath the element that is sliding seem to move down a px and then back up, creating a juddering effect.
$(document).ready(function() {
//Promos banners rotation and accordion
$(function(){
var $accordionList = $('.accordion').find('li');
var numberOfItems = $accordionList.length;
var currentItem = 0;
// Set first item to active
$accordionList.eq(currentItem).addClass('active').find('.content').slideToggle(800, function() {});
// Loops through promos
var infiniateLoop = setInterval(function() {
if(currentItem == numberOfItems - 1){
currentItem = 0;
}
else {
currentItem++;
}
// Remove active class, if is has it, and close content
$accordionList.parent().find('li.active').removeClass('active')
.find('.content').slideToggle(800, function() {
});
// Add active class and open content
$accordionList.eq(currentItem).addClass('active').find('.content').slideToggle(800, function() {
});
}, 4000 );
// Click to show promo
$accordionList.on('click', function () {
// Stop rotation
clearInterval(infiniateLoop);
var $accordionHead = $(this);
// Remove active class, if is has it, and close content
if($accordionHead.hasClass('active')) {
// Do nothing
}
else {
$accordionHead.parent().find('li.active').removeClass('active')
.find('.content').slideToggle(800, function() {
});
// Add active class and open content
$accordionHead.addClass('active').find('.content').slideToggle(800, function() {
});
};
});
});
});
Fiddle here demonstrating the problem
I've seen some suggestions that you fix the height of the content div - but the site is responsive so that won't work.
Ya, I've had this problem before to. My favorite fix is to just make my own .slideToggle()
div = $('div');
height = div.height();
width = div.width();
$('div').click( function() {
if ($(this).hasClass('hidden')) {
$(this).animate({height: "0", width: "0"}, 200).hide().addClass('hidden');
} else {
$(this).animate({height: height, width: width}, 200).show().removeClass('hidden');
}
});
You could even wrap it in a prototype function if you wanted to.

Categories

Resources