How to set jQuery breakpoints? - javascript

Because this is my first post, so in the beginning welcome everyone.
Since I'm just starting in JS and jQuery, can someone suggest how to deal with jQuery breakpoints?
On the website, I have a menu at the top in position: fixed and height: 200px. In the menu linked to scroll to a specific section using jQuery. The selected section goes to the top of the page.
I have created breakpoints in CSS and e.g. below 1024px, the menu is already 100px hight. Do you have an idea on how to convert a rule in jQuery, so that below 1024px scrolls to top - 100?
<nav>
<a class="region" href="#">Okolica</a>
</nav>
<section class="s1"> <section>
nav {
height: 200px;
}
#media (max-width: 1024px) {
nav {
height: 100px;
}
}
$('.region').on('click', function () {
$('body, html').animate({
scrollTop: $('.s1').offset().top - 200
}, 2000)
})
I tried code below but it doesn't work.
document.addEventListener('DOMContentLoaded', init);
function init(){
let query = window.matchMedia("(max-width: 1024px)");
if(query.matches){
$('.region').on('click', function () {
$('body, html').animate({
scrollTop: $('.s1').offset().top - 100
}, 2000)
})
}}
Any ideas?

you can extract the window size with vanilla javascript
https://developer.mozilla.org/en-US/docs/Web/API/window/innerWidth
window.innerWidth

In jQuery you can write a breakpoint like this:
if ($(window).width() < 1024) {
//YOUR FUNCTION FOR EXAMPLE
$('.region').on('click', function () {
$('body, html').animate({
scrollTop: $('.s1').offset().top - 100
}, 2000)
})
}

Related

Image fade-in on exposure

