If the following code works (which certainly does)
$( 'html, body' ).animate(
{
"scrollTop": "500"
},
500
);
then why doesn't the following code work?
$( window ).animate(
{
"scrollTop": "500"
},
500
);
If the following code works
$( window ).scroll( myScrollFunctionHandler );
then why doesn't the following code work?
$( 'html, body' ).scroll( myScrollFunctionHandler );
Can somebody please make a comprehensive explanation as to why this has to be this way?
window does not have a scrollTop property, which is why your first example doesn't work. document.body does.
As to your second example, $(window).scroll is the event handler installer for window.onscroll. There is no "body onscroll" event, so obviously an event handler installed on the body (or html) element won't be invoked, as events do not bubble down the DOM, but only up.
This should be due to the internal working of $(window).animate(). Experiment results suggested that inside this jQuery animate() code, $(window).scrollTop() would ALWAYS return zero and $(window).scrollTop(value) could NOT set the value properly.
However, these work before the animate() and in its step callback function. Thus, the code like below would work properly.
function scrollNow(final_val){
var initial_val = $(window).scrollTop(),
diff = final_val - initial_val
;
$(window).animate(
{
scrollTop: diff,
},
{
duration: 1000,
step: function(now, fx){
$(window).scrollTop(initial_val + now);
}
}
);
}
Related
I wanna move content with animation.
There's an animation in the jquery function, like that:
.on('click', '.btn', function () {
var contentWidth = $(window).width() - $('.sidebar').width();
$( ".content" ).animate({
left: "+=1000",
}, 5000, function() {
// moving content function
}
);
});
So, because I have various positions of content, I need to use this value in the variable contentWidth. How I can set this value in a variable and decrement the left value every time when I call a function?
Something like left: "+=contentWidth" doesn't work. Is where I make mistake?
Not sure if i got it but...
maybe you could use string interpolation
.on('click', '.btn', function () {
var contentWidth = $(window).width() - $('.sidebar').width();
$( ".content" ).animate({
left: `+=${contentWith}`,
}, 5000, function() {
// moving content function
}
);
});
Not tested but should work theoretically
On my site, I am trying to fix the navigation so that when the browser is getting resized from desktop to mobile size, the mobile menu works. I have the mobile menu working on initial load, and the desktop navigation working on initial load, but when I run the script in a $(window).on('resize', function() {} and click an item as depicted in my script, the event fires always +1 each time the window was rested after a resize.
What I mean is, if I load the page, scale it into mobile size, click the menu and a dropdown item, the click event will fire once. Resize the window out and then back in, the click event will fire now 2 times, then 3, and so on, depending on how many times the browser was resized.
I'm not sure exactly what is going on in my resize script that is screwing everything up and I'm at my wits end at trying to figure it out. Normally people aren't sitting there resizing their browser from desktop to mobile, but my boss does when he show's clients a beta of their site and wants this to never be an issue.
Here is my resize script:
(function( $ ) {
var id,
$body = $('body'),
$window = $( window ),
$navSlider = $('.nav-slider'),
$navMask = $( '.nav-mask' ),
$navToggler = $( '.navbar-toggler' ),
$parent = $( '.menu-item-has-children' ),
$parentLink = $( '.dropdown-toggle' ),
$childContainer = $( '.dropdown-menu' );
$window.on( 'resize', function( e ) {
clearTimeout(id);
id = setTimeout(function() {
close();
var width = $window.width();
if ( width < 992 ) {
setHeightToNav();
$navMask.on( 'click', function() { close() } );
$navToggler.on( 'click', function() { open() } );
$parentLink.on( 'click', function( e ) {
e.preventDefault();
var $this = $( this );
$this.data( 'clicked', true );
console.log( $this.parent() );
} )
}
if ( width >= 992 ) {
resetNavHeight();
console.clear();
}
}, 500 );
} );
function setHeightToNav() {
if ( $body.hasClass( 'logged-in' ) ) {
var $wpAdminBar = $( '#wpadminbar' ).outerHeight();
$navSlider.css( { top: $wpAdminBar + 'px' } );
}
var $navHeight = $( '#header-container' ).outerHeight();
$navSlider.css( { marginTop: $navHeight + 'px' } );
}
function resetNavHeight() {
if ( $body.hasClass( 'logged-in' ) ) {
$navSlider.css( { top: 0 + 'px' } );
}
$navSlider.css( { marginTop: 0 + 'px' } );
}
function close() {
$body.removeClass( 'has-active-menu' );
setTimeout( function() {
$navSlider.removeClass( 'toggling' );
$parent.removeClass( 'show' );
$parentLink.attr( 'aria-expanded', false );
$childContainer.removeClass( 'show' ).removeAttr( 'style' );
$parentLink.data('clicked', false);
}, 250 );
console.log('close()');
}
function open() {
$body.addClass( 'has-active-menu' );
$navSlider.addClass( 'toggling' );
}
})( jQuery );
I've tried my script both with AND without the setTimeout function and it happens exactly the same.
On the project, we are using Bootstrap 4, with the Bootstraps Dropdown._clearMenus(); function commented out in the right places as it was causing conflicts with the functionality I wanted with the navigation.
A link to a site where you can see this is here. It's a WordPress site as well if that matters for anything.
Any help is appreciated. I've been at this for several hours and am at my wits end.
.on( 'click', function ) does not set the event listener, it adds an event listener. Try doing off('click') before setting it if you really need to set this listener here.
But note that any other 'click' listener for this element will also be removed.
That's for the quick fix. You could do better, but that would require more work (track with a boolean if you just changed "display mode", and add or remove the event listeners only then, for example).
I have been experimenting with Javascript animations for the first time recently and have run into this problem on one of my projects.
The below jquery scrolls horizontally without a problem. However when I add a second value in an attempt to scroll vertically nothing happens, and no errors are thrown up.
$( ".space_background" ).ready(function() {
$( ".space_background" ).animate({
backgroundPosition: "+=200px"
}, 5000, function() {
});
});
The below code is what I thought I would have to add to achieve the effect
$( ".space_background" ).ready(function() {
$( ".space_background" ).animate({
backgroundPosition: "+=200px 200px"
}, 5000, function() {
});
});
I have also tried backgroundPositionX and backgroundPositionY, neither of which work.
Any help sorely appeciated
To move background in vertical direction using jQuery
$( ".space_background" ).ready(function() {
$( ".space_background" ).animate({
backgroundPositionY: "+=200px"
}, 5000, function() {
});
});
Above code works for few browsers reason being jQuery can't animate background position properly as one need it to animate with two values. Above code is working for browsers that implemented the non-standard background-position-x and -y like Internet Explorer. So you need to use any plugins for this like following -
/**
* #author Alexander Farkas
* v. 1.02
*/
(function($) {
$.extend($.fx.step,{
backgroundPosition: function(fx) {
if (fx.state === 0 && typeof fx.end == 'string') {
var start = $.curCSS(fx.elem,'backgroundPosition');
start = toArray(start);
fx.start = [start[0],start[2]];
var end = toArray(fx.end);
fx.end = [end[0],end[2]];
fx.unit = [end[1],end[3]];
}
var nowPosX = [];
nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];
function toArray(strg){
strg = strg.replace(/left|top/g,'0px');
strg = strg.replace(/right|bottom/g,'100%');
strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
}
}
});
})(jQuery);
or
http://snook.ca/technical/jquery-bg/jquery.bgpos.js
Now you can write following code to animate backgrond position using jQuery
$( ".space_background" ).animate({backgroundPosition:"(-150px 0)"});
For more reference:
http://snook.ca/archives/javascript/jquery-bg-image-animations
Im trying to make a box animate when i scroll down to its position, but the animation wont stop, the element just keeps repeating the animation forever.
The code im using :
jQuery(document).scroll(function (e) {
var value = jQuery(this).scrollTop();
if (value = 600) {
jQuery( "body" ).addClass( "scroll" );
jQuery('#car1').animate({top: '+=50px'}, 2000);
}
});
A single = isnt a comparison operator. It is in fact assigning a value to your variable.
That being said, your condition :
if (value = 600)
is always true since 600 is a truthy value.
Try using == or ===.
To anime once, you can use the class you are inputing on the body. Just invert your 2 lines and do a condition :
if(!jQuery("body").hasClass("scroll")) //Animate only if it haven't the class scroll
jQuery('#car1').animate({top: '+=50px'}, 2000);
jQuery( "body" ).addClass( "scroll" );
The question has to do with Firefox refreshing the browser window to 100% when a function is called.
If the browser view is at say, 75%, and I use .click method on a link - the page refreshes at 100% THEN the function executes. Safari executes the function without refreshing the window.
The code now looks like:
function hideFlag(){
$("#ftm").click(function () {
var stageWidth = $("#window_div").width();
if (stageWidth <= 1200){
$( "#window_div" ).animate({
width: 1250,
opacity: ".8",
}, 1000 );
$( "#flagDiv" ).animate({
opacity: "0",
}, 1000 );
}
else{
$( "#window_div" ).animate({
width: 500,
opacity: ".6",
}, 1000 );
$( "#flagDiv" ).animate({
opacity: "1",
}, 1000 );
}
});
}
In Firefox, if my browser view is zoomed out to 75% and I replace the .click() method with .mouseenter, the divs animate without the screen redrawing or resizing on mouseenter. I don't understand the difference between the click() and mouseenter() implementations.
Solved it.
It was far simpler than I thought. Proper use of the "return false;" argument on the click method
solved my problem. Revised code is as follows:
function hideFlag(){
$("#ftm").click(function () {
var stageWidth = $("#window_div").width();
if (stageWidth <= 1200){
$( "#window_div" ).animate({
width: 1250,
opacity: ".8",
}, 1000 ); return false;
$( "#flagDiv" ).animate({
opacity: "0",
}, 1000 ); return false;
}
else{
$( "#window_div" ).animate({
width: 500,
opacity: ".6",
}, 1000 );return false;
$( "#flagDiv" ).animate({
opacity: "1",
}, 1000 );return false;
}
});
}
Thanks all for the help.
Not that this a direct answer to your question, but it's rather long for a comment.
You're using jQuery. I think you're missing the point of the whole cross-browser-library thing. Change
stageWidth = document.getElementById("window_div").clientWidth
to
stageWidth = $("#window_div").width()
no browser-specific code needed. There also no need for that addEventHandler function when using jQuery. It takes care of the differences between browsers so that you don't have to. That means you can change the setUpClickHandler function to this:
function setUpClickHandler() {
$('#ftm').click(hideFlag);
$('#ath').click(showFlag);
}
and change showFlag to this:
function showFlag(e){
$('#flagDiv').show();
}
and change
addEventHandler(window, "load", setUpClickHandler, false);
to
$(window).load(setUpClickHandler);