Toggle between Relative to Fixed position on scrpll - javascript

I believe that it's a very small tweak to make it work...
I need to switch between fixed to relative position.
JSFiddle
$(window).on('scroll', function() {
($(window).scrollTop() > 50) ? ($('.me').addClass('fixed')) : ($('.me').removeClass('fixed'))
};
.fixed {
position: fixed;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<br><br><br><br><br><br><br><br><br>
<div class="me">123</div>
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
Where is the exact bug?

This is working fine for me.....
$(window).on('scroll', function () {
($(window).scrollTop() > 50) ? $('.me').addClass('fixed') : $('.me').removeClass('fixed');
});
may be some brackets missing... and if you want to put css directly with jquery use .css();
working Fiddle

Related

Fixed div on scroll and change state using CSS and sticky.js

I'm currently using sticky.js to fix a div to the top of my screen when I scroll. This works perfectly and I wouldn't want to change it but I would like to apply some css to the div to effect some change when it sticks.
I have tried implementing some JavaScript to the sticky script but it's still not working.
This is what I have now:
HTML
<div class="header"><div class="small_logo"><img src=""></div></div>
JavaScript
$(document).ready(function(){
$(".header").sticky({
topSpacing: 0,
success: function() {
$('.header').addClass("wide");
$('.small_logo').fadeIn("slow");
}
});
});
I'm sure it's just a simple javascript format issue but I just can't seem to find the right syntax.
Further to #Alex's point, the documentation does not describe any success option that you have used in your code.
The correct way would be to use the events that have been described in the documentation on github
I've given an example below.
$(document).ready(function(){
$(".header").sticky({topSpacing: 0});
$('.header').on('sticky-start', function() {
$(".small_logo img").fadeIn("slow");
});
$('.header').on('sticky-end', function() {
$(".small_logo img").fadeOut("slow");
});
});
.header {
background: #EEE;
height: 100px;
}
.small_logo img{
height: 100px;
display: none;
}
.body {
height: 1000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.sticky/1.0.4/jquery.sticky.min.js"></script>
<div class="header">
<div class="small_logo">
<!-- <a href="/"> -->
<img src="https://i.ytimg.com/vi/YCaGYUIfdy4/maxresdefault.jpg">
<!-- </a> -->
</div>
</div>
<div class="body"></div>
Did you see the brief documentation on GitHub?
According to the section about events you will need to do the following:
$('.header').on('sticky-start', function() { // your code });
You can use this simple example. Or this code:
<script>
var prevScrollpos = window.pageYOffset;
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
$('.header').css({top: '0px'});
} else {
$('.header').css({top: '-50px'});
}
prevScrollpos = currentScrollPos;
}
</script>
Try this
var header = document.getElementById("myHeader");
var sticky = header.offsetTop;
$(window).scroll(function() {
if (window.pageYOffset > sticky) {
header.classList.add("sticky");
} else {
header.classList.remove("sticky");
}
})
.sticky {
position: fixed;
top: 0;
width: 100%
}
apply css to sticky class for effect

jQuery on scroll toggle between two classes

By default I have a navigation bar which has a red background color.
What I want to do is when the users scrolls down more than 100px to change the background to blue and if he goes back to 0px to change the background to it's default state.
I want to do this by toggling between two classes, for example <div class="navigation red"> should be the default class and if the user scroll down to add <div class="navigation blue"> and if he scrolls back to have <div class="navigation red"> again.
Here is my attempt :
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() > 100){
$('.navigation').toggleClass( "blue");
}
});
});
But this is not working. Here's a jsbin.
Any ideas how to get it to work ?
Try the following code:
$(document).ready(function () {
$(window).scroll(function () {
$('.navigation').toggleClass("blue", ($(window).scrollTop() > 100));
});
});
Here's the example in jsbin
Using toggleClass() may be the wrong solution for this. Use addClass/removeClass instead:
if ($(window).scrollTop() > 100){
$('.navigation').addClass( "blue");
}
else {
$('.navigation').removeClass("blue");
}
You can use .addClass() and removeClass()like this one: http://jsfiddle.net/csdtesting/qhfmw8hx/
$(window).scroll(function() {
var windowYmax = 100;
var scrolledY = $(window).scrollTop();
if (scrolledY > windowYmax) {
$('.navigation').addClass("blue");
} else {
$('.navigation').removeClass("blue");
$('.navigation').addClass("red");
}
});
.navigation {
height: 800px;
}
.navigation.red {
background: red;
}
.navigation.blue {
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navigation red">scroll me down and up please to see me changing colors...</div>
Hope it helps!
The problem is that you call toggleClass everytime the user scrolls. This code would fix this issue:
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() > 100 && !$( ".navigation" ).hasClass( "blue" ) || $(window).scrollTop() === 0 && $( ".navigation" ).hasClass( "blue" ){
$('.navigation').toggleClass( "blue");
}
});
});
The jsbin
You're working with adding a class and removing another, i would suggest just using addClass and removeClass for this case. Also you can chain the methods.
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() > 100){
$('.navigation').addClass('blue').removeClass('red');
} else {
$('.navigation').addClass('red').removeClass('blue');
}
});
});
Here's the jsbin

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();
});

Floating Menu in PrototypeJS

