query two events for on - javascript

I have a page with links on top. When a link is clicked it scrolls down to a particular section. For styling purposes, I had to write a small jQuery to have to land 100px above the actual section that it scrolls to. Now I need the pixel number to change depending on the media query. Is there something wrong about how this is written? The responsive part isn't working..
function offsetAnchor() {
if(jQuery(location.hash).length !== 0) {
if (jQuery(window).width() <= 350) {
window.scrollTo(window.scrollX, window.scrollY - 180);
}
else {
window.scrollTo(window.scrollX, window.scrollY - 100);
}
}
}
// This will capture hash changes while you are on the same page
jQuery(window).on("hashchange", function () {
offsetAnchor();
});
window.setTimeout(function() {
offsetAnchor();
}, 1);

the syntax should be :
jQuery(window).on("hashchange resize", function () {}
you can read more about .on() function at jQuery API

Related

Slide div on and off the page on scroll without interrupting the animation when the user continues to scroll

I am trying to smoothly slide a div on and off the page (left to right) using jQuery only. I have accomplished the task, however if you continue to scroll up or down while the animation is still going, it will interrupt it in the middle of the action causing it to hesitate. I've run into this issue before and could never figure it out without using a plugin of some sort.
I know how to accomplish this with CSS transitions, jQuery UI, greensock, etc., but I am curious if there is a way to prevent that interruption with jQuery only. I am open to a pure JavaScript solution (no jQuery) as well if there is one.
My code:
var amountScrolled = 50;
$(window).scroll(function() {
if ($(window).scrollTop() > amountScrolled) {
$('#slide').stop().animate({marginLeft:"0px"}, 500);
} else {
$('#slide').stop().animate({marginLeft: "-400px"}, 500);
}
});
Example: https://jsfiddle.net/Hysteresis/hg9cvxop/6/
This works: JSFIDDLE link
It's all about the Callback Functions!
var amountScrolled = 50;
var loopRunning = 0;
$(window).scroll(function() {
if ($(window).scrollTop() > amountScrolled){
if(loopRunning === 0){
animateSlide("0px",500);
}
} else {
if(loopRunning === 0){
animateSlide("-400px",500);
}
}
});
function animateSlide(px, time){
loopRunning = 1;
$('#slide').stop().animate({marginLeft:px}, time, function(){
loopRunning = 0;
});
}
Well, to answer your question rather than provide advice on better ways to do it, I usually handle tasks like this by assigning a temporary class to denote that something is in the process of being animated. As somebody else said, the reason for the stuttering is because the scroll function is getting called multiple times, so you keep stopping and restarting the animation.
So you can try something like this (Fiddle):
var amountScrolled = 50;
$(window).scroll(function() {
if ($('#slide').hasClass('sliding')) {
return;
}
if ($(window).scrollTop() > amountScrolled) {
$('#slide').stop().addClass('sliding').animate({marginLeft:"0px"}, 500, function() {
$(this).removeClass('sliding');
});
} else {
$('#slide').stop().addClass('sliding').animate({marginLeft: "-400px"}, 500, function() {
$(this).removeClass('sliding');
});
}
});

Changing text content on scroll position

I found a solution that didn't work mainly that I want. Here it is:
topic url
and this solution works for me:
if(pos.top >= $(this).offset().top && pos.top <= $(this).next().offset().top)
{
$('#date').html($(this).find('.description').text());
return;
}
jsfiddle
but I want to change content description in gray box more smooth. I've tried to give animation in CSS for it, but it didn't work.
I modified your script a bit to detect when the text changes and when that happens I apply a small animation with jQuery. I set the opacity to a low value, e.g. opacity:0.4 and then make a quick animation back to opacity:1.
This will help your user to see easier the change in the text.
$(window).load(function () {
$(window).on('scroll resize', function () {
var pos = $('#date').offset();
$('.post').each(function () {
if (pos.top >= $(this).offset().top && pos.top <= $(this).next().offset().top) {
var newDescr = $(this).find('.description').text();
var oldDescr = $('#date').html();
$('#date').html(newDescr);
if(newDescr !== oldDescr) {
$('#date').css('opacity', 0.4).animate({ 'opacity': '1',}, 200);
return;
}
}
});
});
$(document).ready(function () {
$(window).trigger('scroll'); // init the value
});
});
Demo here

Disable script after certain scrolling

I've posted it before but none got it what I need. I need to disable this script after certain scrolling page, let's say page is scrolled 30% this script is disabled.
The reason I need to disable this script is that after certain scrolling div used in script is showed over some other div elements when page is scrolled, so I need to disable script after certain scrolling.
<script>
$(window).load(function () {
$(window).scroll(function () {
if ($(window).scrollTop() > 60) {
$('.additional').css('position', 'fixed');
$('.additional').css('top', 70);
} else {
$('.additional').css('position', 'relative');
$('.additional').css('top', 0);
}
});
});
</script>
I've created a working function in this fiddle with a dummy outcome, as you didn't provide any code of your page structure.
It calculates the scroll percentage using $(window).scrollTop() and $(document).height() and then uses an if/else statement to toggle two outcomes based on the result of the calculation.
function moveScroller() {
var move = function () {
var calc = $(window).scrollTop() / $(document).height();
if (calc > 0.3) {
/*EG:*/ $('#content').css('backgroundColor', '#f00');
/*$('.additional').css('position', 'fixed');
$('.additional').css('top', 70);*/
} else {
/*EG:*/ $('#content').css('backgroundColor', '#f0f');
/*$('.additional').css('position', 'relative');
$('.additional').css('top', 0);*/
}
};
$(window).scroll(move);
move();
}
$(function () {
moveScroller();
});

Height check on resize causing lag

I'm using the below jquery to check and reset the height of my div on resize. However, there is a terrible freeze/lag when using the below code. The structure is just three absolutely positioned divs. One at the top, one at the bottom, and one in the middle. Any idea why this might be happening?
$(window).resize(function () {
if ($("#master_bodywrapper_div").height() < 500) {
$("#master_bodywrapper_div").height(500);
}
else {
$("#master_bodywrapper_div").height("auto");
}
});
This is because, on some browsers, the resize event can fire dozens of times per second. You should have a resizing function that is called only after the window is done being resized, like so:
(function($) {
var resizeTimer = false;
function doResize() {
if ($("#master_bodywrapper_div").height() < 500) {
$("#master_bodywrapper_div").height(500);
}
else {
$("#master_bodywrapper_div").height("auto");
}
resizeTimer = false;
}
$(window).on("resize", function() {
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(doResize, 300);
});
})(jQuery);
Hope this helps!
Well, it is querying the DOM twice every time resize is triggered and this function called, which might be the source (DOM querying can be expensive). Note that resize is triggered a lot even if you simply grab the edge and move your mouse (with a moderate speed) 200px to one side. Try moving the $("#master_bodywrapper_div") query to above the resize callback, cached in a var, and then use that var reference in your callback function.
var div = $("#master_bodywrapper_div");
$(window).resize(function () {
if (div.height() < 500) {
div.height(500);
}
else {
div.height("auto");
}
});

Slide down and slide up events mixed up in a fast mouse wheel up and down

I'm using jquery slideDown() and slideUp() to show a fixed gototop link when the scroll bar height is more than 200px.
Problem:
Link slide action mixed up in a fast mouse wheel up and down. Because of 0.4 sec running time of slide functions. I tried to define a visible flag and complete functions to prevent mixing. But not successful.
JsFiddle
Scroll down in result block to view the link and try a fast wheel up and down. If the result block has big height on your screen, please decrease the height to see the action.
impress: function () {
if ($(window).scrollTop() > this.MIN_SCROLL_HEIGHT
&& !this.buttonVisibleFlag)
{
this.button.slideDown(400, function() {
Blue.buttonVisibleFlag = true;
});
}
else if ($(window).scrollTop() <= this.MIN_SCROLL_HEIGHT
&& this.buttonVisibleFlag)
{
this.button.slideUp(400, function() {
Blue.buttonVisibleFlag = false;
});
}
}
Any ideas or help would be greatly appreciated.
I think your best bet would be to perform the sliding actions only after the user has stopped scrolling for a certain (small) period of time. I found this method to detect when the user stops scrolling and implemented in your code, here's the result:
Updated fiddle
var Blue = {
MIN_SCROLL_HEIGHT: 200,
button: null,
buttonVisibleFlag: null,
init: function () {
this.button = $(".gototop");
this.buttonVisibleFlag = false;
this.setWindowBindings();
},
setWindowBindings: function () {
$(window).scroll(function () {
//perform actions only after the user stops scrolling
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function () {
Blue.impress();
}, 150));
});
},
impress: function () {
if ($(window).scrollTop() > this.MIN_SCROLL_HEIGHT) {
this.button.slideDown();
} else if ($(window).scrollTop() <= this.MIN_SCROLL_HEIGHT) {
this.button.slideUp();
}
}
}
$(document).ready(function () {
Blue.init();
});
Note: you may want to tweak the timeout interval to suit your needs

Categories

Resources