Scroll eventListener stops working - javascript

The problem is when I enable the eventListener width the scroll eventListener stops working.
var header = document.getElementById("header");
var nav = document.getElemantById("ulArea");
var HaLogo = document.getElementById("logo");
var yPosition = window.scrollTop();
window.addEventListener("scroll" , yScroll);
function yScroll () {
if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
header.style.height = "90px";
logo.style.float = "left";
logo.style.height = "90px";
logo.style.width = "90px";
logo.style.margin = "0px 0px 10px 30px";
ulArea.style.margin = "0px 0px 0px auto";
ulArea.style.float = "none";
} else {
header.style.height = "220px";
logo.style.background = "transparent";
logo.style.float = "none";
logo.style.height = "150px";
logo.style.width = "150px";
logo.style.margin = "0 auto";
ulArea.style.margin = "0 auto";
ulArea.style.float = "none";
}
}
window.addEventListener("width" , headerHeight)
function headerHeight() {
if (document.getElementById("header").width < 990px) {
header.style.height = "100px";
} else {
header.style.height = "220px";
}
}

There are a few problems with your code:
You need to use the resize event (there is no width event).
I think the logo variable isn;t defined, do you mean HaLogo?
ulArea isn't defined.
You need to use the .style.width property of the element (.width doesn't exist).
You need to parse the element's width into an integer with parseInt. If you don't parse it you'll be comparing a string like '50px' to an int 990.
Change < 990px to < 990 (remove the px).
You should end up with if (parseInt(document.getElementById("header").style.width) < 990) { for your if statement and window.addEventListener("resize", headerHeight); for your second event listener.

I think what you are actually looking for is the resize event instead of width:
window.addEventListener('resize', function(event){
// do stuff here
});

Related

Three cases on scroll - function inside an if

I need to set three different background on a navbar:
1. No background if the page is less than 400 px of scrolling
2. Two different colors if the scroll of the page is more than 400 px:
a) blue when I scroll down
b) green when I scroll up.
I've tried to use the following code, but it seems like after I enter in the first IF, the function continue to work even if the page is less than 400px.
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 400 || document.documentElement.scrollTop > 400) {
var prevScrollpos = window.pageYOffset;
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById("nav1").style.background = "rgba(0, 41, 51,1)";
} else {
lastScroll = currentScroll;
document.getElementById("nav1").style.background = "rgba(68,78,36,1)";
}
prevScrollpos = currentScrollPos;
} else {
document.getElementById("nav1").style.background = "rgba(0,0,0,0)";
}
}
Thanks!
Do not attempt to assign two functions to window.onscroll, which is a property and can hold only one function.
Here is what is going on with your current code:
An annonymous function is declared (it calls scrollFunction) and assigned to window.onscroll
At the very first scroll, scrollFunction is called. If the page has not scrolled yet beyond 400px, the if block is not executed.
As soon as the page goes beyond 400px, prevScrollpos is declared... Then the function previously assigned to window.onscroll is overwriten with a new one.
That is why the comparison for 400px isn't done after that. It is out of that second function. The first one got lost in the nothingness.
Here is what you want to achieve:
// This variable needs to be global
let prevScrollpos = 0;
// This getElement can also be global
let nav1 = document.getElementById("nav1")
function scrollFunction() {
// This varable needs to be local
let currentScrollPos = window.pageYOffset;
if (document.body.scrollTop > 400 || document.documentElement.scrollTop > 400) {
// Determine scroll direction
if (prevScrollpos > currentScrollPos) {
nav1.style.background = "rgba(0, 41, 51,1)";
} else {
nav1.style.background = "rgba(68,78,36,1)";
}
}
// If below 400px
else {
nav1.style.background = "rgba(0,0,0,0)";
}
// Update this variable for the next iteration
prevScrollpos = currentScrollPos;
// For this demo only
console.clear()
console.log(currentScrollPos)
}
// Assign the scrollFunction reference to the window property
window.onscroll = scrollFunction;
body {
height: 1000px;
}
#nav1{
position: sticky;
top: 4px;
height: 100px;
border: 1px solid black;
}
<div id="nav1"></div>
You can use this script:
<script>
window.onscroll = function () { myFunction() };
function myFunction() {
if (document.body.scrollTop > 400 || document.documentElement.scrollTop > 400) {
var lastScrollTop = 0;
window.addEventListener("scroll", function () {
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st > lastScrollTop) {
document.getElementById("nav").style.background = "rgba(0, 41, 51,1)";
} else {
document.getElementById("nav").style.background = "rgba(68,78,36,1)";
}
lastScrollTop = st <= 0 ? 0 : st;
}, false);
} else {
document.getElementById("nav").style.background = "rgba(0,0,0,0)";
}
}
</script>

Resize function to replace divs disables onclick function