can someone please help me make a floating menu in prototypeJS? I found documentation to do it in jQuery, like here: net.tutsplus.com/tutorials/html-css-techniques/creating-a-floating-html-menu-using-jquery-and-css/ and here: manos.malihu.gr/jquery-floating-menu, but can't figure out where to start for prototypeJS.
So I got it work, sorta. I found documentation here. Here's my code:
<html>
<head>
<title>Prototype examples</title>
<script src="lib/prototype/prototype.js" type="text/javascript"></script>
<script type="text/javascript">
Event.observe(window,'scroll', function(evt){
$('movable').setStyle({ top: 8 + document.viewport.getScrollOffsets().top + 'px' });
});
</script>
<style type="text/css">
#container {
background:#000;
padding:100px 10px 10px;
}
#movable {
position: absolute;
float:left;
width:18.5%;
height: 300px;
background-color: red;
}
#firstDiv {
background:#ccc;
float:right;
height:1200px;
width:80%;
}
.clear-both {clear:both;}
</style>
</head>
<body>
<div id="container">
<div id="movable"> Floating menu</div>
<div id="firstDiv">right</div>
<div class="clear-both"></div>
</div>
</body>
</html>
So now I'm trying to get it so it's not choppy when you scroll, and so the menu doesnt start moving until the scroll has moved down to like 100px vertically or something, so it hooks into place.
Figured it out with some help. Used this tutorial: http://jqueryfordesigners.com/fixed-floating-elements/
But changed it up to use Prototype JS syntax. Here's the code:
var topMenu = $('ELEMENT').cumulativeOffset().top;
Event.observe(window,'scroll', function(evt) {
// what the y position of the scroll is
var y = document.viewport.getScrollOffsets().top;
// console.log(y) // console
// check which browser it's using
if (false) { // newer browsers, could be "false"
if (y >= topMenu) {
// if so, ad the fixed class
$('ELEMENT').addClassName('fixed');
} else {
// otherwise remove it
$('ELEMENT').removeClassName('fixed');
}
}
else { // older browsers, iPad, iPhone
if (y >= topMenu) {
$('ELEMENT').setStyle({ top: (0 + document.viewport.getScrollOffsets().top - topMenu) + 'px' });
}
else {
$('ELEMENT').setStyle({ top: 0 + 'px' });
}
}
});
If you want it to not look choppy, you're going to have to use an animation library. If you're using Prototype, then your best bet is to look into Scriptaculous at http://script.aculo.us/
I'd also recommend using Element.cumulativeOffset on DOM load to get the absolute top offset of the menu. Then each time you scroll the menu element, include this initial padding so the menu doesn't just latch on to the top of the viewport.
One more idea too, if you don't particularly want to use an animation library, you could try making the menu position: fixed. You'll still have to keep updating the position for IE though, as it doesn't support fixed positioning ...

jquery drag image

i want to make a draggable image in jquery.
first of all my experience with jquery is 0. having said that let me describe what i want to achieve. i have fixed width/height div. and the image contained inside the div is large in size. so i want the image to be draggable inside that div so that the user can see the entire image.
can someone help. pls be a little elaborate about the procedure considering my jquery fluency.
You can use the following;
$(function() {
$("#draggable").draggable();
});
.container {
margin-top: 50px;
cursor: move;
}
#screen {
overflow: hidden;
width: 200px;
height: 200px;
clear: both;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="container">
<div id="screen">
<img src="https://picsum.photos/200/200" class="drag-image" id="draggable" />
</div>
</div>
You want the jQuery Draggable UI tool. The code for this, as with all jQuery, is very simple:
$(document).ready(function(){
$("#draggable").draggable();
});
Will create a draggable object from a standard html tag (the IMG in your case). And for limiting it's mobility to a specific region, you would look into its containment option.
Update: "What is '#draggable' and 'ready'"?
'#draggable' represents the element that you want to be able to drag. The hash (#) symbol represents an ID. When you add your image tags, may give give it an id like the following:
<img src="myimage.jpg" id="draggable" />
That will make the javascript above make your image draggable, because it has the '#draggable' id that the jQuery is looking for.
'.ready()' is the method that is automagically raised by your browser once the page is finished loading. Developers are encouraged by the jQuery group to place all jQuery code within this method to ensure all of the elements on the page are completely loaded prior to any jQuery code attempts to manipulate them.
to limit to a region for this example, containment is not much of a help.
I have implemented this for vertical only scroll, needs enhancement for horizontal limit:
stop: function(event, ui) {
var helper = ui.helper, pos = ui.position;
var h = -(helper.outerHeight() - $(helper).parent().outerHeight());
if (pos.top >= 0) {
helper.animate({ top: 0 });
} else if (pos.top <= h) {
helper.animate({ top: h });
}
}
$('#dragMe').draggable({ containment: 'body' });
This code will make it posible to drag the div with the ID of dragMe where ever you want inside the body of the document. You can also write a class or id as containment.
$('#dragMe').draggable({ containment: '#container' });
This code will make the div dragMe able to be draggable inside of the id container.
Hope this helps otherwise you should be able to find your answer here http://jqueryui.com/demos/draggable/
Expanding on the answer from PH. this will provide an elastic bounceback whenever the image is dragged to the point the underlying container is exposed:
stop: function(event, ui) {
var helper = ui.helper, pos = ui.position;
var h = -(helper.outerHeight() - $(helper).parent().outerHeight());
var w = -(helper.outerWidth() - $(helper).parent().outerWidth());
if (pos.top <= h) {
helper.animate({ top: h });
} else if (pos.top > 0) {
helper.animate({ top: 0 });
}
if (pos.left <= w) {
helper.animate({ left: w });
} else if (pos.left > 0) {
helper.animate({ left: 0 });
}
}

Categories

Resources