Variables won't increment in a jQuery function? - javascript

I was just doing some last minute touches when I came across a problem with my code:
$(document).ready(function()
{
/* Declaring some variables to help with scrolling through my Portfolio */
var workArray = [];
var scrollPos = 1;
/* This makes the left scroll arrow disappear if it's
at the start (scrollPos is less then or equal to 1) */
if (scrollPos <= 1) {
$('#left_scroll').hide();
} else {
$('#left_scroll').show();
}
/*This SHOULD decrement and increment values to the scrollPos variable
when the corresponding arrows are clicked*/
$('#left_scroll').click(function(){
scrollPos--;
});
$('#right_scroll').click(function(){
scrollPos++;
});
(left_scroll) is assigned to an arrow key on my page that is suppose to subtract from the value (scrollPos) that tells when the left or right arrow image should be visible.
Currently I have the value scrollPos set to 1, so the left arrow key is invisible and the right one is visible, but for some reason, when either one is clicked it doesn't appear as though any values are changed as the left arrow key remains invisible.
Can anyone see any problems with my code, hope you can help. :D
Martin

The click handlers are just doing what you told them to do, and that is increment and decrement. You didn't tell the handlers to do anything else, like some hide and show.
Place the logic inside for hide and show inside the handler functions in order to hide and show on clicking your buttons.

Working jsFiddle Demo
You must call your if statement after your increment/decrement.
Make a function for this:
function checkScrollPos() {
/* This makes the left scroll arrow disappear if it's
at the start (scrollPos is less then or equal to 1) */
if (scrollPos <= 1) {
$('#left_scroll').hide();
} else {
$('#left_scroll').show();
}
}
And after your click, call it:
$('#left_scroll').click(function(){
scrollPos--;
checkScrollPos();
});
$('#right_scroll').click(function(){
scrollPos++;
checkScrollPos();
});

Your code:
if (scrollPos <= 1) {
$('#left_scroll').hide();
} else {
$('#left_scroll').show();
}
Only executes one time. If you want to check scrollPos value every time your arrows get clicked, use a function:
function hideOrShow(scrollPos) {
if (scrollPos <= 1) {
$('#left_scroll').hide();
} else {
$('#left_scroll').show();
}
}
$('#left_scroll').click(function(){
scrollPos--;
hideOrShow(scrollPos)
});
$('#right_scroll').click(function(){
scrollPos++;
hideOrShow(scrollPos)
});

Related

Div blinking while resize

I am working on a bootstrap based website and I have the following case :
A main container and a floating left navigation menu.
The floating left navigation menu, is set to position fixed, because it is following the user scroll.
What I would like is when the end user resize the window, and when the main content meets the left menu (overlap), the left menu becomes hidden, and when there is enough space the left menu comes back.
Actually, it is not really working, it is blinking. I have written a little bit of jquery binded to the resize function.
Here is the jsfiddle :
https://jsfiddle.net/cuw46rsv/5/
function getDiffLeftMenu(div1, div2) {
var value = ($(div1).offset().left - $(div2).offset().left);
console.log(value - $(div2).width());
if(value - $(div2).width() < 0){
return true;
}
}
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
$('#sectionsMenu').hide();
}
else {
$('#sectionsMenu').show();
}
}).resize();
Is this possible to not have this blinking effet ?
Thanks a lot for any help.
Regards.
Here's the solution with your logic, .hide() method causes it to have offset 0 and that's why it's blinking (it can get stuck as hidden all the time).
https://jsfiddle.net/cuw46rsv/7/
function getDiffLeftMenu(div1, div2) {
var value = ($(div1).offset().left - $(div2).offset().left);
console.log(value - $(div2).width());
if(value - $(div2).width() < 0){
return true;
}
}
By using opacity offset will stay there.
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
$('#sectionsMenu').css('opacity', 0);
}
else {
$('#sectionsMenu').css('opacity', 1);
}
}).resize();
well you are doing it wrong, but you can solve it like this (as a workaround):
$(window).on('resize', function(event) {
var value = ($('.central-content').offset().left - $('#sectionsMenu').offset().left);
if(getDiffLeftMenu('.central-content','#sectionsMenu')){
setTimeout(function(){$('#sectionsMenu').hide();},20);
}
else {
$('#sectionsMenu').show();
}
}).resize();
https://jsfiddle.net/cuw46rsv/6/

Pure js add and remove (toggle) class after scrolling x amount?

