Progress bar - jQuery to Pure Vanilla JS - javascript

I am trying to convert this small script to a pure vanilla JS.
The plain JS values are not calculated correctly.
What do I need to get to calculate the same value as in the jQuery version?
Pleaset scroll down in the jQuery fiddle to see what l mean.
$(document).scroll(function() {
var progressBar = $('progress'),
docHeight = $(this).height(),
winHeight = $(window).height(),
max = docHeight - winHeight,
value = $(window).scrollTop();
progressBar.attr('max', max);
progressBar.attr('value', value);
});
DEMO jQuery
And below, my pure JS which doesn't work :
var progressBar = function() {
var myBar = document.querySelector('progress'),
docHeight = document.clientHeight,
winHeight = window.clientHeight,
max = docHeight - winHeight,
value = window.scrollY;
myBar.setAttribute('data-max', myBar.getAttribute('max'));
myBar.setAttribute('max', max);
myBar.setAttribute('data-value', myBar.getAttribute('value'));
myBar.setAttribute('value', value);
};
document.addEventListener('scroll', progressBar);
window.addEventListener('resize', progressBar);
My attempt in vanilla
Thank you!!

You'll need to use different properties to access the document and window heights.
document.clientHeight should be document.body.clientHeight. The clientHeight property is designed to return the calculated heights of HTML elements. Using the body element fits within that design.
window.clientHeight should be window.innerHeight. Since window isn't an HTML element, it has its own height properties.
I also simplified the progress bar attribute-setting logic. Unless you have some external requirement to set the data-max and data-value attributes, you can remove those lines. If you do need to set those attributes, you can use the dataset property.
var progressBar = function() {
var myBar = document.querySelector('progress'),
docHeight = document.body.clientHeight,
winHeight = window.innerHeight,
max = docHeight - winHeight,
value = window.scrollY;
myBar.setAttribute('max', max);
myBar.setAttribute('value', value);
};
document.addEventListener('scroll', progressBar);
window.addEventListener('resize', progressBar);
See JSFiddle.

The clientHeight property doesn't exist on window or document. If you have a look at the JQuery docs:
$(window).height() returns height of browser viewport
$(document).height() returns the height of HTML document
There already a great answer on StackOverflow explaining the different ways to get the height. Looking at the JQuery source, the height of the window uses window.innerHeight. For the document it's using the max of:
document.body.scrollHeight
document.body.offsetHeight
document.documentElement.clientHeight
Putting it all together, it works AOK: https://jsfiddle.net/pd3dtvxn/7/

Related

jQuery Script creates infinite loop in Firefox (only)

I wrote a jQuery Script which checks the window size and increases the outer wrapper to fit perfectly into the users window.
function reSize($target){
$target.css('width', $(window).width()+'px');
}
$(document).ready(function(){
setTimeout(function() {
$(window).bind('resize', reSize($('#blocker')));
$(window).trigger('resize');
while($(window).height() < $('.newcontainer').height()+30){
$('.newcontainer').css('width', $('.newcontainer').width() - 10 +'px');
}
$('#chatfenster').css('height', $('.newcontainer').height() - 260 +'px');
$('#userlist').css('height', $('.newcontainer').height() - 350 +'px');
}, 100);
});
It works very smooth in Chrome and Safari but in Firefox it's freezing and I don't know why. Sometimes I feel like Firefox is the new IE.
http://design.maxxcoon.com/bestlife/webinar_chat/ (don't open this link in firefox because it crashes the browser)
Can anybody help me please?
Thanks in advance
This part is very unreliable:
while($(window).height() < $('.newcontainer').height()+30){
$('.newcontainer').css('width', $('.newcontainer').width() - 10 +'px');
}
You are checking the height of the window against the height of the first element found with a class of newcontainer. As long as the height of the window is smaller than that height plus 30 pixels, you set the width of all elements with class="newcontainer" to 10 less than the width of the first one of them.
If your condition is for one dimension (height) and the changes you make is to another dimension (width), the loop will run either never, or probably forever, or possibly randomly...
If there is a maximum height or a maximum width for your .newcontainer elements, you should instead calculate the allowed values for height or width and set them once, not in a loop! Something like this, maybe:
var windowHeight = $(window).height();
var maximumContainerHeight = windowHeight - 30;
$('.newcontainer').css('height', maximumContainerHeight + 'px');
However, I do not know if you want to set width or height, so I'm guessing.
If what you are doing is really setting the width of something, hoping that the layout engine will affect the height as a side-effect, you are going at this the very wrong way.
Another, better, solution is to use modern CSS solutions, like flexbox, to let the browser automatically handle all layout issues.
Figured it out without a loop.
May be helpful for others.
<script type="text/javascript">
function reSize($target){
$target.css('width', $(window).width()+'px');
}
$(document).ready(function(){
setTimeout(function() {
$(window).bind('resize', reSize($('#blocker')));
$(window).trigger('resize');
var windowSize = $(window).height();
var containerHeight = $('.newcontainer').height();
var containerWidth = $('.newcontainer').width();
if(containerHeight > windowSize){
var pixelToMuch = containerHeight - windowSize;
var divFactor = pixelToMuch * 1.67;
var newWidth = containerWidth - divFactor;
$('.newcontainer').css('width',newWidth+'px');
}
$('#chatfenster').css('height', $('.newcontainer').height() - 260 +'px');
$('#userlist').css('height', $('.newcontainer').height() - 350 +'px');
}, 100);
});
</script>

