I am trying to make a custom scrollbar using the following method:
Scrollbar height is inversely proportional to content height.
scrollHeight ∝ 1 / contentHeight.
scrollHeight = k / contentHeight
So if we take constant of k 's value as 10000. (As the height of container of content is 100px and 100 times 100 is 10000). It's still not doing the job.
Can't figure out the problem. If words are confusing check out this JS Fiddle. I know the concept just can't figure out how to set the height of the scroller for dynamic content.
You can try this:
$(document).ready(function(e){
$('#scroll').draggable({
axis: 'y',
containment: 'parent'
});
var contentHeight = $('p').height();
$('.hey').html(contentHeight);
var containerHeight = $('#scroll-cont').height();
var k = 10000;
var scrollerHeight = $('#scroll').height((k / contentHeight) / 2);
$('.hey').append('<br>' + $('#scroll').height());
$(document).mousemove(function(e){
var offsetS = $('#scroll').offset().top * 2;
$('#scroll-cont').scrollTop(offsetS);
});
});
scrollbarHeight / scrolltrackHeight = visibleHeight / contentHeight
scrollbarHeight = scrolltrackHeight * visibleHeight / contentHeight
For example, you content's height 1000px, and visible height is 250px. If your scrolltrack height is 240px (all visible space - 5px padding from top/bottom), then your scrollbar should be 240 * 250 / 1000 = 60
Related
I found the following code used to track the scroll percentage as you scroll down the page.
document.addEventListener('scroll', function(){
var h = document.documentElement,
b = document.body,
st = 'scrollTop',
sh = 'scrollHeight';
var percent = (h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight) * 100;
document.getElementById('scroll').textContent = 'scrolled: ' + percent + '%';
});
That shows the percentage of the whole page. If I only want the scroll percentage of a specific div like this example https://www.thefarmersdog.com/ how the dog bowl scrolls over when you move down the page.
You need to use getBoundingClientRect()
const coordinates = document.getElementById('your-id').getBoundingClientRect();
console.log(coordinates.top); // This is the distance to the top of the screen
Here is a detailed article that you can read if you need more info.
Divide number of pixels that an element's content has been scrolled vertically by the height of an element's content minus an element's offset height and multiply by 100 to get percentage value from 0 to 100. Optionally, round it to get an integer value.
scrollPercent = scrollTop / (scrollHeight - offsetHeight)
const scrollLabelElement = document.getElementById('scroll');
element.addEventListener('scroll', (_event) =>
const percentScrolled = Math.round(element.scrollTop / (element.scrollHeight - element.offsetHeight));
scrollLabelElement.textContent = `Scrolled: ${percentScrolled}%`;
});
I'm trying to detect what % of the element can be seen on the current window.
For example, if the user can only see half the element, return 50. If the user can see the whole element, return 100.
Here's my code so far:
function getPercentOnScreen() {
var $window = $(window),
viewport_top = $window.scrollTop(),
viewport_height = $window.height(),
viewport_bottom = viewport_top + viewport_height,
$elem = $(this),
top = $elem.offset().top,
height = $elem.height(),
bottom = top + height;
return (bottom - viewport_top) / height * 100;
}
But it doesn't seem to be working. Can anyone help me out in achieveing this I seem to be spinning gears.
What you want to get is the amount of pixels that the element extends past the top and bottom of the viewport. Then you can just subtract it from the total height and divide by that height to get the percentage onscreen.
var px_below = Math.max(bottom - viewport_bottom, 0);
var px_above = Math.max(viewport_top - top, 0);
var percent = (height - px_below - px_above) / height;
return percent;
One thing to note is that jQuery's height method won't include padding. You probably want to use .outerHeight for that.
Your $elem = $(this)assignment seems wrong, here function scoping means this refers to the function you're in (ala ~ the function getPercentOnScreen), try referencing by $elem = $('#yourElementId')instead.
if you only want to calculate percent of element then just do this
function getPercentOnScreen(elem) {
$docHeight = $(document).height();
$elemHeight = $(elem).height();
return ($elemHeight/$docHeight)* 100;
}
I am calculating scrolling progress (% of document hidden from view after scrolling down) on a page with the following line:
window.pageYOffset / document.body.scrollHeight
This works well for most sites. But some sites tweak the scrolling or the overflow property and in effect break the above calculation.
For example, on this page the above line will always return 0.
Is there a better way to calculate scrolling progress that would work in situations like these?
Here's my approach :
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
let limit = Math.max( document.body.scrollHeight, document.body.offsetHeight,
document.documentElement.clientHeight, document.documentElement.scrollHeight,
document.documentElement.offsetHeight );
let footerHeight = document.querySelector('footer').offsetHeight;
let max = limit - window.innerHeight - footerHeight;
let height = window.pageYOffset / max * 100;
height = Math.min(100, Math.max(0, height));
const loader = document.getElementById("loader-scroll");
loader.style.width = 0 + height + "%";
}
It works fine across most browsers
I currently have a page where I have fixed-size divs that load pages as a user scrolls down (similar to Infinite Scroll) and am currently working on functionality to have the loaded images and containers dynamically resize along with the browser window. My current issue is that I'm currently using $(window).width and $(window).height, which naturally causes the images to resize to the window width.
I was wondering what I can set maxWidth and maxHeight to so that the images don't get resized any greater than their original size? I've been using $(window) just to test the function, but I basically don't want the images to become any larger than their original size. I've tried $(this), but it causes the ratio to be equal to 1, resulting in no resize.
$(window).resize(function () {
imageResize();
});
function imageResize() {
$(".added").each(function () {
var maxWidth = $(window).width();
var maxHeight = $(window).height();
var ratio = 0;
var width = $(this).width();
var height = $(this).height();
if (width > maxWidth) {
ratio = (maxWidth / width);
$(this).width(maxWidth);
$(this).height(height * ratio);
$(this).parent().height(height * ratio);
$(this).parent().width(maxWidth);
} else {
ratio = (maxWidth / width);
$(this).width(maxWidth);
$(this).height(height * ratio);
$(this).parent().height(height * ratio);
$(this).parent().width(maxWidth);
}
});
}
You want to set the max-height and max-width properties to the values you said, this will not force the image to grow further than their original height or width and will minimize it if it is larger.
Use:
$("#imageId").attr("max-width",maxWidth);
$("#imageId").attr("max-height",maxHeight);
I would change the style so:
($this).style.maxWidth = maxWidth;
I have written the following script to display a hidden element, then fix it's position to the center of the page.
function popUp(id,type) {
var popUpBox = document.getElementById(id);
popUpBox.style.position = "fixed";
popUpBox.style.display = "block";
popUpBox.style.zIndex = "6";
popUpBox.style.top = "50%";
popUpBox.style.left = "50%";
var height = popUpBox.offsetHeight;
var width = popUpBox.offsetWidth;
var marginTop = (height / 2) * -1;
var marginLeft = (width / 2) * -1;
popUpBox.style.marginTop = marginTop + "px";
popUpBox.style.marginLeft = marginLeft + "px";
}
When this function is called by an onclick event, the offsetHeight and offsetWidth are calculated incorrectly, thus not centering the element correctly. If I click the onclick element a second time, the offsetHeight and offsetWidth calculate correctly.
I have tried changing the order in every way I can imagine, and this is driving me crazy! Any help is very much appreciated!
I am guessing your height and width are not defined on the parent. See this fiddle where it works fine. Boy I'm smart. http://jsfiddle.net/mrtsherman/SdTEf/1/
Old Answer
I think this can be done a lot more simply. You are setting the top and left properties to 50%. This will place the fixed element slight off from the center. I think you are then trying to pull it back into the correct position using negative margins. Instead - just calculate the correct top/left values from the start and don't worry about margin. Here is a jQuery solution, but it can be easily adapted to plain js. I also think your current code won't work if the window has been scrolled at all.
//this code will center the following element on the screen
$('#elementid').click(function() {
$(this).css('position','fixed');
$(this).css('top', (($(window).height() - $(this).outerHeight()) / 2) + $(window).scrollTop() + 'px');
$(this).css('left', (($(window).width() - $(this).outerWidth()) / 2) + $(window).scrollLeft() + 'px');
});