Best Practice for jQuery Compatibility - javascript

I've got this jQuery to add a back to top button. It's simple and works very well. I have it running as a plugin in WordPress MultiSite on probably 120 websites. Today I noticed it isn't working on every site. There are no console errors, but my guess is that some other plugin or script is causing a conflict. This is inconsistent from one site to the other and I can't find a reason.
How can I write this jQuery so it doesn't experience compatibility issues?
jQuery(document).ready(function($){
//Check to see if the window is top if not then display button
$(window).scroll(function(){
if ($(this).scrollTop() > 100) {
$(".scrollToTop").fadeIn();
} else {
$(".scrollToTop").fadeOut();
}
});
//Click event to scroll to top
$(".scrollToTop").click(function(){
$("html, body").animate({scrollTop : 0},800);
return false;
});
});
Example site 1: http://anntowergallery.com/exhibits/ Doesn't work.
Example site 2: http://iemajen.com/asphaltanimals/ Works
I've tried this out on a dozen sites or so and cannot pin point what could cause the problem. No errors in console on the gallery website.
I appreciate any feedback.

Strange bug you got there.
Seems that in site 1 you have the following CSS:
body {
overflow-x: hidden;
}
When that CSS is in place, the $(window).scroll event listener won't fire. If you remove that CSS line, the JS works just fine.
You can also bind the scroll event to the body instead of the window:
$("body").scroll(function(){
...
});
But I recall that had some issues with IE. Probably you'd be safest to bind both $("body").scroll and $(window).scroll:
jQuery(document).ready(function($){
//Check to see if the window is top if not then display button
$(window).add("body").scroll(function(){
if ($(this).scrollTop() > 100) {
$(".scrollToTop").fadeIn();
} else {
$(".scrollToTop").fadeOut();
}
});
//Click event to scroll to top
$(".scrollToTop").click(function(){
$("html, body").animate({scrollTop : 0},800);
return false;
});
});

You've got a style element inside the body tag right before your scroll script, which isn't valid and may be preventing the script from executing. Try moving that into the head.
This is the part I'm talking about:
<style type="text/css">
.scrollToTop {
/* ... */
}
</style>

I wouldn't use that code on mobile devices... every tick of the window scroll is firing either a fadeIn or fadeOut. It would be better to add a flag to check if the scroll to top button is visible, or not (demo)
jQuery(document).ready(function($) {
var visible = false;
//Check to see if the window is top if not then display button
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
if (!visible && scrollTop > 100) {
$(".scrollToTop").fadeIn();
visible = true;
} else if (visible && scrollTop <= 100) {
$(".scrollToTop").fadeOut();
visible = false;
}
});
//Click event to scroll to top
$(".scrollToTop").click(function() {
$("html, body").animate({
scrollTop: 0
}, 800);
return false;
});
});

Related

How to auto scroll (up&down) to section when user scroll (not click!)

I'm trying to achieve a sliding scroll (like fullPage.js) by myself. I don't want to create a plugin either use a plugin. I only want to scroll/slide to a section when user trigger scroll (up and down!).
I've searched all over the internet and I do not know how to prevent the user from scrolling to replace standard scroll behavior by my animated scroll (desktop and mobile). I want to implement this animation inside a Bootstrap carousel item.
Summarizing, I have a carousel with several items, and each item will have a caption (outside the viewport). When the user scrolls down, then I will show the caption (like third slide here), and when the user scrolls up, I will scroll up and hide the caption.
Here is the CodePen with the carousel example running: link
This is what I get so far (I've got part of the code from StackOverflow)...
$(function(){
var _top = $(window).scrollTop();
var _direction;
$(window).scroll(function(){
var _cur_top = $(window).scrollTop();
if(_top < _cur_top)
{
_direction = 'down';
window.scrollTo(0, document.body.scrollHeight);
} else {
_direction = 'up';
window.scrollTo(0, 0);
}
_top = _cur_top;
console.log(_direction);
});
});
I get a very (very!) slow animation... It is not smooth at all.
I've tried this too:
$(document.body).on('DOMMouseScroll mousewheel', function (event) {
event.preventDefault();
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
// Scroll up
$("html, body").animate({scrollTop: 0}, 400);
}
else {
// Scroll down
}
});
But, that code does not work and I get this error: [Intervention] Unable to preventDefault inside passive event listener due to the target being treated as passive.
I will be very thankful if you can help me, please!
Edited:
Someone helped me at "StackOverflow en espaƱol". Here is the solution!! Many thanks to #matahombres ;)

Javascript animations don't work on HTML page

There are several animations in my scripts, but they don't work. I can't identify the problem. What might prevent these animations from running?
I have tried each animation in its own html page, they work fine.
jQuery(document).ready(function($){
var $timeline_block = $('.cd-timeline-block');
//hide timeline blocks which are outside the viewport
$timeline_block.each(function(){
if($(this).offset().top > $(window).scrollTop()+$(window).height()*0.75) {
$(this).find('.cd-timeline-img, .cd-timeline-content').addClass('is-hidden');
}
});
//on scolling, show/animate timeline blocks when enter the viewport
$(window).on('scroll', function(){
$timeline_block.each(function(){
if( $(this).offset().top <= $(window).scrollTop()+$(window).height()*0.75 && $(this).find('.cd-timeline-img').hasClass('is-hidden') ) {
$(this).find('.cd-timeline-img, .cd-timeline-content').removeClass('is-hidden').addClass('bounce-in');
}
});
});
});
The animations don't work once incorporated into my site.
Saw your repo. In index.html in line 542 add a class cssanimations
<section id="cd-timeline" class="cd-container cssanimations">
By the way you used body tag inside body tag. Surly that is not right.

An Issue With jQuery and Safari

