Scroll Handling with Javascript - javascript

I am new to web programming and I stumbled on something strange while working on my website. I use Wordpress but here I had to dive in the Javascript code to get it done.
What I want to achieve is the following:
I want people to get to see the header of my website when they arrive but not be bothered by it once they read stuff on my site.
What I figured out is that I want the website to scroll down if a) people are at the top of the site and b) if they click on a menu link. When people are already on the site and click on a menu item to change pages, I would like to maintain the scroll position of where they were before.
I tried two versions:
This one works like a charm except that the function executes on each reload of the site
var scroll_position = localStorage.getItem('scroll_position');
var header_height = document.getElementById('masthead').offsetHeight;
var menubar_height = document.getElementById('top-bar').offsetHeight;
var page_height = header_height - menubar_height;
jQuery(function () {
if (window.pageYOffset == scroll_position){
jQuery(window).scrollTop(page_height);
}
else{
jQuery(window).scrollTop(scroll_position);
}
});
But as I wanted to execute the function only on clicking one of the menu items, I tried:
jQuery("#top-menu ul li a").click(function(){
if (window.pageYOffset == scroll_position){
jQuery(window).scrollTop(page_height);
}
else{
jQuery(window).scrollTop(scroll_position);
}
});
and suddenly the scroll_position variable doesn't change value as before...
I spend the whole day trying to figure this out and I would appreciate very much if someone out there could tell me what I'm doing wrong!
Thanks in advance.

According to the code you gave us, try this
jQuery(function () {
var header_height = document.getElementById('masthead').offsetHeight;
var menubar_height = document.getElementById('top-bar').offsetHeight;
var page_height = header_height - menubar_height;
jQuery("#top-menu ul li a").click(function(e){
e.preventDefault();
var scroll_position = localStorage.getItem('scroll_position');
if (window.pageYOffset == scroll_position){
jQuery(window).scrollTop(page_height);
}
else{
jQuery(window).scrollTop(scroll_position);
}
});
});
I'm assumig that header_height, menubar_height and page_height can't get altered once the page is loaded, thats why we init them on the page load, not on the click.
Hope it's gonna help you

Related

Trouble with Javascript in Wordpress

I'm trying to create an element in a Wordpress site where a piece of content begins partway down the screen, and sticks to the top of the screen when the user scrolls down.
I've tried various things, and none of them have worked. The most recent attempt uses Javascript to give and take away a class to the content I'm trying to move/fix.
The code is
jQuery( document ).ready(function($) {
alert( "test1!" );
var wrap = $("#wrap");
wrap.on("scroll", function(e) {
if (this.scrollTop > 147) {
wrap.addClass("fix-search");
alert("test2");
} else {
wrap.removeClass("fix-search");
}
});
});
The file is enqueuing properly since the first test alert ("test1" fires, but "test2" doesn't fire as I scroll down the screen. I've had that same piece of code working in a modified version of the original code on codepen (http://codepen.io/anon/pen/NqKKVN) so I can only assume this is something weird with Wordpress interacting with Javascript.
So yeah, anyone know a way to either do that I'm wanting to do in a way that will work with wordpress, or to get the above piece of code working properly?
EDIT: This has been solved. For the reference of anyone else with the same problem the piece of code that eventually worked was
jQuery( document ).ready(function($) {
var scrollTop = $(window).scrollTop();
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
var wrap = $("#menu-all-pages");
if (scrollTop > 147) {
wrap.addClass("fix-search");
console.log("Menu at top");
} else {
wrap.removeClass("fix-search");
console.log("Menu at set point");
}
console.log(scrollTop);
}
window.onscroll = scrollUpdate;
});
I have implemented a similar solution in my blog a few years ago. I got it working by scripting this way:
Add a variable scrollTop which would contain the value in pixels
scrolled from the window top.
var scrollTop = $(window).scrollTop();
See, I use jquery function scrollTop applied to the selected object "window". It would return the value scrolled from the very top of the browser. It does work on Wordpress, I have tried it on my blog.
Put this code in a function scrollUpdate. We'll call it later to update
the scroll value from top
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
}
The function should also contain all the logic checking the scrollTop value and thus applying styles and etc.
Let's make this function be called on every scroll.
window.onscroll = scrollUpdate;
Try it yourself!
P.S. I got a weird feeling, but you should better use hide / show instead of adding a whole css class to the page.