Reset "style" attribute on jquery.resizable element without breaking resizing?

Full jsbin here
Basically, I have a "panel" that is anchored on the right side of the viewport. I want it to be resizable horizontally. The catch is, I want the negative space to be limited between 200px and 400px. If that doesn't make sense, please see the JSBin and it should be easier to understand.
Here's what I have so far:
$( document ).ready(function() {
var maxContentWidth;
var minContentWidth;
$(window).resize(function() {
var ww = $(window).width();
maxContentWidth = ww - 200;
minContentWidth = ww - 400;
$('#content').resizable("option","maxWidth",maxContentWidth);
$('#content').resizable("option","minWidth",minContentWidth);
//if I could even "reinitialize" the pane upon resize, but this doesn't work:
/*$('#content')
.css('right','10px')
.css('top','10px')
.css('left','200px')
.css('bottom','10px');
*/
//I discovered that doesn't work because jquery resizable applies a local "style" attribute, so then I tried this:
//$('#content').attr('style',''); //this makes it completely not resizable at all
});
$('#content').resizable({
handles: "w",
maxWidth: maxContentWidth,
minWidth: minContentWidth
});
});
update: As you can see in the jsbin comments, I decided just reinitializing the panel on window resize was fine and should be simple to do, right? Well, jquery resizable uses a local "style" attribute instead of modifying css. So, I tried just clearing out the style attribute on window.resize, but if I do that I can't resize the panel at all, which doesn't make sense to me.
So. Any ideas how I can "clear" all the styling and reset the CSS without breaking the resizable functionality?
I don't know if i understand, but let's give a try!
http://jsfiddle.net/2eor05dt/
$( document ).ready(function() {
// First Value
var maxContentWidth;
var minContentWidth;
maxContentWidth = $(window).width() - 200;
minContentWidth = $(window).width() - 400;
$(window).resize(function() {
var ww = $(window).width();
maxContentWidth = ww - 200;
minContentWidth = ww - 400;
$('#content').resizable("option","maxWidth",maxContentWidth);
$('#content').resizable("option","minWidth",minContentWidth);
var gap = ww - $('#content').width() - parseInt($('#content').css('left')) - 10;
$('#content').width($('#content').width() + gap);
});
$('#content').resizable({
handles: "w",
maxWidth: maxContentWidth,
minWidth: minContentWidth
});
});

resize image two or three time via javascript

could we do this with javascript?
consider we have a x * y px div
(width=x and hight=y)
and user uploads image in any size, I want to find a way this image not to be Deformed in Container.
I have a senario but not sure it's possible via javascript or jquery in addition of css. you can see my senario below but I dont know how can I write correctly in javascript
var ContainerWidth=document.getElementById("Container").width;
var ContainerHight=document.getElementById("Container").height;
var imgWidth = document.getElementById("myImg").width;
var imgHight =document.getElementById("myImg").height;
if imgWidth > ContainerWidth
{
myimg.style.width = ContainerWidth;
var newHightOfmyimg= myimg.style.height = 'auto';???????????????????????? the main problem: how can I know what is this auto height in px and how can set it in a var?
}
if newHightOfmyimg > ContainerHight
{
UltimateimgHight= ContainerHight;
UltimateimgWidth=auto;
}
firstly to get the style of a property using javascript, you should do the following
var containerWidth = document.getElementById('Container').style.width;
var containerHeight = document.getElementById('Conatiner').style.height;
var imgWidth = document.getElementById('myImg').style.width;
var imgHeight= document.getElementById('myImg').style.height;
that will return the style set by the CSS itself.
secondly, auto is the original width / height of the element. if you want your image or any element to get it's parent's width / height then you could use inherit in CSS.

Get browser width and height after user resizes the window

