Updating global variable on scroll event attached to a DOM element - javascript

I've got a situation where I want a variable to be updated when scrolling inside a <div>. There is a series of other things which will happen depending on this variable updating, so I don't want to wrap it inside the scroll event. Is there a way to avoid that?
Here is my JS:
var scrollEl = document.getElementById("scrollEl");
var scrollElWidth = scrollEl.offsetWidth;
var scrolled = 0;
var updater = function(updated) {
scrolled = Math.round(updated);
return scrolled;
}
scrollEl.addEventListener("scroll", function() {
var percentage = 100 * scrollEl.scrollLeft / (scrollEl.scrollWidth - scrollElWidth);
//This works
console.log(updater(percentage));
});
//This doesn't
console.log('Updated scroll variable: ', scrolled);
Here is a fiddle: https://jsfiddle.net/0u4fp0yv/

Related

Javascript code not getting executed on initial page load

I have written a Javascript function for resizing the Carousel according to the screen width. It's doing the job properly but the only issue is that it doesn't get initialized on the initial page load. The Carousel is only present on the homepage and when I visit it for the first time, the code doesn't get executed. However, if I reload the page it does get executed. It even gets executed when I resize my browser window. But I would like it to initialize on the first first load as well. Here's the code:
let carousel = document.querySelector('#carousel');
if (carousel) {
const size = 0.8;
window.addEventListener('resize', () => {
let width = carousel.clientWidth || carousel.offsetWidth;
let carouselHeight = (width * size) + 'px';
carousel.querySelector(".slide").style.height = carouselHeight;
}, false);
}
You're adding a listener, but the callback won't get called unless it is triggered.
You can instead declare the callback as a function, add the listener with the function as callback, and then call the function directly for the initial load.
function resizeCarousel(size) {
let width = carousel.clientWidth || carousel.offsetWidth;
let carouselHeight = (width * size) + 'px';
carousel.querySelector(".slide").style.height = carouselHeight;
}
let carousel = document.querySelector('#carousel');
if (carousel) {
const size = 0.8;
window.addEventListener('resize', () => resizeCarousel(size), false);
resizeCarousel(size);
}
You’re adding an event listener on the page resize. First of all, this should all be wrapped in an on load event listener so you can be sure that the element #carousel is even available. Then, I would execute the resize function manually by maybe defining the function in the on load event function. Then set it for resizing events. I’m on my phone so it’s hard to type an example, for for example:
document.addEventListener("DOMContentLoaded", function(event) {
function resize() { /* Resize Function. */ }
var carousel = document.querySelector('#carousel');
window.addEventListener(“resize”, resize);
resize(); // Call it now as well as onresize.
});

Reset the initial state of an element after some DOM manimulations (native js)