I am attempting to create a navigation bar that slides up and off the screen when a user scrolls down, and then scrolls back down when a user stops scrolling / scrolls up. Below is a snippet of my script and a jsfiddle:
$(document).ready(function() {
var position = $(window).scrollTop();
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > position) {
$('.nav').addClass('active');
} else {
$('.nav').removeClass('active');
}
position = scroll;
});
});
https://jsfiddle.net/z2uc89sL/
Coupled with my CSS this works fine in all the browsers I have tested it in except for Safari (I'm running version 9.0.2 on a Mac). The problem that is occurring is that when you hit the top of page and there is no further room to scroll up, the nav gets hidden again by re sliding up (as though the user was actually scrolling down again rather than butting up to the top of the page). The opposite is happening at the bottom of the page too.
If you look at the fiddle in Safari you will see the issue I am talking about. If you look at the fiddle in any other browser you'll see what I'm trying to achieve.
This is because of bouncing effect in safari.
You can disable it with some extensions like iNoBounce.
Or simply compare current position like this.
if (scroll > position && position > 0) {
$('.nav').addClass('active');
} else if (position < $(window).height()){
$('.nav').removeClass('active');
}
Below i tried to provide you two different answers, First solution is related to your .nav class while Second is simulation of same functionality as a function. So, it could be reused.
var el = $(".nav");
$(window).scroll(function() {
el.addClass('active');
clearTimeout($.data(this, "scrollCheck"));
$.data(this, "scrollCheck", setTimeout(function() {
el.removeClass('active');
}, 250));
});
/*
* As a Function
*/
function scrollFunc(el) {
var el = el;
$(window).scroll(function() {
el.addClass('active');
clearTimeout($.data(this, "scrollCheck"));
$.data(this, "scrollCheck", setTimeout(function() {
el.removeClass('active');
}, 250));
});
}
scrollFunc($('nav'));
To see the results online, Please have a look at my fiddle https://jsfiddle.net/yeoman/g19nejfu/1/ i forked your question and update it with working answer.
I would love to explain about what's going on but actually this question is somehow answered already. So, for that purpose, i will share some useful links. One should check them out to understand it.
jQuery scroll() detect when user stops scrolling
http://gabrieleromanato.name/jquery-check-if-users-stop-scrolling/
Hope that my answer will you. Thanks, Cheers!

CSS Div Scroll Height

I am trying to recreate the effect seen here: http://jsfiddle.net/surendraVsingh/aATHd/2/
But I am trying to animate the height. For some reason, it works fine when I scroll down, but upon scrolling up, the height doesn't change back to normal. Any ideas?
Here is what I have now: http://justinledelson.com/new/
$(window).scroll(function(){
if ($(this).scrollTop() > 250){
$('#header').animate({"height":"100px"}, 1500);
}
else{
$('#header').animate({"height":"470px"}, 1);
}
});
Thanks!
Although I said that this wasn't a solution for your problem, it seems that it's actually a solution.
Add a class after each action. Something like expanded and collapsed for each situation, and check if that class is present before doing the animation. That way the animations won't trigger until it's necessary.
This avoids triggering the animation multiple times queuing the animation. That's why if you scrolled down a lot of times and scrolled back to top, the "expanding" animation triggered long after you scrolled up (it had to wait that each "collapsing" animation ended)
My test was:
$(window).scroll(function(){
var $header = $('#header');
if ($(this).scrollTop() > 50){ // x should be from where you want this to happen from top//
if (!$header.hasClass('collapsed')) {
$header.animate({"height":"100px"}, 1500, function() {
$header.toggleClass('expanded collapsed');
});
}
}
else{
if (!$header.hasClass('expanded')) {
$header.animate({"height":"470px"}, 1, function() {
$header.toggleClass('expanded collapsed');
});
}
}
});
header should start with expanded class

$(window).scroll() firing on page load

Is there a way to prevent $(window).scroll() from firing on page load?
Testing the following code in Firefox 4, it fires even when I unplug the mouse.
jQuery(document).ready(function($){
$(window).scroll(function(){
console.log("Scroll Fired");
});
});
The scroll event is unrelated to the mouse, it is called whenever a new document scrolling position is set. And arguably that position is set when the document loads (you might load it with an anchor after all), also if the user presses a cursor key on his keyboard. I don't know why you need to ignore the initial scroll event but I guess that you only want to do it if pageYOffset is zero. That's easy:
var oldPageYOffset = 0;
$(window).scroll(function(){
if (window.pageYOffset != oldPageYOffset)
{
oldPageYOffset = window.pageYOffset;
console.log("Window scrolling changed");
}
});
Note: MSIE doesn't have window.pageYOffset property so the above will need to be adjusted. Maybe jQuery offers a cross-browser alternative.
This was the solution I went for. Any improvements gratefully received.
var scroll = 0;
$(window).scroll(function(){
if (scroll>0){
console.log("Scroll Fired");
}
scroll++;
});
The scroll event does not fire on every load, only when refreshing a page that was scrolled, or when navigating to an anchor directly.
Many of the answers suggest ignore the first time it's called, which would ignore a valid scroll if the page doesn't get scrolled initially.
//Scroll the page and then reload just the iframe (right click, reload frame)
//Timeout of 1 was not reliable, 10 seemed to be where I tested it, but again, this is not very elegant.
//This will not fire initially
setTimeout(function(){
$(window).scroll(function(){
console.log('delayed scroll handler');
});
}, 10);
//This will fire initially when reloading the page and re-establishing the scroll position
$(window).scroll(function(){
console.log('regular scroll handler');
});
div {
height: 2000px;
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
</div>
This seems to have worked for me.
$(window).bind("load", function() {
$(window).on("scroll", function () {
console.log('scroll');
});
});
sure, don't load it until after the load. make it a call back for sleep for 500 millis.

Categories