How do I fade in an image once it's in view? I'm trying to make my website responsive, so having it fade in on the amount of pixels scrolled won't do. I need it to be exposed depending on the percent scrolled. Or if there's a way to have it fade in when it's in the field of vision?
Here's the code:
$(document).ready(function(){
$(window).bind("scroll", function() {
if ($(this).scrollTop() > 300) {
$("#bluprintdesign").fadeIn();
} else {
$("#bluprintdesign").stop().fadeOut();
}
Right now what I have going on is it fades in when scrolled 300px and fades out if you scroll back up. I like that, but I want it in percentages so it's responsive to all screen resolutions.
Thank you!
Here's a function showImages() that will measure your $.scrollTop() + $(window).height() to establish the scroll point of the bottom of the viewport, and will add a class to hidden images when half of the image has passed the bottom of the viewport. I'm calling it on $(document).ready(); and $(window).on('scroll'); so that it will load images in the viewport on page load and as you scroll.
Using opacity: 0 instead of display: none (what $.fadeIn()/$.fadeOut() will toggle) allows the image to still take up space in the document, allowing you to calculate it's height (needed to know when half of the image is in view) without having to do anything tricky, and will also maintain the page layout when the image fades in, versus the page jumping around if you toggle display.
There are also libraries that will do this for you. jQuery waypoints is a popular one.
function showImages() {
var $window = $(window),
thresh = $window.scrollTop() + $window.height();
$('img:not(.show)').each(function() {
if (thresh > $(this).offset().top + ($(this).outerHeight() / 2)) {
$(this).addClass('show');
}
});
}
$(window).on('scroll', function() {
showImages();
})
$(function() {
showImages();
})
section {
height: 200vh;
border-top: 1px solid black;
}
img {
opacity: 0;
transition: opacity .25s;
}
.show {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<img src="http://kenwheeler.github.io/slick/img/fonz1.png">
</section>
<section>
<img src="http://kenwheeler.github.io/slick/img/fonz1.png">
</section>
<section>
<img src="http://kenwheeler.github.io/slick/img/fonz1.png">
</section>

How can i show/hide image with scrollTop

I've got a logo image that in page load is hidden. I'd like that the image would show after page scroll.
Tried that approach:
CSS:
#logo {
display: none;
}
JS/JQuery:
jQuery( document ).ready(function( $ ) {
$(document).scroll(function() {
var scroll = $(this).scrollTop();
if (scroll >=100){
$('#logo').show();
} else {
$('#logo').hide();
}
});
});
Case 1: if page is loaded with scroll = 0, after page scroll logo image doesn't show.
Case 2: if page is loaded with scroll > 100, logo image is show or hidden correctly.
Your code seems to work fine on scroll. If you just need to also conditionally hide/show the image based on the scroll position when the page loads, you can call the hide/show code when the page loads as well as when you scroll the page.
jQuery(document).ready(function($) {
function hideShow(scroll) {
if (scroll >= 100) {
$('#logo').show();
} else {
$('#logo').hide();
}
}
hideShow($(this).scrollTop());
$(document).scroll(function() {
hideShow($(this).scrollTop());
});
});
body {
height: 500vh;
}
#logo {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="http://kenwheeler.github.io/slick/img/fonz1.png" id="logo">

Having trouble getting the scroll animation to not trigger the scroll event

I currently have a number of div tags that can be seen below that are each the height of the viewport.
<!-- .current represents the div the user is currently viewing -->
<div class="full-height current" id="id1">
<div class="container">
</div>
</div>
<div class="full-height" id="id2">
<div class="container">
</div>
</div>
<div class="full-height" id="id3">
<div class="container">
</div>
</div>
<div class="full-height" id="id4">
<div class="container">
</div>
</div>
<div class="full-height" id="id5">
<div class="container">
</div>
</div>
I am attempting to implement a feature where upon a user scrolling, the window will scroll to the next div tag, always having only one div in view at a time. The way I implemented it works great, except for the fact that the animation triggers the scroll event again, resulting in an endless loop of the page scrolling once the user scrolls at all. I attempted to fix this by having a variable that will stop the event from triggering if the animation is in progress, but it does not seem to work. I am aware that I didn't do it for the scroll up, but I just wanted to see if it worked for the down first.
$(window).scroll(function(event) {
var scrollTop = $(this).scrollTop();
// If user scrolls down
if ((scrollTop > lastScrollTop) && $(".current").next("div").length > 0) {
if (animating == false) {
console.log("down");
$(".current").next("div").addClass("current");
$(".current").first().removeClass("current");
animating = true;
$("html, body").animate({
scrollTop: $(".current").offset().top
}, 1000, function() {animating = false});
}
// If user scrolls up
} else {
if ($(".current").prev("div").length > 0) {
console.log("up");
$(".current").prev("div").addClass("current");
$(".current").last().removeClass("current");
$("html, body").animate({
scrollTop: $(".current").offset().top
}, 1000);
}
}
lastScrollTop = scrollTop;
});
CSS included just in case. The 100vh - 111px is due to a fixed navbar at the top that is 111px high
/* Makes the element take up the entire height of the screen */
.full-height{
height: -o-calc(100vh - 111px); /* opera */
height: -webkit-calc(100vh - 111px); /* google, safari */
height: -moz-calc(100vh - 111px); /* firefox */
}
#id1 {
background-color: red;
}
#id2 {
background-color: blue;
}
#id3 {
background-color: yellow;
}
#id4 {
background-color: green;
}
#id5 {
background-color: purple;
}
If anyone could give me any ideas for fixing my problem, that would be great.
You'll want to stop the event and preventDefault. Here is some code from a current landing page:
$(document).ready(function () {
$('a.page-scroll').on('click', function(event) {
var link = $(this);
$('html, body').stop().animate({
scrollTop: $(link.attr('href')).offset().top - 50
}, 500);
event.preventDefault();
});
$('body').scrollspy({
target: '.navbar-fixed-top',
offset: 80
});
});
It uses bootstrap scrollspy so just ignore that. But notice that it stops any scroll animation that could be running and then also calls event.preventDefault() to stop the scroll event from bubbling and thus becoming recursive.
EDIT:
O.k. so I've a better look and the basic problem re: infinite scrolling is the code doesn't check if the scrollTop is already at 'where it needs to be'. You need an additional check to short circuit the scroll:
if (animating == false) {
if ($(this).scrollTop() == lastScrollTop) return;
if (($(this).scrollTop() > lastScrollTop) && $(".current").next("div")) {
console.log("down");
$(".current").next("div").addClass("current");
$(".current").first().removeClass("current");
animating = true;
$("html, body").stop().animate({
scrollTop: $(".current").offset().top
}, 1000,
function () { lastScrollTop = $(this).scrollTop(); animating = false; });
// If user scrolls up
} else {
if ($(".current").prev("div").length > 0) {
console.log("up");
$(".current").prev("div").addClass("current");
$(".current").last().removeClass("current");
$("html, body").stop().animate({
scrollTop: $(".current").offset().top
}, 1000, function () { lastScrollTop = $(this).scrollTop(); animating = false; });
}
}
}
Otherwise as it stands it will always either scroll up or down and never settle. That said with that "working" it's a terrible user experience. It will jump about since your scroll to code will fight the user on current scrollTop if they keep scrolling. i.e. your code will make it jump back to a previous position.
Try defining scroll event handler as named function ; defining lastScrollTop outside of scroll handler ; substituting .one() for .on() to allow animation to complete before re-attaching scroll event ; use .promise() which should be called at most once to avoid .animate() complete callback being called twice with selector "html, body" ; substituting single if to check for next or previous element .length and .animate() call for multiple if..else conditions and statements, animation function calls ; re-attach scroll event at .then() following animation completion .promise()
var lastScrollTop = 0;
function scroller(event) {
var scrollTop = $(this).scrollTop();
var direction = scrollTop > lastScrollTop ? "next" : "prev";
var el = $(".current")[direction](".full-height");
console.log(direction === "next" ? "down" : "up");
if (el.is("*")) {
$("html, body").animate({
scrollTop: el.offset().top
}, 1000).promise().then(function() {
console.log(this)
lastScrollTop = $(window).scrollTop();
$(".current")
.removeClass("current")[direction]("div")
.addClass("current")
setTimeout(function() {
$(window).one("scroll", scroller)
})
});
} else {
lastScrollTop = scrollTop;
$(window).one("scroll", scroller)
}
}
$(window).one("scroll", scroller);
/* Makes the element take up the entire height of the screen */
.full-height {
height: -o-calc(100vh - 111px);
/* opera */
height: -webkit-calc(100vh - 111px);
/* google, safari */
height: -moz-calc(100vh - 111px);
/* firefox */
}
#id1 {
background-color: red;
}
#id2 {
background-color: blue;
}
#id3 {
background-color: yellow;
}
#id4 {
background-color: green;
}
#id5 {
background-color: purple;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- .current represents the div the user is currently viewing -->
<div class="full-height current" id="id1">
<div class="container">
</div>
</div>
<div class="full-height" id="id2">
<div class="container">
</div>
</div>
<div class="full-height" id="id3">
<div class="container">
</div>
</div>
<div class="full-height" id="id4">
<div class="container">
</div>
</div>
<div class="full-height" id="id5">
<div class="container">
</div>
</div>
If you define height 100vh ,scroll event wont trigger

