jQuery does not adjust scroll position - javascript

Basically, I want to have certain points on my website, that act like "magnets". If you are near one of these, the window should scroll to the top, similar to this jQuery plug-in : http://benoit.pointet.info/stuff/jquery-scrollsnap-plugin/
The problem is, that the window does not scroll, even though the page is in range of a "magnet".
here is the jQuery:
$(document).ready( function() {
var magnets = [];
var range = 200;
var active = true;
$('.container').each(function(i,obj) {
magnets.push($(this).offset().top);
});
console.log(magnets);
var attract = function(where,time){
$('html, body').animate({
scrollTop: where
}, time);
active = false;
};
//checks the range of a magnet
var magnetic = function(what){
var top = $(window).scrollTop();
var min = top - range;
var max = top + range;
if( (min <= what) && (max >= what) ){
return true;
} else{
return false;
}
}
//returns, wether you are in range of a magnet from your magnets array or not
var inRange = function(){
var magnet = -1;
for(var i=0; i<magnets.length; i++){
if( magnetic(magnets[i]) == true){
magnet = i;
}
}
return magnet;
}
$(window).scroll(function() {
$('.counter').html("");
$('.counter').append("<p>"+inRange()+"</p>");
if(active == true && inRange != -1){
attract(magnets[inRange()]);
}
else if(active == false && inRange() == -1){
active = true;
}
else if(active == true && inRange() == -1){
console.log("fuck");
}
});
});
alternative codepen link: http://codepen.io/NiclasvanEyk/pen/jEMrZr

There is a mistake in your code:
if(active == true && inRange != -1){
attract(magnets[inRange()]);
}
Should be
if(active == true && inRange() != -1){
attract(magnets[inRange()]);
}

Related

How when I scroll highest and then remove class

I have a question about when I scroll highest I want to remove the class that have position fixed because the position fixed will hide my div right, so I need remove it and dont hide my div when I scroll highest.
May I know can only edit the javascript code to solved it? ty
Here is my codepen link
https://codepen.io/WeiKang-Ng/pen/bGxGQwx
Here is js code
(function(){
var doc = document.documentElement;
var w = window;
/*
define four variables: curScroll, prevScroll, curDirection, prevDirection
*/
var curScroll;
var prevScroll = w.scrollY || doc.scrollTop;
var curDirection = 0;
var prevDirection = 0;
var header = document.getElementById('site-header');
var toggled;
var threshold = 100;
var checkScroll = function() {
curScroll = w.scrollY || doc.scrollTop;
if(curScroll > prevScroll) {
// scrolled down
curDirection = 2;
}
else {
//scrolled up
curDirection = 1;
}
if(curDirection !== prevDirection) {
toggled = toggleHeader();
}
prevScroll = curScroll;
if(toggled) {
prevDirection = curDirection;
}
};
var toggleHeader = function() {
toggled = true;
if (curDirection === 2 && curScroll > threshold) {
header.classList.add("nav-on-scroll");
header.classList.remove("show-nav-on-scroll");
} else if (curDirection === 1 && curScroll > threshold) {
header.classList.add("show-nav-on-scroll");
} else {
toggled = false;
}
return toggled
};
window.addEventListener('scroll', checkScroll);
})();
you need to add 2 lines to remove class from the header.
1st line removes the class if the user is scrolling up and has not yet reached the threshold.
2nd line removes the class if the user is not scrolling or has scrolled past the threshold.
modify the toggleHeader function as follow
var toggleHeader = function() {
toggled = true;
if (curDirection === 2 && curScroll > threshold) {
header.classList.add("nav-on-scroll");
header.classList.remove("show-nav-on-scroll");
} else if (curDirection === 1 && curScroll > threshold) {
header.classList.add("show-nav-on-scroll");
header.classList.remove("nav-on-scroll");
} else {
toggled = false;
header.classList.remove("nav-on-scroll");
}
return toggled;
};