I don't want to use jQuery for this.
It's really simple, I just want to add a class after scrolling past a certain amount of pixels (lets say 10px) and remove it if we ever go back to the top 10 pixels.
My best attempt was:
var scrollpos = window.pageYOffset;
var header = document.getElementById("header");
function add_class_on_scroll() {
header.classList.add("fade-in");
}
function remove_class_on_scroll() {
header.classList.remove("fade-in");
}
window.addEventListener('scroll', function(){
if(scrollpos > 10){
add_class_on_scroll();
}
else {
remove_class_on_scroll();
}
console.log(scrollpos);
});
But console shows a number that continues to grow regardless of scrolling up or down. And the class fade-in never gets added, though console shows we past 10.
You forgot to change the offset value in the scroll handler.
//use window.scrollY
var scrollpos = window.scrollY;
var header = document.getElementById("header");
function add_class_on_scroll() {
header.classList.add("fade-in");
}
function remove_class_on_scroll() {
header.classList.remove("fade-in");
}
window.addEventListener('scroll', function(){
//Here you forgot to update the value
scrollpos = window.scrollY;
if(scrollpos > 10){
add_class_on_scroll();
}
else {
remove_class_on_scroll();
}
console.log(scrollpos);
});
Now you code works properly
Explanation
There is no documentation for that, like you asked for. This is just an issue in the logic workflow.
When you say that scrollpos = window.scrollY your page is at an top-offset of 0, so your variable stores that value.
When the page scrolls, your scroll listener will fires. When yout listener checks for the scrollpos value, the value is still 0, of course.
But if, at every scroll handler, you update the scrollpos value, now you can have a dynamic value.
Another option is you to create a getter, like
var scrollpos = function(){return window.scrollY};
This way you can dynamically check what that method will return for you at every offset.
if(scrollpos() > 10)
See? Hope that helped. (:
One simple way to achieve what you want (one line of code inside the scroll event):
window.addEventListener('scroll', function(e) {
document.getElementById('header').classList[e.pageY > 10 ? 'add' : 'remove']('fade-in');
});
#header {
height: 600px;
}
.fade-in {
background-color: orange;
}
<div id='header'></div>
just use the method toggle in classList
header.classList.toggle('fade-in')

Using variable to control an event

I have a footer popup that shows when the page is scrolled a certain amount. I have a little x that the user can click to make the footer go away. I am trying to use a variable to make the footer stay hidden when the x is clicked. I am not able to get it to work like I want and I want to understand why. Here is the code:
jQuery(function($) {
$(document).scroll(function(){
var position = $(this).scrollTop();
var fired = 0;
if(position < 360 && fired === 0){
$('#popup').slideUp();
} else {
$('#popup').slideDown();
}
$('.close').on('click', function(){
$('#popup').slideUp();
fired = 1; // I thought that this was suppose to override the current variable
});
});
});
So, why does this not work?
It doesn't work because you declared var fired = 0; inside the scroll function. So whenever the user scrolls, fired is set to 0. Just declare it above the scroll-function, then it should work.
Fired is a local variable to the scroll callback and as a result is always 0. Place it outside of the callback and it will remain once set.
jQuery(function($) {
var fired = 0;
$(document).scroll(function(){
var position = $(this).scrollTop();
//...

How can I set my browser window's scrollbar or a div scrollbar to scroll in increments using animate and scrollTop?

The general idea to the site i am designing is to scroll through a set of menu items horizontally and incrementally underneath a static div that will magnify(increase dimensions and pt size) the contents of a menu items. I don't really need help with the magnify portion because i think it's as simple as adding a mag class to any of the menuItem divs that go underneath the static div. I have been messing with this for a few weeks and the code I have for incrementally scrolling, so far, is this:
$(document).ready(function () {
currentScrollPos = $('#scrollableDiv').scrollTop(120); //sets default scroll pos
/*The incrementScroll function is passed arguments currentScrollPos and UserScroll which are variables that i have initiated earlier in the program, and then initiates a for loop.
-The first statement sets up the variables: nextScrollPos as equal to the currentScrollPos(which by default is 120px) plus 240px(the distance to next menuItem), prevScrollPos as equal to the currentScrollPos(which by default is 120px) minus 240px(the distance to next menuItem).
-The second Statement checks to see if the user has scrolled using var userScroll
-The third statement sets: var CurrentScroll equal to the new scroll position and var userScroll to false*/
function incrementScroll(currentScrollPos, userScroll) {
for (var nextScrollPos = parseInt(currentScrollPos + 240, 10),
prevScrollPos = parseInt(currentScrollPos - 240, 10); //end first statement
userScroll == 'true'; console.log('dude'), //end second statement and begining of third
currentScrollPos = scrollTop(), userScroll = 'false') {
if (scrollTop() < currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(prevScrollPos, 10))
}, 200);
console.log('scrolln up')
} else if (scrollTop() > currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(nextScrollPos, 10))
}, 200);
console.log('scrolln down')//fire when
}
}
}
$('#scrollableDiv').scroll(function () {
userScroll = 'true';
_.debounce(incrementScroll, 200); //controls the amount of times the incrementScroll function is called
console.log('straight scrolln')
});
});
I have found a variety of solutions that are nigh close: such as a plugin that snaps to the next or previous div horizontally demo, another solution that also snaps and is based on setTimeout demo, but nothing that nails incrementally scrolling through divs. I also found a way to control the rate at which a user may scroll through the menuItems using debounce which is included in the above code.
The console.logs inside the loop do not fire when I demo the code in jsfiddle which leads me to believe the problem lies within the loop. I'm a noob though so it could be in syntax or anywhere else in the code for that matter. Also in the second demo, i have provided the css for the horizontal static div, but the moment I put it in my html it keeps the js from working.
I would like to write the code instead of using a plugin and any help would be appreciated! Also, thank you ahead of time!
Try this fiddle. Menu container height is 960px to show 4 menu items. "Zoom" div is positioned absolutely at top. When you scroll mouse over this div, menu items shifts to top/bottom. I had to add additional div to bottom to be able to scroll to last 3 menu items. JS code:
jQuery(document).ready(function($){
var current = 0;
var menu = $('.menu-container').scrollTop(0);
var items = menu.find('.menu-item');
var zoom = $('.zoom');
function isVerticalScroll(event){
var e = event.originalEvent;
if (e.axis && e.axis === e.HORIZONTAL_AXIS)
return false;
if (e.wheelDeltaX)
return false;
return true;
}
function handleMouseScroll(event){
if(isVerticalScroll(event)){
var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;
current += (delta > 0 ? 1 : -1);
if(current < 0)
current = 0;
if(current >= items.length){
current = items.length - 1;
}
menu.stop().animate({
"scrollTop": current * 240
}, 300);
items.removeClass('current').eq(current).addClass('current');
event && event.preventDefault();
return false;
}
}
zoom.on({
"MozMousePixelScroll": handleMouseScroll,
"mousewheel": handleMouseScroll
});
});
Hope it will help.