Scroll helper for mobile website

I have a very long article page that I want to help mobile users scroll on. For very long lists in mobile apps there's usually a alphabetical index that can help users jump to various places in the list. How do I implement something like that for a webapp?
If it helps my stack is angularjs / jquery / phonegap.
Just use angular's built-in $anchorScroll service.
See the live example in angular's official docs. Here are the important pieces of code:
In your view template:
<div id="scrollArea" ng-controller="ScrollCtrl">
<a ng-click="gotoBottom()">Go to bottom</a>
<a id="bottom"></a> You're at the bottom!
</div>
In your controller:
function ScrollCtrl($scope, $location, $anchorScroll) {
$scope.gotoBottom = function (){
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');
// call $anchorScroll()
$anchorScroll();
};
}
iOS7 Style List Navigator
If you want something nice on the phone, I just wrote this iOS7 style list navigator. I think the way Apple solved the problem is very straightforward. So we steal it.
It's written considering that you won't probably scroll the body, because in the many designs I've seen for smartphones, scrolling a container allows you to have fixed headers and footers for Android < 4 without getting mad.
A word of warning: this code is really fresh and untested.
SEE DEMO AND CODE
CSS (extract)
#scrolling {
padding-top: 44px;
overflow: scroll;
-webkit-overflow-scroll: touch;
height: 100%;
}
.menu {
position: fixed;
right: 0;
font-size: 12px;
text-align: center;
display: inline-block;
z-index: 2;
top: 58px;
}
.list .divider {
position: -webkit-sticky; /* will stop the label when it reaches the header */
top: 44px;
}
HTML (extract)
<div id="scrolling">
<ul class="menu">
<li>A</li>
<li>B</li>
<li>C</li>
<!-- etc -->
</ul>
<ul class="list">
<li class="divider" id="a">A</li>
<li>Amelia Webster</li>
<li>Andrew WifKinson</li>
<!-- etc -->
Javascript (zepto/jquery)
$(function() {
$(window).on("touchstart touchmove mouseover click", ".menu a", function(e) {
e.preventDefault();
clearInterval(t);
var steps = 25;
var padding = 68;
var target = $( $(this).attr("href") ).next("li");
if ( target.length > 0 ) {
var scroller = $("#scrolling")[0];
var step = parseInt((target[0].offsetTop - padding - scroller.scrollTop)/steps);
var stepno = 0;
setInterval( function() {
if ( stepno++ <= steps ) {
scroller.scrollTop += step;
} else {
clearInterval(t)
}
}, 20);
};
});
});
It performs a basic check of link validity before attempting the scroll. You can change padding to your needs.
Also, you will notice that we are targeting the first element after the required target. This is because Safari seems to go nuts because of the sticky positioning.
This code uses jQuery/Zepto selectors for the sake of brevity and readability. But these libraries are not really needed to achieve the result. With just a little extra digitation you could easily go dependency-free.
http://codepen.io/frapporti/pen/GtaLD
You can use a toggleable sidebar like this one. Resize your browser to the width of the screen of a mobile phone to understand what I mean.
Then create a directive in angularjs to wrap jQuery's animate function to scroll to a specific part in the article. Like this:
angular.module('yourModule', [])
.directive('scrollTo', function() {
return {
restrict : 'EA',
link: function(scope , element, attr){
$('html, body').animate({
scrollTop: $( attr['href'] ).offset().top
}, 300);
}
};
});
where href will be an id of a specific section in the article. Then all you need to do is apply the directive to the links in the sidebar.
...
<li><a href="#section-1" scroll-to>Jump to section 1</a></li>
...
Hope this helps.
This might be what you're looking for http://www.designkode.com/alphascroll-jquery-mobile/
Haven't used it myself, but seems pretty simple to get going with.
I think something like this could work for you: http://codepen.io/aecend/pen/AsnIE. This is just a basic prototype I put together to answer but I could expand on the concept if needed. Basically, it creates a translucent bar on the right side of the screen, finds each of the headings for articles (which would need to be adapted to suit your needs) and places clickable/tappable anchors to jump to individual articles. When you click one, the page scrolls to that article. I have a few ideas to make this actually usable, but here's the proof of concept.
CSS
#scrollhelper {
position: fixed;
top: 0;
right: 0;
height: 100%;
width: 5%;
background-color: rgba(0,0,0,0.2);
overflow: hidden;
}
#scrollhelper .point {
position: absolute;
display: block;
width: 100%;
height: 10px;
margin: 0 auto;
background-color: rgba(0,0,255,0.5);
}
JavaScript
var articles;
function buildScrollHelp() {
var bodyHeight = $("body").height();
var viewHeight = window.innerHeight;
$("#scrollhelper").html("");
articles.each(function() {
var top = $(this).offset().top;
var element = document.createElement("a");
element.className = "point";
element.href = "#" + $(this).attr("id");
element.style.top = ((top / bodyHeight) * viewHeight) + "px";
$(element).on("click", function(e){
e.preventDefault();
$('html, body').animate({
scrollTop: $($(this).attr("href")).offset().top
}, 500);
});
$("#scrollhelper")[0].appendChild(element);
});
}
$(document).ready(function() {
articles = $("body").children("[id]");
$("body").append("<div id=\"scrollhelper\"></div>");
$(window).resize(function(){
buildScrollHelp();
});
buildScrollHelp();
});