Is there any way to get the browser width and height after a user has resized the window. For example if the window is 1920 by 1080 and the user changes the window to 500 by 500 is there any way to get those two new values in JavaScript or jquery?
Pure Javascript answer:
var onresize = function() {
//your code here
//this is just an example
width = document.body.clientWidth;
height = document.body.clientHeight;
}
window.addEventListener("resize", onresize);
This works fine on chrome. However, it works only on chrome. A slightly more cross-browser example is using the event target properties "outerWidth" and "outerHeight", since in this case the event "target" is the window itself. The code would be like this
var onresize = function(e) {
//note i need to pass the event as an argument to the function
width = e.target.outerWidth;
height = e.target.outerHeight;
}
window.addEventListener("resize", onresize);
This works fine in firefox and chrome
Hope it helps :)
Edit: Tested in ie9 and this worked too :)
If you need to know these values to do layout adjustments, I bet you plan on listening to those values. I recommended using the Window.matchmedia() API for that purpose instead.
It is much more performant and is basically the JS equivalent of CSS media queries.
Very quick example of use:
if (window.matchMedia("(max-width: 500px)").matches) {
/* the viewport is less than or exactly 500 pixels wide */
} else {
/* the viewport is more than 500 pixels wide */
}
You can also setup a listener that'll get called every time the state of the matches property changes.
See MDN for description and example of using a listener.
It's possible by listening to resize event.
$(window).resize(function() {
var width = $(window).width();
var height = $(window).height();
})
You can use the JQuery resize() function. Also make sure you add the same resize logic to reload event. If user reloads in the sized window your logic won't work.
$(window).resize(function() {
$windowWidth = $(window).width();
$windowHeight = $(window).height();
});
$(document).ready(function() {
//same logic that you use in the resize...
});
Practically, I use this and it helps me a lot:
var TO = false;
var resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize';
$(window).bind(resizeEvent, function() {
TO && clearTimeout(TO);
TO = setTimeout(resizeBody, 200);
});
function resizeBody(){
var height = window.innerHeight || $(window).height();
var width = window.innerWidth || $(window).width();
alert(height);
alert(width);
}
You can use the resize event, along with the height() and width() properties
$(window).resize(function(){
var height = $(window).height();
var width = $(window).width();
});
See some more examples here
Use jQuery resize method to listen window size change . inside callback you can get height and width.
$(window).resize(function(){
var width = $(window).width();
var height = $(window).height();
});
Simplest way to get real width and height of an element after window resize as the follow:
<div id="myContainer">
<!--Some Tages ... -->
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function () {
$(window).resize(function () {
//The below two lines of codes more Important to clear the previous settings to get the current measure of width and height
$('#myContainer').css('height', 'unset');
$('#myContainer').css('width', 'unset');
var element = $('#myContainer');
var height = element.height();
var width = element.width();
//Below two lines will includes padding but not border
var innerHeight = element.innerHeight();
var innerWidth = element.innerWidth();
//Below two lines will includes padding, border but no margin
var outerHeight = element.outerHeight();
var outerWidth = element.outerWidth();
//Below two lines will includes padding, border and margin
var outerHeight = element.outerHeight(true);
var outerWidth = element.outerWidth(true);
});
});
</script>
You can use the event object to get the height and width, I use destructuring assignment and the target points to window:
const handleGetDim = ({ target }) => ({
width: target.innerWidth,
height: target.innerHeight,
});
window.addEventListener('resize', handleGetDim);

Resizing images in Chrome using JQuery

I just ran into the weirdest of bugs today. I'm not sure if it's a bug in Chrome or something that I can work around but here goes.
I built a JQuery function to resize a set of images that are posted on a forum:
$(".post-message img.post-image").load(function(){
$(this).each(function() {
var maxWidth = 200;
if($(this).width() > maxWidth)
{
var factor = $(this).width() / maxWidth;
var width = $(this).width();
var height = $(this).height();
$(this).css('width', width / factor);
$(this).css('height', height / factor);
}
});
});
The problem is that this only seems to work when I refresh the page. It doesn't work when you press previous or when you get linked to the page.
In chrome the $(img).width() property returns 0 in both cases when the function doesn't work.
This function performs as expected in IE9 and FF3
What can I do to fix this odd behavior?
Most probably because the images are being pulled up from the browser cache, and the load event is not triggering. The way around this is to manually trigger load if the images's complete properties have been set:
$(".post-message img.post-image").one("load", function(){
$(this).each(function() {
var maxWidth = 200;
if($(this).width() > maxWidth)
{
var factor = $(this).width() / maxWidth;
var width = $(this).width();
var height = $(this).height();
$(this).css('width', width / factor);
$(this).css('height', height / factor);
}
});
}).each(function() {
if(this.complete) $(this).trigger("load");
});
Karmin is correct here. I ran into this problem a few years ago and ended up just not relying on img.load. His workaround for manually triggering the load event should work.
However...
Developers should do max-width or height in CSS in this scenario. In fact, it is good programming practice to do what one can in CSS before doing them in javascript.
Additionally, if one were to keep going with this solution, var width and var height should be placed outside of the if statement next to var maxWidth, and used wherever $(this).width() is called (including the initial check on line 4). Right now the code is unnecessarily creating a new jQuery object to get the height each time when it should have stored and used the value from the first check.
Thanks for the contributions guys. A previous answer given on stack - that I apparently couldn't find this afternoon jQuery && Google Chrome - solved my problem!
$(window).load(function() {
$(".post-message img.post-image").one("load", function(){
$(this).each(function() {
var maxWidth = 200;
if($(this).width() > maxWidth)
{
var factor = $(this).width() / maxWidth;
var width = $(this).width();
var height = $(this).height();
$(this).css('width', width / factor);
$(this).css('height', height / factor);
}
console.log($(this).width())
});
}).each(function() {
if(this.complete) $(this).trigger("load");
});
});
The code has to be executed on $(window).load() together with the provided code by karim79.

Categories