Moving a box in JavaScript again -- the program seems to be detecting two key presses even though I'm only pressing one

I'm trying to build on the top answer here by adding "gravity" such that the box always moves down unless a key is pressed.
I've been fiddling for a couple of hours now and I can't figure it out. In the previous code he send two variables to the calculateNewValue function, for top and left of the css position.
I thought I would simply be able to break these two tests for true/false key presses out into four, and then add a +1 for when the up arrow is false, hence the box will always fall down unless you tell it not to.
It almost works, but the box moves down and to the right, instead of just down. And gravity doesn't work like that.
This must have something to do with top and left being used to move the box in two directions. But if the event handler is storing the keycode for only one key, wouldn't all the other tests return false? How can I get it to not move right?
$(function(){
var pane = $('#pane'),
box = $('#box'),
maxValue = pane.width() - box.width(),
keysPressed = {},
distancePerIteration = 3;
function calculateNewValue(oldValue) {
var newValue = parseInt(oldValue, 10)
- (keysPressed[37] ? distancePerIteration : 0)
- (keysPressed[38] ? distancePerIteration : 0)
+ (keysPressed[39] ? distancePerIteration : 0)
+ (keysPressed[40] ? distancePerIteration : 1)
return newValue < 0 ? 0 : newValue > maxValue ? maxValue : newValue;
}
$(window).keydown(function(event) { keysPressed[event.which] = true; });
$(window).keyup(function(event) { keysPressed[event.which] = false; });
setInterval(function() {
box.css({
left: function(index ,oldValue) {
return calculateNewValue(oldValue);
},
top: function(index, oldValue) {
return calculateNewValue(oldValue);
}
});
}, 20);
});
Usually you only use keyup() function. Then the keypress will only fire one event. Only in special cases it is necessary to use keydown().
Your code is flawed. Every 20 milliseconds you modify the the left/top of the box by the same amount every time.
The way you have set up the code, the left and top values always increase by the same amount every time the CSS is updated - so the box will always move either upleft or downright depending on if you press left/up keys.
If you're just trying to move the box up and down then you probably want to change the code not to modify the left attribute - and then change the calculateNewValue to not use the ascii for left/right arrows.

Categories