Parallax transition with subtle bounce between two anchors/divs

I'm trying to have just one link on my website that links to the 'below-the-fold area' that I'll have a simple contact form at; the idea is to have that link do a nice transition similar to js parallax and once it reaches the below the fold area it kind of subtly 'bounces' a few pixels back up. (The space between anchors is about 800px)
My attempts in the code below, but it's still just being read as an anchor-point without any transition. (Should I be loading a different jQuery library, or load them in a different order?)
Updated Attempt 12-16:
Calling in the head
Libraries being called:
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script>
Just About before closing head tag. (A few inline styles are right before closing </head> if matters)
<script type="text/javascript">
$('a').on('click', function (event) {
event.preventDefault();//stop the browser from jumping to the anchor
var href = $(this).attr('href'),
oset = $(href).offset().top;
$('html, body').stop().animate({
scrollTop : oset
}, 700, function () {
location.hash = href;
});
});
</script>
Mark-up, CTA divs
<div id="top" class="scrollpls"><img src="http://www.mysite.com/imgs/down_btn.png" border="0" style="float:right; margin-top:200px;"></div>
..and near bottom of doc
<div id="bottom" class="scrollpls"><a href="#top">
<img src="http://www.mysite.com/imgs/upsubway.png" style=" float: right;
float: right;
margin-right: -74px;
margin-top: 700px;
}"></a></div>
http://jsfiddle.net/Hpegt/1/
A fiddle created from an early Question regarding this function and states creating a style with the div height in it. Since declaring this for all divs as in the fiddle would break my layout, I tried it with a class
.scrollpls {
height : 500px;
border :0px solid #000;
}
What am I doing wrong here? After I someday get this, I'll be trying to figure out how to implement an 'ease' with a subtle bounce back after it navs to the points.
Thanks for any help
There are tons of built-in easing effects if you include jQueryUI.
Try this modification to your fiddle - http://jsfiddle.net/CzQXC/
$('a').on('click', function (event) {
event.preventDefault();//stop the browser from jumping to the anchor
var href = $(this).attr('href'),
oset = $(href).offset().top;
$('html, body').stop().animate(
{
scrollTop : oset
},
1000,
'easeInOutElastic',
function ()
{
location.hash = href;
}
);
});
Try this:
<script type="text/javascript">
$(function() {
// this should really be in a click handler, but just for an example:
$('html,body').animate({
scrollTop: $("#testtop").offset().top
}, 2000, 'bounce');
});
</script>
Note: the bounce parameter specifies the easing to use. This is part of jQueryUI so you'll need to download that and include it on your page for the effect to work properly.
For some reason it took a few minutes to function after I put the code in, but finally it resolved and I think this was the solution:
#top, #bottom {
height : 130px;
border : 0px solid #000;
overflow:hidden;
}

Categories

Resources