I know the title is shit, but I don't know what will be better.
The case is, I create few spans with divs inside on absolute coordinate, according to $(window).width(). When I resize it, I want to rearrange them, so on $(window).resize() I call function to delete the spans, $("span").empty(); and do exactly the same thing, as when I created then. Further more there is a click function, that works fine with the first created spans, and then when I clear then and create exactly the same thing after resize, it doens't work.
Please look at the simplified jsfiddle to understand. First try to click object. Then resize the window and try to click on it.
http://jsfiddle.net/4159v04o/1/
Any ideas why that occurs? Thank you in advance!
It's due to divs being created/erased dynamically. What you need is event delegation.
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
Replace:
$('div').on({click: function() {
With:
$(document).on("click", "div", function() {
Updated fiddle
I have debug the code link and changed the code. there were some code related to name.*. but in name there is only string and you are using style method which is not supporting.
So I removed all the name.* line now it is working fine
var secondstack = [];
var positionTop = 20;
var positionLeft = 20;
document.body.style.background = '#00CCFF';
document.body.style.backgroundSize = "cover";
for(var i = 0; i < 25; i++){
var span = document.createElement("span");
span.style.position = "absolute";
span.style.left = positionLeft + "px";
span.style.top = positionTop + "px";
var div = document.createElement("div");
div.style.width = '105px';
div.style.height = '100px';
div.id = i;
div.style.background = '#00FFCC';
$(div).css({backgroundSize: "cover"});
if((positionLeft + 250) < $(window).width()) positionLeft += 120;
else {
old_Width = positionLeft;
var positionTop = 160 + positionTop;
var positionLeft = 20;
}
span.appendChild(div);
document.body.appendChild(span);
}
DivClick();
var resizeTimer;
$(window).resize(function () {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(doSomething, 100);
DivClick()
});
function rearrange(){
$("div").empty();
$("span").empty();
secondstack = [];
var positionTop = 20;
var positionLeft = 20;
for(var i = 0; i < 25; i++){
var span = document.createElement("span");
span.style.position = "absolute";
span.style.left = positionLeft + "px";
span.style.top = positionTop + "px";
var div = document.createElement("div");
div.style.width = '105px';
div.style.height = '100px';
div.id = i;
div.style.background = '#00FFCC';
$(div).css({backgroundSize: "cover"});
if((positionLeft + 250) < $(window).width()) positionLeft += 120;
else {
var positionTop = 160 + positionTop;
var positionLeft = 20;
}
span.appendChild(div);
document.body.appendChild(span);
}
}
function DivClick()
{
$('div').on({click: function(){
var el = document.getElementById(this.id);
el.style.border = "3px solid white";
if(!(secondstack.indexOf(this.id) > -1)) secondstack.push(this.id);
else {
var index = secondstack.indexOf(this.id);
el.style.border = "3px solid black";
secondstack.splice(index, 1);
}
}});
}
Just paste and run on same Jsfiddel Example

Why isn't Chrome running this Javascript?

The script works perfect in FF and IE, but not in Chrome. Could someone help med to locate the problem?
The if statmenst seems not to be runned when they are supposed to, they do nothing when the should.
var top = 285;
var bottom = 650;
var pageheight, maxscroll;
window.onload = function(){
pageheight = document.body.offsetHeight;
maxscroll = pageheight - (bottom+40);
}
window.onscroll = function(){
var element = document.getElementById("guide-menu");
if(window.pageYOffset < top){
element.style.position = "absolute";
element.style.top = "300px";
}
if(window.pageYOffset > top){
element.style.top = "10px";
element.style.position = "fixed";
element.style.marginTop = "0px";
}
if(window.pageYOffset > maxscroll){
element.style.position = "absolute";
element.style.marginTop = (pageheight - bottom - 40) + "px";
}
}
"top" has different meaning in chrome. Just try to rename top variable.
The "top" variable returns the topmost browser window. Chrome is the only major browser not supporting overriding this variable.
Renaming your variable to something like "myTop" works perfectly.
This code works well.
var myTop = 285;
var bottom = 650;
var pageheight, maxscroll;
window.onload = function(){
pageheight = document.body.offsetHeight;
maxscroll = pageheight - (bottom+40);
window.onscroll = function()
{
var element = document.getElementById("guide-menu");
if(window.pageYOffset < myTop)
{
element.style.position = "absolute";
element.style.top = "300px";
}
if(window.pageYOffset > myTop)
{
element.style.top = "10px";
element.style.position = "fixed";
element.style.marginTop = "0px";
}
if(window.pageYOffset > maxscroll)
{
element.style.position = "absolute";
element.style.marginTop = (pageheight - bottom - 40) + "px";
}
}
}
By the way, check that you are puting the right conditions for the IF statements. If you want a menu which scrolls with the webpage, then you have to exchange the two first if conditions.

Detect vertical scroll and scrollbar width and apply width change to body

In my page, I wish to detect whether the page has vertical scrollbars, and if so, need to detect the width of the scrollbar, so I can reduce my body by the width and thus prevent my sidebar from changing location from viewing a non-scrolling page to a scrolling page.
I have the following jQuery/Javascript code:
$(document).ready(function () {
var parent, child, width;
if (width === undefined) {
parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');
child = parent.children();
width = child.innerWidth() - child.height(99).innerWidth();
parent.remove();
}
if ($("body").height() > $(window).height()) {
//change width of body here
}
});
Unfortunately, this code doesn't work for me. Can someone please let me know where I'm going wrong?
(function($) {
$.fn.ScrollBarWidth = function() {
if (this.get(0).scrollHeight > this.height()) { //check if element has scrollbar
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild(inner);
document.body.appendChild(outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild(outer);
return (w1 - w2);
}
}
})(jQuery);
Runs like so :
var scrollbarWidth = $('body').ScrollBarWidth();
console.log(scrollbarWidth);​ //prints the scrollbar width to the console
FIDDLE
You shouldn't need to change the width of the body. By default, it's 100% of the window's width and will adjust when scrollbars appear.
However, if you can't for some reason set the width to 100%, first see if disabling the horizontal scrollbar helps you:
overflow-x: hidden;
If that doesn't cut it, use the function from here to get the scrollbar's width. Then, listen to the window resize event:
var $window = $(window),
$body = $('body');
function resize() {
if ($body.height() > $window.height()) {
$body.width($body.width() - getScrollBarWidth());
}
}
$(window).resize(resize);​

javascript toggle animation issue

I am doing a small javascript animation. this is my code :
window.onload = function () {
var heading = document.getElementsByTagName('h1')[0];
heading.onclick = function () {
var divHeight = 250;
var speed = 10;
var myInterval = 0;
alert(divHeight);
slide();
function slide() {
if (divHeight == 250) {
myInterval = setInterval(slideUp, 30);
} else {
myInterval = setInterval(slideDwn, 30);
alert('i am called as slide down')
}
}
function slideUp() {
var anima = document.getElementById('anima');
if (divHeight <= 0) {
divHeight = 0;
anima.style.height = '0px';
clearInterval(myInterval);
} else {
divHeight -= speed;
if (divHeight < 0) divHeight = 0;
anima.style.height = divHeight + 'px';
}
}
function slideDwn() {
var anima = document.getElementById('anima');
if (divHeight >= 250) {
divHeight = 250;
clearInterval(myInterval);
} else {
divHeight += speed;
anima.style.height = divHeight + 'px';
}
}
}
}
i am using above code for simple animation. i need to get the result 250 on the first click, as well second click i has to get 0 value. but it showing the 250 with unchanged. but i am assigning the value to set '0', once the div height reached to '0'.
what is the issue with my code? any one help me?
Everytime you click on the div the divHeight variable is reset to 250, thus your code never calls slideDwn. Moving the divHeight declaration outside the event handler should do the trick.
Also, your div wont have the correct size when any of the 2 animations end. You're setting the divHeight variable to 250 or 0 correctly, but never actually setting anima.style.height after that.
I've rewritten your code into something simpler and lighter. The main difference here is that we're using a single slide() function here, and that the height of the div in question is stored in a variable beforehand to ensure that the element slides into the correct position.
Note that this is a very simplistic implementation and assumes that the div carries no padding. (The code uses ele.clientHeight and ele.style.height interchangeably, which admittedly, is a pretty bad choice, but is done here to keep the code simple)
var heading = document.getElementsByTagName('h1')[0],
anima = document.getElementById('anima'),
divHeight = anima.clientHeight,
speed = 10,
myInterval = 0,
animating = false;
function slide(speed, goal) {
if(Math.abs(anima.clientHeight - goal) <= speed){
anima.style.height = goal + 'px';
animating = false;
clearInterval(myInterval);
} else if(anima.clientHeight - goal > 0){
anima.style.height = (anima.clientHeight - speed) + 'px';
} else {
anima.style.height = (anima.clientHeight + speed) + 'px';
}
}
heading.onclick = function() {
if(!animating) {
animating = true;
var goal = (anima.clientHeight >= divHeight) ? 0 : divHeight;
myInterval = setInterval(slide, 13, speed, goal);
}
}
See http://www.jsfiddle.net/yijiang/dWJgG/2/ for a simple demo.
I've corrected your code a bit (See working demo)
window.onload = function () {
var heading = document.getElementsByTagName('h1')[0];
var anima = document.getElementById('anima');
var divHeight = 250;
heading.onclick = function () {
var speed = 10;
var myInterval = 0;
function slideUp() {
divHeight -= speed;
if (divHeight <= 0) {
divHeight = 0;
clearInterval(myInterval);
}
anima.style.height = divHeight + 'px';
}
function slideDwn() {
divHeight += speed;
if (divHeight >= 250) {
divHeight = 250;
clearInterval(myInterval);
}
anima.style.height = divHeight + 'px';
}
function slide() {
console.log(divHeight )
if (divHeight == 250) {
myInterval = setInterval(slideUp, 30);
} else {
myInterval = setInterval(slideDwn, 30);
}
}
slide();
}
}​

Categories