Button link to different ID with scroll

I'm trying to make a single down arrow that jumps to the next ID on the page as you scroll down. I don't really know JavaScript so I'm trying to keep it as simple as possible. I thought, as there are only a few sections, that I could just hide and display different divs with arrows that have different targets. I used two different codes to arrive at this, but doesn't seem to be working. Any ideas?
<script type="text/javascript">
$(window).scroll(function(){
if($(window).scrollTop() >= 800) {
var elem = document.getElementById("arrow");
elem.setAttribute("style","display:none;");
} else {
elem.setAttribute("style","display:inline;");
}
});
</script>
I'm not sure I understand exactly what you want to do, but your code can be simplified a bit by taking advantage of the shortcuts that jQuery provides.
//When the document is ready...
$(function(){
//Select the arrow just once
var arrow = $("#arrow");
//Attach a scroll event to the window
$(window).scroll(function(){
//See what the scroll position is
var scrollPos = document.body.scrollTop;
//When the document has scrolled to a certain point or more, hide the arrow.
//Otherwise, show it.
if(scrollPos >= 800){
arrow.hide();
} else {
arrow.show();
}
});
});
Here's a brief demo of it in action: http://jsfiddle.net/Bt35Q/

Menu bar scrolling not working in IE

I have a flyover dropdown menu and when I scroll down the page this menu need to appear all the time. I have this below code which is working fine for FFox and chrome but IE8 and I hope IE9 its not working. Not sure whats causing the issue. Please suggest if any change need to be done to work with IE as well
var name = ".cssMenu";
//var menuYloc = null;
$(document).ready(function(){
//menuYloc = parseInt($(name).css("top").substring(0,$(name).css("top").indexOf("px")))
$(window).scroll(function () {
if($(this).scrollTop()>70){
offset =$(document).scrollTop()-70+"px";
}
else
{
offset = $(document).scrollTop()+"px";
}
$(name).css("top",offset);
});
});
i blind shoot suspect it being the order its executed. try wrapping it in () like:
`offset =($(document).scrollTop()-70)+"px";`

jQuery script fires twice? Perhaps live event is firing twice?