I want to save the initial state of my Element (with all childs) and after that do some actions ( initialize scrollbar plugin ) and after the window resize event I want to clear these changed values to the saved "pure" element and after that re-initialize the scrollbar plugin (I just want to do a scrollbar element responsive with the different views).
I tried to use .cloneNode(true), jquery.clone(true) and jquery.replaceWith() but it doesn't work for me becase these methods somehow keep all chages that was done before. So I can't get the saved initial HTML.
Should I user outerHTML maybe? Thanks for any help.
var GLOBAL_rawScrollBarNode;
var GLOBAL_scrollBarParent;
$(document).ready(function($){
GLOBAL_rawScrollBarNode = $('#scrollbar3').clone();
GLOBAL_scrollBarParent = $('.portfolio-scroll-box')[0];
portfolioScrollbarOfDeviceWidth();
$(window).resize(function(){
portfolioScrollbarOfDeviceWidth();
});
function portfolioScrollbarOfDeviceWidth() {
var documentWidth = document.documentElement.clientWidth;
//GLOBAL_scrollBarParent.removeChild(document.getElementById('scrollbar3'));
//GLOBAL_scrollBarParent.appendChild(GLOBAL_rawScrollBarNode);
GLOBAL_scrollBarParent.replaceWith(GLOBAL_rawScrollBarNode[0])
var $scrollBarEl = $('#scrollbar3');
setTimeout(() => {
if (documentWidth < 942) {
console.log("XXX")
var bar = $scrollBarEl.tinyscrollbar({ axis: 'x',sizethumb: 135 });
console.log(bar);
} else {
console.log("YYY")
var bar = $scrollBarEl.tinyscrollbar({ axis: 'y',sizethumb: 135 });
console.log(bar);
}
}, 2000)
}
P.S. in case of the outerHTML of the saved ELEMENT and after that assign it like innerHTML to it's parent - it works fine. But I want to know how this issue can be resolved in other more elegant way :)

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();
//...

jQuery infinite scrolling scrolling in fixed div

Background
I am trying to create an infinite scrolling table inside a fixed position div. The problem is that all the solutions I come across use the window height and document scrollTop to calculate if the user has scrolled to the bottom of the screen.
Problem
I have tried to create a jQuery plugin that can calculate if a user has scrolled to the bottom of a fixed div with overflow: scroll; set.
My approach has been to create a wrapper div (the div with a fixed position and overflow: scroll) that wraps the table, I also place another div at the bottom of the table. I then try calculate if the wrapper.scrollTop() is greater than the bottom div position.top every time the wrapper is scrolled. I then load the new records and append them to the table body.
$.fn.isScrolledTo = function () {
var element = $(this);
var bottom = element.find('.bottom');
$(element).scroll(function () {
if (element.scrollTop() >= bottom.position().top) {
var tableBody = element.find("tbody");
tableBody.append(tableBody.html());
}
});
};
$('.fixed').isScrolledTo();
See Example http://jsfiddle.net/leviputna/v4q3a/
Question
Clearly my current example is not correct. My question is how to I detect when a user has scrolled to the bottom of a fixed div with overflow:scroll set?
Using the bottom element is a bit clunky, I think. Instead, why not use the scrollHeight and height to test once the scrollable area has run out.
$.fn.isScrolledTo = function () {
var element = this,
tableBody = this.find("tbody");
element.scroll(function(){
if( element.scrollTop() >= element[0].scrollHeight-element.height()){
tableBody.append(tableBody.html());
}
});
};
$('.fixed').isScrolledTo();
EDIT (12/30/14):
A DRYer version of the plugin might be much more re-usable:
$.fn.whenScrolledToBottom = function (cback_fxn) {
this.on('scroll',this,function(){
if( ev.data.scrollTop() >= ev.data[0].scrollHeight - ev.data.height()){
return cback_fxn.apply(ev.data, arguments)
}
});
};
Plugin Usage:
var $fixed = $('.fixed'),
$tableBody = $fixed.find("tbody");
$fixed.whenScrolledToBottom(function(){
// Load more data..
$tableBody.append($tableBody.html());
});
I have modified your code to handle the scroll event with a timer threshold:
$.fn.isScrolledTo = function () {
var element = $(this);
var bottom = element.find('.bottom');
$(element).scroll(function(){
if (this.timer) clearTimeout(this.timer);
this.timer=setTimeout(function(){
if( element.scrollTop() >= bottom.position().top){
var tableBody = element.find("tbody");
tableBody.append(tableBody.html());
}
},300);
});
};
$('.fixed').isScrolledTo();
The issue you are having is that as you scroll, new scroll event is being generated. Your code might have other issues, but this is a start.

Two JQuery functions for auto height on the same website

I have a question regarding using a function multiple times on the page I am trying to set a block auto height in dependence of screen resolution but I have 2 divs on different pages that need to be applied this function, it get applied only for one div for ex:
first tie I apply it to following selectors
<script>
$(function () {
resize_main_pane();
$(window).resize(resize_main_pane);
});
function resize_main_pane() {
var offset = $('.pagina-servicii').offset(),
remaining_height = parseInt($(window).height() - offset.top - 105);
$('.pagina-servicii').height(remaining_height);
}
</script>
second time to the following:
<script>
$(function () {
resize_main_pane();
$(window).resize(resize_main_pane);
});
function resize_main_pane() {
var offset = $('.another-selector').offset(),
remaining_height = parseInt($(window).height() - offset.top - 283);
$('.another-selector').height(remaining_height);
}
</script>
How can I combine them or use separately? I wonder if I need to use some no conflict setting?
Loop all selected divs and apply height to them:
function resize_main_pane() {
$.each($('#selector1, #selector2', function(){
var offsetMinus = $(this).hasClass('bigOffset') ? 283 : 105;
var offset = $(this).offset(),
remaining_height = parseInt($(window).height() - offset.top - offsetMinus);
$(this).height(remaining_height);
});
}
Put your selectors in an array and loop trough them with each.
The $(this) will be either of your class selectors and calculates the offset and height independently.
$(function () {
resize_main_pane();
$(window).resize(resize_main_pane);
// If you want to trigger this function on document load you could replace the above line with:
$(window).resize(resize_main_pane).trigger('resize');
});
function resize_main_pane() {
$('.pagina-servicii, .another-selector').each(function(index) {
var offset = $(this).offset(),
remaining_height = parseInt($(window).height() - offset.top - [105,283][index]);
$(this).height(remaining_height);
});
}

Categories