How to add a padding top to smooth scroll

I have implemented a javascript smooth scroll in a one page site and works perfectly. However, because I have a fixed nav at the top of the page, when the page scrolls to the anchor, the top of the page disappears behind the nav. How can I offset the scroll of 90px?
Here is the code:
var ss = {
fixAllLinks: function() {
// Get a list of all links in the page
var allLinks = document.getElementsByTagName('a');
// Walk through the list
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if ((lnk.href && lnk.href.indexOf('#') != -1) &&
( (lnk.pathname == location.pathname) ||
('/'+lnk.pathname == location.pathname) ) &&
(lnk.search == location.search)) {
// If the link is internal to the page (begins in #)
// then attach the smoothScroll function as an onclick
// event handler
ss.addEvent(lnk,'click',ss.smoothScroll);
}
}
},
smoothScroll: function(e) {
// This is an event handler; get the clicked on element,
// in a cross-browser fashion
if (window.event) {
target = window.event.srcElement;
} else if (e) {
target = e.target;
} else return;
// Make sure that the target is an element, not a text node
// within an element
if (target.nodeName.toLowerCase() != 'a') {
target = target.parentNode;
}
// Paranoia; check this is an A tag
if (target.nodeName.toLowerCase() != 'a') return;
// Find the <a name> tag corresponding to this href
// First strip off the hash (first character)
anchor = target.hash.substr(1);
// Now loop all A tags until we find one with that name
var allLinks = document.getElementsByTagName('a');
var destinationLink = null;
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if (lnk.name && (lnk.name == anchor)) {
destinationLink = lnk;
break;
}
}
if (!destinationLink) destinationLink = document.getElementById(anchor);
// If we didn't find a destination, give up and let the browser do
// its thing
if (!destinationLink) return true;
// Find the destination's position
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent &&
(thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
// Stop any current scrolling
clearInterval(ss.INTERVAL);
cypos = ss.getCurrentYPos();
ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
ss.INTERVAL =
setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',20);
// And stop the actual click happening
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}
},
scrollWindow: function(scramount,dest,anchor) {
wascypos = ss.getCurrentYPos();
isAbove = (wascypos < dest);
window.scrollTo(0,wascypos + scramount);
iscypos = ss.getCurrentYPos();
isAboveNow = (iscypos < dest);
if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
// if we've just scrolled past the destination, or
// we haven't moved from the last scroll (i.e., we're at the
// bottom of the page) then scroll exactly to the link
window.scrollTo(0,dest);
// cancel the repeating timer
clearInterval(ss.INTERVAL);
// and jump to the link directly so the URL's right
location.hash = anchor;
}
},
getCurrentYPos: function() {
if (document.body && document.body.scrollTop)
return document.body.scrollTop;
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
if (window.pageYOffset)
return window.pageYOffset;
return 0;
},
addEvent: function(elm, evType, fn, useCapture) {
// addEvent and removeEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.addEventListener){
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent){
var r = elm.attachEvent("on"+evType, fn);
return r;
} else {
alert("Handler could not be removed");
}
}
}
ss.STEPS = 25;
ss.addEvent(window,"load",ss.fixAllLinks);
Thanks in advance for your help!
You can do a calculation when setting the destination coordinates:
// Find the destination's position
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent &&
(thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
//subtract nav from offset position
desty = desty - 90;
if(desty < 0){ desty = 0; }
That being said, using a static number is dangerous business. Might make more sense to calculate minus the header's actual height instead.
Simply make changes in the CSS:
html{
scroll-behavior: smooth;
scroll-padding-top: 50px;
}
This will handle your fixed header issue.

make message always on the top

i want to make a message which will be always on the top however scrolling the page using java script.
i tried the below code, but when i scroll it still on its static place
var message = '<b><font color=000000 size=5>mona link to us! </font></b>'
//enter a color name or hex to be used as the background color of the message
var backgroundcolor = "#FFFF8A"
//enter 1 for always display, 2 for ONCE per browser session
var displaymode = 1
//Set duration message should appear on screen, in seconds (10000=10 sec, 0=perpetual)
var displayduration = 0
//enter 0 for non-flashing message, 1 for flashing
var flashmode = 1
//if above is set to flashing, enter the flash-to color below
var flashtocolor = "lightyellow"
var ie = document.all
var ieNOTopera = document.all && navigator.userAgent.indexOf("Opera") == -1
function regenerate() {
window.location.reload()
}
function regenerate2() {
if (document.layers)
setTimeout("window.onresize=regenerate", 400)
}
var which = 0
function flash() {
if (which == 0) {
if (document.layers)
topmsg_obj.bgColor = flashtocolor
else
topmsg_obj.style.backgroundColor = flashtocolor
which = 1
}
else {
if (document.layers)
topmsg_obj.bgColor = backgroundcolor
else
topmsg_obj.style.backgroundColor = backgroundcolor
which = 0
}
}
if (ie || document.getElementById)
document.write('<div id="topmsg" style="position:absolute;visibility:hidden">' + message + '</div>')
var topmsg_obj = ie ? document.all.topmsg : document.getElementById ? document.getElementById("topmsg") : document.topmsg
function positionit() {
var dsocleft = ie ? document.body.scrollLeft : pageXOffset
var dsoctop = ie ? document.body.scrollTop : pageYOffset
var window_width = ieNOTopera ? document.body.clientWidth : window.innerWidth - 20
var window_height = ieNOTopera ? document.body.clientHeight : window.innerHeight
if (ie || document.getElementById) {
topmsg_obj.style.left = parseInt(dsocleft) + window_width / 2 - topmsg_obj.offsetWidth / 2
topmsg_obj.style.top = parseInt(dsoctop) + parseInt(window_height) - topmsg_obj.offsetHeight - 4
}
else if (document.layers) {
topmsg_obj.left = dsocleft + window_width / 2 - topmsg_obj.document.width / 2
topmsg_obj.top = dsoctop + window_height - topmsg_obj.document.height - 5
}
}
function setmessage() {
if (displaymode == 2 && (!display_msg_or_not()))
return
if (document.layers) {
topmsg_obj = new Layer(window.innerWidth)
topmsg_obj.bgColor = backgroundcolor
regenerate2()
topmsg_obj.document.write(message)
topmsg_obj.document.close()
positionit()
topmsg_obj.visibility = "show"
if (displayduration != 0)
setTimeout("topmsg_obj.visibility='hide'", displayduration)
}
else {
positionit()
topmsg_obj.style.backgroundColor = backgroundcolor
topmsg_obj.style.visibility = "visible"
if (displayduration != 0)
setTimeout("topmsg_obj.style.visibility='hidden'", displayduration)
}
setInterval("positionit()", 100)
if (flashmode == 1)
setInterval("flash()", 1000)
}
function get_cookie(Name) {
var search = Name + "="
var returnvalue = ""
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search)
if (offset != -1) {
offset += search.length
end = document.cookie.indexOf(";", offset)
if (end == -1)
end = document.cookie.length;
returnvalue = unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}
function display_msg_or_not() {
if (get_cookie("displaymsg") == "") {
document.cookie = "displaymsg=yes"
return true
}
else
return false
}
if (document.layers || ie || document.getElementById)
window.onload = setmessage
any help. or any new code please
If I'm understanding what you want, I think you're totally over thinking it. You can use CSS to keep your message fixed at the top of the page. just add position: fixed. It's how I make my header stay at the top of the page on this site: http://www.recipegraze.com
So use javascript to make the message appear/disappear, but use some simple CSS to make it stick to the top of the page.
edit: you'll also want to up the z-index of the message to make sure it appears on top of your other content, not under it.

Easy Smooth Scroll Plugin: How do I offset scroll?

I am using the Easy Smooth Scroll Plugin for Wordpress.
Below is the .js file that the plugin uses:
var ss = {
fixAllLinks: function() {
var allLinks = document.getElementsByTagName('a');
for (var i = 0; i < allLinks.length; i++) {
var lnk = allLinks[i];
if ((lnk.href && lnk.href.indexOf('#') != -1) && ((lnk.pathname == location.pathname) || ('/' + lnk.pathname == location.pathname)) && (lnk.search == location.search)) {
ss.addEvent(lnk, 'click', ss.smoothScroll);
}
}
},
smoothScroll: function(e) {
if (window.event) {
target = window.event.srcElement;
} else if (e) {
target = e.target;
} else return;
if (target.nodeName.toLowerCase() != 'a') {
target = target.parentNode;
}
if (target.nodeName.toLowerCase() != 'a') return;
anchor = target.hash.substr(1);
var allLinks = document.getElementsByTagName('a');
var destinationLink = null;
for (var i = 0; i < allLinks.length; i++) {
var lnk = allLinks[i];
if (lnk.name && (lnk.name == anchor)) {
destinationLink = lnk;
break;
}
}
if (!destinationLink) destinationLink = document.getElementById(anchor);
if (!destinationLink) return true;
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent && (thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
clearInterval(ss.INTERVAL);
cypos = ss.getCurrentYPos();
ss_stepsize = parseInt((desty - cypos) / ss.STEPS);
ss.INTERVAL = setInterval('ss.scrollWindow(' + ss_stepsize + ',' + desty + ',"' + anchor + '")', 10);
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}
},
scrollWindow: function(scramount, dest, anchor) {
wascypos = ss.getCurrentYPos();
isAbove = (wascypos < dest);
window.scrollTo(0, wascypos + scramount);
iscypos = ss.getCurrentYPos();
isAboveNow = (iscypos < dest);
if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
window.scrollTo(0, dest);
clearInterval(ss.INTERVAL);
location.hash = anchor;
}
},
getCurrentYPos: function() {
if (document.body && document.body.scrollTop) return document.body.scrollTop;
if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop;
if (window.pageYOffset) return window.pageYOffset;
return 0;
},
addEvent: function(elm, evType, fn, useCapture) {
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent) {
var r = elm.attachEvent("on" + evType, fn);
return r;
} else {
alert("Handler could not be removed");
}
}
}
ss.STEPS = 25;
ss.addEvent(window, "load", ss.fixAllLinks);
The live page is here: http://iamjoepro.com/album/promaha/
I have the smooth scroll scrolling to an anchor, but I would like to offset it by the height of my fixed header (120px)
I am no javascript expert, I'm hoping this is easy for someone, but I can't decipher where to add the offset in my .js file?
I had a similar issue and found that the following solution worked for me.
Change the line:
var desty = destinationLink.offsetTop;
to read:
var desty = destinationLink.offsetTop - 120;
(where '120' is the height in pixels of your fixed header)
Then, remove the line:
location.hash = anchor;
(otherwise, the page will scroll to your 120px offset but then return back to the location of the anchor)
Hope this helps!