I am building an application using the latest version of PhoneGap, jQM and jQuery 1.8.0. So far so good except for this tiny and annoying problem I came across.
I have my show.html linked from the index.html that contains the following code:
<div id="search"> contains search bar and submit button </div>
<div id="list" style="display:none;">
<ul data-role="listview" data-filter="true"> </ul>
</div>
The ul tag is empty because the list will be dynamically appended to it using ajax when the submit button is clicked. I didn't want to display the #list div at first so I set the display to none.
So this works fine, when the submit button is clicked, it will send an ajax request to the server and append the items to the list. It will also hide the search div. This works alright as well!
Now the problem comes in, I added a window.scroll function to detect when the bottom of the page is reached.
Here's my jQuery code:
$(document).on("pageshow", "#pageID", function() {
$("#submit").click(function() {
$.ajax({
success: function(data, status){
$('#search').hide();
$('#list').show();
//append to list div and refresh list here
}
});
});
//detects bottom of page
$(window).scroll(function () {
if ($(window).scrollTop()+200 >= ($(document).height() - ($(window).height()))) {
console.log('end of the page');
lastPostFunc(); //infinite scroll function
}
});
});
This prints 'end of the page' two times to the firebug console! This script exists in between the head tag.
Is there anyway to just make it print once? I need this because I implemented my own endless scroll function and the problem is causing my ajax request to post twice to the server. The function works great but is not the cause of the problem because even when I commented lastPostFunc() out, it still prints to the console twice!!
Edit: Personally, I don't think the answers given so far are wrong, they are correct but they do not help me solve the problem. Maybe I need to rephrase things better. I copied my code and pasted it on a standalone page, it prints only once, so my code actually has nothing wrong with it and it's working like it should be.
Therefore, I was wondering whether there's something else that's causing it to print twice after submitting the form. My form and my results page is ON the same page. Does this means it caused the live event to work twice? Thus, causing it to print to the console twice on pageshow? If I am correct, is there anyway to work around this and making it only print ONCE?
Any help is appreciated. Thank you!
Okay I finally solved it.
Apparently all I have to do is to add this line of code to it:
$(window).scroll(function (e) {
if (reach bottom) {
e.stopImmediatePropagation();
console.log('End of the Page');
}
});
And it works! Stopped printing twice for me.
Your function will actually write output to the console more than two times. The problem lies within your condition:
if ($(window).scrollTop()+200 >= ($(document).height() - ($(window).height())))
Because for every scroll within this area the condition will evaluate to true. You could change it to:
if ($(window).scrollTop() == ($(document).height() - ($(window).height())))
May this will solve your problem
jQuery(window).scroll(function() {
if( (jQuery(document).height() < (jQuery(window).scrollTop() + jQuery(window).height() + 200))&&(jQuery(document).height() > (jQuery(window).scrollTop() + jQuery(window).height() + 99))) {
console.log('test')
}
});
//Update
var lastlogtime= null;
jQuery(window).scroll(function() {
if( (jQuery(document).height() < (jQuery(window).scrollTop() + jQuery(window).height() + 200))&&(jQuery(document).height() > (jQuery(window).scrollTop() + jQuery(window).height() + 99))) {
if(((lastlogtime+600)<(+new Date())) || (lastlogtime== null)){
//your scroll logic
console.log('test') ;
lastlogtime= +new Date();
}
}
});

iscroll scrollToElement not updating currPage variable

UPDATE:
I was able to get my scroller working as desired but I feel like I have hacked around the actual issue and would love it if anyone has a more solid answer, I've updated and noted in the snippets below the new jQuery I'm using.
I'm using iScroll-4 (http://cubiq.org/iscroll-4) for an iPad/Android web app, everything's working perfectly with the swipes and scrolling but I have a table of contents at the beginning of the app that allows users to jump to specific areas of the scroller --
I'm using the iScroll function scrollToElement(element, duration) in order to jump to the different areas. Also using scrollToPage(page, duration) to allow the user to manually navigate forward and backward one page at a time.
While watching the console logs the currPageX variable updates when I navigate with the scrollToPage function and when I swipe, but when using the scrollToElement the currPageX variable does not update.
Therefore if I jump to an element and then navigate forward with scrollToPage('next', 0) it will go backwards and navigate me to the next page after the table of contents.
I have tried using the scroll.refresh() function after scrollToElement, before, putting the function inside a timeout, etc. and I can't figure out why the currPageX is not updating.
Here's a snippet of the jQuery code that I'm using the two different functions:
// TO NAVIGATE FORWARD AND BACKWARDS
$('span.control').on('click', function() {
var slideDir = $(this).attr('data-dir');
if (slideDir == 'prev') {
var tehPg = tehScroll.currPageX-1;
} else if (slideDir == 'next') {
var tehPg = tehScroll.currPageX+1;
}
tehScroll.scrollToPage(tehPg, 0);
return false;
});
// TO JUMP FROM CONTENTS
$('li[data-page="toc"] span').on('click', function() {
var toPage = $(this).attr('data-page');
tehScroll.scrollToElement('li[data-page="'+toPage+'"]', 800);
// ADDED THE FOLLOWING LINE TO MANUALLY SET currPageX after scrolling!
tehScroll.currPageX = $('#slides li[data-page="'+toPage+'"]').index();
return false;
});
Did you consider using jquery-mobile-iscrollview widget plug-in? - there is a function scrollToPage(pageX, pageY, time), works well for me...
best
M

Categories