I want to rewrite the following code so that it doesn't get the height of the <body>, but rather the height of the element I put the object in to carry out the function:
var img = document.getElementById("logo");
window.onscroll = function() {
var bodyHeight = parseInt(getComputedStyle(document.body).height, 10);
var scrollLimit = bodyHeight - window.innerHeight;
var scrollTop = document.body.scrollTop;
var scrollPCT = (scrollTop / (scrollLimit / 100)) / 100;
logo.style.top = bodyHeight * scrollPCT - logo.offsetHeight + "px";
};
How can I target, say an ID, instead of document.body? I tried the following but it didn't work at all:
var img = document.getElementById("logo");
window.onscroll = function() {
var body = document.getElementById("container");
var bodyHeight = parseInt(getComputedStyle(document.getElementById("container")).height, 10);
var scrollLimit = bodyHeight - window.innerHeight;
var scrollTop = document.getElementById("container").scrollTop;
var scrollPCT = (scrollTop / (scrollLimit / 100)) / 100;
logo.style.top = bodyHeight * scrollPCT - logo.offsetHeight + "px";
};
The desired effect involves a reverse scroll in which an image will move down as the user scrolls down, instead of up, like it normally does.
I guess the computed height does not work? Use the clientHeight property:
var bodyHeight = document.getElementById("container").clientHeight;
(or one of the other height properties)
Related
var totalHeight = 0;
$(".scroll-section").each(function(){
totalHeight += $(this).height();
});
$(".site-content").scroll(function() {
var scrollTop = $(".site-content").scrollTop();
var movePos = (scrollTop / totalHeight) * 100;
movePos = movePos + 100;
console.log(movePos);
$(".page-fixed").css("background-size", `${movePos}% 100%`)
});
I tried margin, does not work
Doing this for webflow so yeah... Would need to get it webflow compatible as well
I have a text in a single line (white-space: nowrap).
I want to reduce the font size of this text if the width of it greater than the width of the parent-block.
I use while loop. Why it doesn't work? Width of "elemWidth" is not updated and loop and the cycle freeze?
$('.slider__title-wrap').each(function(){
var width = $(this).width();
var fontSize = 50;
var elem = $(this).find('.slider__title');
var elemWidth = elem.width();
while(elemWidth >= width) {
fontSize = Math.floor(fontSize * 0.96);
elem.css({fontSize: fontSize+'px'});
};
})
var elemWidth = elem.width();
makes a copy of elem.width();
You need to reevaluate elemWidth into your loop :
$('.slider__title-wrap').each(function(){
var width = $(this).width();
var fontSize = 50;
var elem = $(this).find('.slider__title');
var elemWidth = elem.width();
while(elemWidth >= width) {
fontSize = Math.floor(fontSize * 0.96);
elem.css({fontSize: fontSize+'px'});
elemWidth = elem.width();
};
})
You don't seem to be changing either elemWidth or width inside the while loop. So it will either never start, or never end. You need to update the values you're comparing before the loop ends:
$('.slider__title-wrap').each(function(){
var width = $(this).width();
var fontSize = 50;
var elem = $(this).find('.slider__title');
var elemWidth = elem.width();
while(elemWidth >= width) {
fontSize = Math.floor(fontSize * 0.96);
elem.css({fontSize: fontSize+'px'});
width = $(this).width();
elemWidth = $(this).find('.slider__title').width();
};
});
Alternatively, eliminate the variables so you don't have to update anything:
$('.slider__title-wrap').each(function(){
var fontSize = 50;
while($(this).width() >= $(this).find('.slider__title').width()) {
fontSize = Math.floor(fontSize * 0.96);
elem.css({fontSize: fontSize+'px'});
};
});
Incidentally, I'd use fontSize = fontSize-1; instead of multiplying by 0.96, but it's probably a micro-optimization.
I have a container with n number of div inside it. I need the container to resize according to it children. I know this can be done using jquery library as follows.
JQuery
$(document).ready(function(){
setContainerWidth();
});
$(window).resize(function(){
setContainerWidth();
});
function setContainerWidth()
{
$('.container').css('width', 'auto'); //reset
var windowWidth = $(document).width();
var blockWidth = $('.block').outerWidth(true);
var maxBoxPerRow = Math.floor(windowWidth / blockWidth);
$('.container').width(maxBoxPerRow * blockWidth);
}
This time I need to do this with the pure javascript for some plugin issue. I broke down the code till as follows and stuck in the middle any help would be appreciated.
Javascript
function setContainerWidth(){
var container_width = document.getElementById('container').offsetWidth;
var width = document.body.clientWidth
var block_width = document.getElementsByClassName("block").offsetWidth;
container.style.width = "auto"
var maxBoxPerRow = Math.floor(width / block_width)
container.offsetWidth(maxBoxPerRow * block_width)
}
Example one using jquery
Example two using javascript
You are missing a few things from your pure javascript translation:
function setContainerWidth()
{
var container = document.getElementById('container');
container.style.width = "auto";
var window_width = window.innerWidth;
var block_width = document.getElementsByClassName("block")[0].offsetWidth;
var maxBoxPerRow = Math.floor(window_width / block_width);
container.style.width = (maxBoxPerRow * block_width) + 'px';
}
I am a little confused on how to keep some variables Ive created uptodate when the window is resized so my scroll function carries on getting the correct values. Basically I have multiple elements that contain a message that gets displayed when the user scrolls the element into 50% height of the viewport height. This works fine but my issue is when I resize I'm not sure how to update my variables boxHeight, elementOffset, verticalMatch which keep control of the values I need to use in my scroll event. I was wondering can someone help explain how I can resolve this?
My code looks like this
var windowHeight = $(window).height(),
headerHeight = $('.header').height();
$('.box').each(function (i,e) {
var el = $(e);
var boxHeight = el.height(),
elementOffset = el.offset().top,
verticalMatch = (windowHeight / 2) + (headerHeight / 2) - (boxHeight / 2);
$(window).on('scroll', function () {
var scrollTop = $(window).scrollTop(),
distance = elementOffset - scrollTop;
if( distance <= verticalMatch ) {
el.addClass('is-active');
}
});
});
$(window).on('resize', function() {
windowHeight = $(window).height()
elementOffset = $('.box').offset().top;
$('.box').each(function (i,e) {
var el = $(e);
//update boxHeight, elementOffset, verticalMatch
verticalMatch = (windowHeight / 2) + (headerHeight / 2) - (boxHeight / 2);
});
});
And heres the JS Fiddle: http://jsfiddle.net/fm4z7/2/
If someone could explain how I do this it would be great!
If all you want to do is update your sizing variables during a resize event, then do just that:
$(window).on('resize', function() {
windowHeight = $(window).height();
elementOffset = $('.box').offset().top;
});
Your variables are global so they can be accessed anywhere.
I'm trying to get an image that is around 1920x1200px to pan around on a 800x600px browser window.
So if my mouse is on the top-left of the browser window the image is alined so it's top-left margins are on the top-left of the browser window. The same goes for the bottum-right.
So if the mouse is in the centre of the screen the image should be centered too.
Im not sure what calculations are needed as my math is a bit rusty.
Currently I'm using a bit of javascript that just moves the image using CSS's top/left properties but without much success as it's just moving the picture around from it's top/left corner.
I'v also set the image's position to absolute in css.
function updateImgPosition( e )
{
var avatar = document.getElementById("avatar");
// Width
var windowWidth = window.innerWidth;
var mouseWidthLocation = e.x;
var percentOfWidth = (100 / windowWidth) * mouseWidthLocation;
// Height
var windowHeight = window.innerHeight;
var mouseHeightLocation = e.y;
var percentOfHeight = (100 / windowHeight) * mouseHeightLocation;
avatar.style.top = percentOfHeight + "%";
avatar.style.left = percentOfWidth + "%";
}
document.onmousemove = updateImgPosition;
This is a demo of what I have: http://jsfiddle.net/uQAmQ/1/
Fiddle: http://jsfiddle.net/uQAmQ/2/
You should not "pan" on an absolutely positioned element, because the window's width and height keep changing according to the image. A smoother solution involves using a background image. See the middle of my answer for the used logic.
Consider this JavaScript (read comments; HTML + CSS at fiddle):
(function(){ //Anonymous function wrapper for private variables
/* Static variables: Get the true width and height of the image*/
var avatar = document.getElementById("avatar");
var avatarWidth = avatar.width;
var avatarHeight = avatar.height;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
/* Logic: Move */
var ratioY = (avatarHeight - windowHeight) / windowHeight;
var ratioX = (avatarWidth - windowWidth) / windowWidth;
function updateImgPosition( e ) {
var mouseY = e.pageX; //e.pageX, NOT e.x
var mouseX = e.pageY;
var imgTop = ratioY*(-mouseY);
var imgLeft = ratioX*(-mouseX);
document.body.style.backgroundPosition = imgLeft + "px " + imgTop + "px";
}
/* Add event to WINDOW, NOT "document"! */
window.onmousemove = updateImgPosition;
})();
The logic behind it:
Relative units cannot be used, because the image size is specified in absolute units.
The offsets should change according to a specific ratio, which is similar to: image size divided by window size.However, this ratio is not complete: The image would disappear at the bottom/left corner of the window. To fix this, substract the window's size from the image's size. The result can be found in the code at variable ratioX and ratioY.
The previous code had to be loaded at the window.onload event, because the image's size was dynamically calculated. For this reason, a HTML element was also included in the body.
The same code can be written much smaller and efficient, by specifying the size of the background in the code. See this improved code. Fiddle: http://jsfiddle.net/uQAmQ/3/
(function(){ //Anonymous function wrapper for private variables
/* Static variables: Get the true width and height of the image*/
var avatarWidth = 1690;
var avatarHeight = 1069;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
/* Logic: Move */
var ratioY = (avatarHeight - windowHeight) / windowHeight;
var ratioX = (avatarWidth - windowWidth) / windowWidth;
function updateImgPosition( e ) {
var mouseX = e.pageX; //e.pageX, NOT e.x
var mouseY = e.pageY;
var imgTop = ratioY*(-mouseY);
var imgLeft = ratioX*(-mouseX);
document.body.style.backgroundPosition = imgLeft + "px " + imgTop + "px";
}
/* Add event to WINDOW, NOT "document"! */
window.onmousemove = updateImgPosition;
})();
If you don't mind a decreased code readability, the following code is the best solution, Fiddle: http://jsfiddle.net/uQAmQ/4/:
(function(){ //Anonymous function wrapper for private variables
/* Static variables: Get the true width and height of the image*/
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var ratioY = (windowHeight - 1069) / windowHeight;
var ratioX = (windowWidth - 1690) / windowWidth;
window.onmousemove = function( e ) {
document.body.style.backgroundPosition = ratioX * e.pageX + "px " + ratioY * e.pageY + "px";
}
})();