Navigate up and down in scrollable div with keycodes

I have a searchable textbox which populates a div with the search results. The div is scrollable. What I am trying to achieve, is to navigate through the result items with page up and down (keycode 38 & 40). But as soon as I try this, the whole div scrolls, and the result item itself does not take on the new selected css class.
Below is some of my code
this.TagNavigation = function (event) {
var div = $("#TagSearchResults");
var anchors = $("#TagSearchResults a");
var selectedAnchor = $("#TagSearchResults a.selected");
var position = anchors.index(selectedAnchor);
if (event.keyCode == "13" && anchors.length > 0) {
FRAMEWORK.AddUpdateInterventionTags(selectedAnchor.attr("id").split("-")[1] + "|" + selectedAnchor.text(), "add");
}
if (event.keyCode == "13" && anchors.length == 0 && $("#txtTagSearch").val() != "Start typing to search Tags") {
FRAMEWORK.AddNewTag($("#txtTagSearch").val());
}
else if (event.keyCode == "38") {
if (position > 0) {
canClose = false;
selectedAnchor.removeClass("selected");
var newSelectedAnchor = $(anchors.get(position - 1));
newSelectedAnchor.addClass("selected");
$("#txtTagSearch").val(newSelectedAnchor.text());
}
}
else if (event.keyCode == "40") {
if (position <= anchors.length) {
canClose = false;
selectedAnchor.removeClass("selected");
var newSelectedAnchor = $(anchors.get(position + 1));
newSelectedAnchor.addClass("selected");
$("#txtTagSearch").val(newSelectedAnchor.text());
//newSelectedAnchor.focus();
}
}
};
this.AjaxSearch = function (text) {
var div = $("#TagSearchResults");
var anchors = $("#TagSearchResults a");
var selectedAnchor = $("#TagSearchResults a.selected");
var position = anchors.index(selectedAnchor);
if (event.keyCode == "13") {
FRAMEWORK.TagNavigation(event);
}
else if (event.keyCode == "38") {
FRAMEWORK.TagNavigation(event);
}
else if (event.keyCode == "40") {
FRAMEWORK.TagNavigation(event);
}
else if (text.length >= 3) {
FRAMEWORK.RenderSearchResults(text);
}
else {
$("#TagSearchResults").html("");
$("#TagSearchResults").hide();
}
};
As you can see in the TagNavigation function (keycode 40), I tried to set the focus on the active element, but still no success.
Any help please.
You need to check weather the newly selected element has a higher Y value that the bottom of the containing div. If so, then scroll the div by the height of the new element. Change your 'if (event.keyCode == "40")' statement to the following:
this.TagNavigation = function (event) {
var div = $("#TagSearchResults");
var anchors = $("#TagSearchResults a");
var selectedAnchor = $("#TagSearchResults a.selected");
var position = anchors.index(selectedAnchor);
if (event.keyCode == "13" && anchors.length > 0) {
FRAMEWORK.AddUpdateInterventionTags(selectedAnchor.attr("id").split("-")[1] + "|" + selectedAnchor.text(), "add");
}
if (event.keyCode == "13" && anchors.length == 0 && $("#txtTagSearch").val() != "Start typing to search Tags") {
FRAMEWORK.AddNewTag($("#txtTagSearch").val());
}
else if (event.keyCode == "38") {
if (position > 0) {
canClose = false;
selectedAnchor.removeClass("selected");
var newSelectedAnchor = $(anchors.get(position - 1));
newSelectedAnchor.addClass("selected");
$("#txtTagSearch").val(newSelectedAnchor.text());
var newSelectedAnchorPosistion = newSelectedAnchor.offset();
var divPosition = div.offset();
divPosition = divPosition.top;
if (newSelectedAnchorPosistion.top + 1 > divPosition) {
var newPos = div.scrollTop() - newSelectedAnchor.outerHeight();
div.scrollTop(newPos);
}
}
}
else if (event.keyCode == "40") {
if (position < anchors.length - 1) {
canClose = false;
selectedAnchor.removeClass("selected");
var newSelectedAnchor = $(anchors.get(position + 1));
newSelectedAnchor.addClass("selected");
$("#txtTagSearch").val(newSelectedAnchor.text());
var newSelectedAnchorPosistion = newSelectedAnchor.offset();
var divPosition = div.offset();
divPosition = divPosition.top + div.outerHeight();
if (newSelectedAnchorPosistion.top + 1 >= divPosition) {
var newPos = div.scrollTop() + newSelectedAnchor.outerHeight();
div.scrollTop(newPos);
}
}
}
};

Categories

Resources