I think I'm going crazy :).
In my js file I have:
alert( $('.element').width() );
it will alert "867"...Which is wrong.
In the Chrome or Firefox console i type:
$('.element').width();
It responds with 567. Which is correct.
Am I missing something here. Should I be doing this a different way. Cause the code in the js file is messing everyting up.
BTW the element does have a width and float set through CSS -- width: 80% and float: left. But the browser consoles still give me the right width.
Thanks.
Try this:
$(window).load(function(){
alert( $('.element').width() );
});
try
$('.element').outerWidth();
Let me know if it helps
Sometimes you have to work with properties thinking about padding and margin extra sizes. Commands like innerWidth take care about the padding of the element, but outerWidth corresponds to the size counting it's border (and if receive true their margin too).
Take a look at this topic already closed, i hope this must help you: What is difference between width, innerWidth and outerWidth, height, innerHeight and outerHeight in jQuery
Cause
The .width() method is subject to the browser's reflow and repaint. The browser reflows and repaints the DOM objects during runtime. Visual changes to the HTML document also trigger reflow and repaint.
With these reasons, the .width() method will return a zero (0) value during browser states where reflow-and-repaint is still about to happen.
Solution
Always call the .width() method after reflow-and-repaint.
Common cases
Case #1. Document ready VS Window load
$(document).ready(function(){
// during this state, .width() is more likely equal to zero (0)
});
During the $(document).ready, DOM objects are ready to be manipulated. However, the browser is still doing reflow-and-repaint. Thus, there is a huge chance you will get .width() = 0
$(window).load(function(){
// during this state, .width() is more likely to have the right values
});
At $(window).load, DOM objects are ready to be manipulated and the browser is done with reflow and have repainted everything on the document.
Case #2. Hidden VS Shown
HTML
<div style="display:none">
<button>Foo</button>
</div>
jQuery
// still hidden
$('button').width(); // 0
// now shown
$('div').show();
$('button').width(); // right value
Again, to fix the zero width issue, always call the .width() method after reflow-and-repaint.
Related
I am new to jquery and am currently trying to set a variable equal to the height of some div with id="thing" before animating another div with class=".init_leftbar" by the same quantity.
var iHeight = $("#thing").height();
$(".init_leftbar").animate({top: iHeight + "px"});
However, this does not seem to be working.
if I just set "iHeight" equal to some number it will animate however.
I figured there has been some misunderstanding on my part as to how the "height()" method works.
Any help is greatly appreciated.
I would try to print $("#thing").height() in the browser console with
console.log($("#thing").height());
to see what is returning from the div.
I also noticed that .height() has some problems with absolute positioned divs given a display:block; style.
As documented in the Jquery API:
http://api.jquery.com/height/
// Returns height of browser viewport
$( window ).height();
// Returns height of HTML document
$( document ).height();
Consider running the script on document ready, allowing everything else to load first.
Also, you might get better mileage with outerheight(), which accounts for everything which can make up the height, including padding.
What about replacing:
$("#thing").height();
with:
$('#thing').css("height");
Be aware that css() returns string as "100px" and not 100 as height()
so you need to delete the '+ "px"' suffix.
My problem is very similar to this one except the thing that fixed element may change his height dynamically during application lifecycle (other data, viewport change, etc... ).
I'm using setInterval() function with 100ms interval to update offset of content element depending on header height.
jQuery(function($){
setInterval(function(){
$('article').css('padding-top', $('header').outerHeight());
}, 100)
});
Here is jsfiddle for it (change the width of the resulted page to see how it works).
For user experience it looks just great, but I'm curious is there a better way?
What are the disadvantages of this approach?
The major disadvantage is that you consume CPU every 100ms. And it doesn't do anything most of the time.
There is a better way. Just emit an event after the fixed element changes height and bind your css adjusment to it. Something like:
$(document).trigger('my_element_changed_height');
wherever the height changes and
$(document).on('my_element_changed_height', function() {
$('article').css('padding-top', $('header').outerHeight());
});
I suppose you can use jquery.ba-resize.js library. Here is a link: http://benalman.com/projects/jquery-resize-plugin
It allows you to use resize event on any DOM element. But if I'm not mistaken this library uses setTimeout functionality and I'm not sure that's better in performance.
UPDATE: time goes and web evolve, position: sticky
header{
position: sticky;
}
Old Answer:
Here is another solution that comes to my head. I was thinking how would be great have such position : fixed-relative :) (That fixed on viewport but doesn't desapear from normal flow) And here is an idea how to emulate this behaviour. Set header element position as relative.
header{
position: relative;
}
And add some listner to scroll event.
jQuery(function($){
$(window).scroll(function(){
$('header').css('top',$(this).scrollTop() );
});
});
It's much pretty than have infinity loop with setInterval or trigger some event across your application.
Unfortunately it will not work on most touch devices
I am trying to write a code based on the width of a page. For that, I am using "window.screen.availWidth", and then a conditional, as you can see below:
var page_width = window.screen.availWidth;
if ((930 < page_width) || (page_width <= 1100)) {
// code...
}
My problem is that the conditional doesn't work, and applies the code regardless of the page width. When I call the variable alone, it gives me the proper value, so I suppose the problem is somewhere in the conditional. Can anyone please shed some light on this? (I am new to Javascript!)
That's because if the first part is false (ie. the page width is less than 930) then the second part must be true.
I think you meant && instead of ||.
screen.availWidth returns the width of the user's screen not of the page. You might want to compute the width of the browser window using jQuery like so:
$(window).width()
Or, depending on what your are doing, you might want to take a look at CSS media queries.
It's an and/or problem. "If page_width is greater than 930 or the page width is less than or equal to 1100". I assume you want it to be if page_width is in that range, so just change the or to an and and I think it should work right.
I'm working on a script uses jQuery's data() function and HTML5 data attributes to dynamically switch an image's src attribute based on a media query. The idea behind this is to serve a lo-fi image by default (optimized for mobile), and serve a hi-fi image for larger screens. (This is not necessarily limited to images.) The script works 100% in Chrome/Opera/Safari/iOS but not completely in FF and IE.
<img src="ex1_lo-res.png" data-websrc="ex2_hi-res.png" alt="example">
<img src="ex2_lo-res.png" data-websrc="ex2_hi-res.png" alt="example">
A live example of this in use is responsetheme.com, where above 480px wide, the image should be pink, and below 480px wide, it should be yellow. I know that both data() and Modernizr.mq are supported in FF and IE—I tested them without the resize() function. So I think the issue has something to do with the trigger or the each() or resize() function. Any idea on what I'm missing?
jQuery(document).ready(function($) {
/* get elements that have a data-websrc attribute */
$websrc = $('[data-websrc]');
$websrc.each(function() {
/*
Set data-osrc equal to element's original src value.
This allows us the ability to access the original src
(even after we replace the attribute).
*/
var $this = $(this);
$this.data('osrc', $this.attr('src'));
});
$(window).resize(function() {
/*
Check breakpoint.
(Modernizr.mq checks the media query and returns boolean.)
*/
airsrcWEB = Modernizr.mq('screen and (min-width:480px)');
/*
Replace src with data-websrc (if above breakpoint).
Otherwise fallback to data-osrc (original src).
*/
$websrc.each(function() {
var $this = $(this);
var src = ( window.airsrcWEB ) ? $this.data('websrc') : $this.data('osrc');
$this.attr('src', src);
});
}).resize(); // trigger resize handlers
});
Also, I wasn't sure as to whether I have the functions in the most efficient way as far as which was inside which, so I'd also like to hear any tips for speeding this up. =)
Update 1: I also tried with the ternary like this and still the same issue:
var src = ( airsrcWEB ) ? $this.data('websrc') : $this.data('osrc');
Update 2: I figured out the issue with FF. Apparently a FF6 window won't resize below about 556px wide. I tested the script with a breakpoint above that and the switch worked. (Even the examples on mediaqueri.es won't shrink below 556px wide in FF6.)
You already found out that FF has a minimal window size. I don't know the exact value, but I believe it's a percentage of the initially available viewport width.
This is a restriction of XUL, the language in which FF was written.
The question is, is this really a problem in your case? The only persons that fiddle around with the window size are (front-end) webdevelopers. Normal users just load a page and stick with it, so basically I'm thinking that you might not really need to attach this functionality to a resize event.
Furthermore, this is only an issue when users are shrinking the window, not when expanding. If they already loaded the hi-res image, why bother loading the low-res aswell?
I want to be able to calculate the width, in pixels, of an element that has the width css property set to 'auto'.
I have tried element.style.width but didn't work because it returned 'auto'. I notices that the jQuery function width() returns the length in px, but I cannot use jQuery to solve this, because it is not available in my page. So, does anybody know an equivalent method for jQuery width()?
Thanks.
jQuery uses...
element.getBoundingClientRect().width
internally, it has some other stuff on top to deal with browser differences.
It returns an elements rendered size, where as .offsetxx returns sizes according to the box model.
element.getBoundingClientRect()
Is the most accurate way to get an elements "real" dimensions.
Here is a post by John Resig ( author of jQuery ) on the matter.
http://ejohn.org/blog/getboundingclientrect-is-awesome/
Wasted 2 hours on this.
For my case other answers did not work so combining others answers & my findings into one post with examples, for easy reading:
For an element like select, the width() in JQuery is same as clientWidth in JavaScript.
Sample code below, including output:
// Add jQuery library in HTML:
// <head>
// <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
// </head>
let eleId = 'myselectid1'; // NOTE: Provide your element id below
// jQuery
console.log( $('#' + eleId).width() );
// JavaScript
let ele = document.getElementById(eleId);
console.log(ele.clientWidth); // 58 // includes padding into calculation
console.log(ele.offsetWidth); // 60 // includes border size and padding into width calculation
console.log(ele.getBoundingClientRect().width); // 60 // includes border size and padding into width calculation
console.log(window.getComputedStyle(ele, null).getPropertyValue("width")); // 60px (note the px in value, you may also get values like 'auto') // all dynamic values for all CSS properties, IE>=9
console.log(ele.style.height); // empty string // if you set it earlier, you would get this
console.log(ele.innerWidth); // undefined // only works on window object, not on element like select/ div - fails in older IE<9
Hope that helps.
It basically comes down to .offsetWidth, but the jQuery code is a little more complicated due to cross-browser differences.