I have a tricky layout that I believe can only be responsive with JavaScript, but I can't manage to get inline styling with bound data to accomplish this. There is a wrapper element around an image that I want to be the height of the image plus 80px. For brevity, I'll just post the two elements that I need working together, and cut out the extra markup because it is irrelevant.
<v-flex v-resize="onResize" v-bind:style="{height: this.imageHeight}" xs12 md6>
{{this.imageHeight}}
<img src="../assets/images/image1.jpg" alt="image" ref="desktop-image">
</v-flex>
In data, I define imageHeight as 0 at first with the intention of having that value update once the page loads or the screen is resized.
data () {
return {
imageHeight : 0
}
}
Then in mounted(), I redefine the imageHeight data to be the height I want.
this.imageHeight = this.$refs["desktop-image"].offsetHeight + 80;
I also include this in the resize method.
onResize () {
this.imageHeight = this.$refs["desktop-image"].offsetHeight + 80;
}
Once the page loads or once I resize the screen, the outputted {{this.imageHeight}} value that I have above the image updates correctly, but it never updates in the v-bind:style on the image element so the height stays at 0px.
How can I get the inline styling data to update like it does elsewhere?
The height CSS property must be either:
a <length> value with length units (for non-zero values); e.g., 200px
or:
a <percentage> value; e.g., 100%
A number value is invalid. The value is in the form of a string, so your code should append 'px' to the calculated number:
this.imageHeight = this.$refs["desktop-image"].offsetHeight + 80 + 'px';
demo
Related
What would be the best way in Javascript/JQuery to determine the size in pixels a div would actually take to display it?
Let say I have a table with and the columns are fixed with the tag width="60px". Inside this column I add dynamically a div with a certain content, which will mostly be the following :
<div class="auto">
<img width="50px" src="/images/header-5123724.png">
<hr>
<span>Table1</span></div>
So, I know the size of the image which is 50px, but I do not know how long the text will be.
Another hint I have is that the element <span> will always be there, and the content should not be wrapped.
Is there a way to "render" the span and to get the size in pixels?
Any help is appreciated.
I found a way to accomplish what I wanted. I will post it here, maybe that can help somebody.
// add an extra span
$(this).parent().append('<span id="test" />');
//.. pick up the element to test into obj
// test the size
$('#test').html(obj.text()).css({
'font-family': obj.css('font-family'),
'font-size': obj.css('font-size'),
'font-weight': obj.css('font-weight')
});
//Width and adjustment
Width = $('#test').width() + 24;
//...If we want to check the max width, then we can loop through many columns of the table
//Finally adjust the width
obj.width(Width).css('min-width', Width);
//Cleanup
$('#test').remove();";
It is not very clean, but that worked for my case. For some reason the size of the columns were not set properly because it was resized by some plugin after the content was rendered by the browser.
Cheers.
Will the width be calculated on page load or on the fly?
If it is on page load then, #cont is the id of the content box.
$(document).ready(function() {
var dynWidth = $('#cont').width();
console.log('dynWidth: ' + dynWidth);
});
If it is on the fly then,
$(document).ready(function() {
$('#cont').bind('DOMSubtreeModified', function(){
var dynWidth = $('#cont').width();
console.log('changed dynWidth: ' + dynWidth);
});
});
Note: DOMSubtreeModified is not supported in IE8 (and below).
For any details refer this link.
If I have div A and div B, is there a way to say A.width = b.width = MAX(a.width, b.width) ? That is, whichever has the largest inner content would dictate how large both are.
The actual problem I'm trying to solve is with columns - left, middle, and right. I want the left and right to be the same fixed width (but this could vary depending on their content).
It is not possible to use CSS to achieve this. However, if there is a way to do it with a JS-based solution. Here I am using jQuery. Let's say you have two divs, with classes a and b respectively.
$(function() {
function equalizeSize($ele) {
if($ele.length > 1) {
// Let CSS automatically calculate natural width first
$ele.css({ width: 'auto' });
// And then we fetch the newly calculated widths
var maxWidth = Math.max.apply(Math, $ele.map(function(){ return $(this).outerWidth(); }).get());
$ele.css({ width: maxWidth });
}
}
// Run when DOM is ready
equalizeSize($('.a, .b'));
// Run again when viewport has been resized, which **may** affect your div width.
// This is optional, but good to have
// ps: You might want to look into throttling the resize function
$(window).resize(equalizeSize($('.a, .b')));
});
See proof-of-concept fiddle here: http://jsfiddle.net/teddyrised/N4MMg/
The advantages of this simple function:
Allows you to dictate what elements you want to equalize widths with.
Uses the .map() function to construct an array, which we then use Math.max.apply to get the maximum value in the array
Forces automatic calculation of width when the function first fires (especially when resizing the viewport)
Allows you to call to recalculate the size again, using the handler equalizeSize() when you change the content in the divs... you can call the function again, say, after an AJAX call that appends content to either element.
It is not very clear what you want from the description. but I can rewrite your code this way.
var properWidth = Math.max($("#a").width(), $("#b").width());
$("#a").css("width", properWidth + "px");
$("#b").css("width", properWidth + "px");
I am not sure if it is this kind of solution you want.
I'm not sure there is a way to do it like that. But why not make a default function to set the size:
function changeSize(w, h)
{
A.setAttribute('style', 'width:'+w+'; height:'+h);
b.setAttribute('style', 'width:'+w+'; height:'+h);
}
Working fiddle: http://jsfiddle.net/kychan/ER2zZ/
I have a function that corrects and adapts the size (and vertical alignment) of three fluid columns with text and images.
The script, while not polished/efficient yet, works exactly as expected but sometimes(?) fails at the beginning.
The functions is the following:
var resetHeight = function(){
var maxHeight = 0;
$(".same-height-col").height("auto").each(function(){
maxHeight = $(this).height() > maxHeight ? $(this).height() : maxHeight;
}).height(maxHeight + 25);
var maxTextSize = 0;
var tempHeight;
$(".same-height-col").each(function(){
tempHeight = $(this).find(".links-text").height();
maxTextSize = tempHeight > maxTextSize ? tempHeight : maxTextSize;
});
var topMargin;
$(".same-height-col").each(function(){
topMargin = (maxTextSize - $(this).find(".links-text").height()) + 25;
$(this).find(".links-image").css("margin-top",topMargin);
});
}
The I call it twice:
$(document).ready(function() {
resetHeight();
$(window).resize(function() {
resetHeight();
});
});
The problem is that many times when I load the page, I see this:
That doesn't happen consistently, but it does happen pretty often, but as soon as I resize the window the script works exactly as expected:
So where could the mistake be?
The script is called for sure even at the beginning, if I put an alert in the function, and just load the page (with no resize), the alert pops up.
When you calculate the maxHeight value, you reset all the inline heights that were set in the previous resetHeight call by doing $(".same-height-col").height("auto"). However, you don't reset the margin-top properties that were added to the links-image elements.
This means that the second time that resetHeight is called (and all subsequent times), the maxHeight calculations will be different. To make sure the results are the same each time, you need to reset the margin-top property on the links-image elements before doing the calculation.
$(".same-height-col .links-image").css("margin-top","");
$(".same-height-col").height("auto").each(function(){
maxHeight = $(this).height() > maxHeight ? $(this).height() : maxHeight;
}).height(maxHeight + 25);
You may also want to make that height maxHeight+50 rather than maxHeight+25 if you think the result of the layout after the resize looked better than the intial layout on load.
As i understand your issue, you should set attribute width and height of images and use the document ready handler:
HTML for all images in .links-image DIVs: {width/height/alt attributes should always be specified for image when possible}
<div class="links-image" style="margin-top: 53px;">
<img src="img/list.png" width="210" height="92" alt="">
</div>
JS code:
$(document).ready(function() {
$(window).resize(resetHeight).trigger('resize');
});
I’m starting with the premise that you want the box content components — the title, the subtitle, and the image — vertically aligned across all the three boxes. If this is not true, just ignore this answer.
While I can’t spot the issue in the code at hand, I would try to approach it another way, without JS: clearfix the columns and fix the height of the components: let’s say I expect titles to be one line of text, subtitles three lines, and images are already fixed-height.
The fixed height will give you vertical alignment, and the clearfix will take care of the column height.
I have the following elements in a HTML page:
<body>
<div style="height:100%; width:100%">
<div style="height:100px;"></div>
<div id="container" style="height:25%; width:50%">
</div>
Now I would like to get the height in pixels of the div container using jQuery (or plain JavaScript).
How can I do it?
$('#container').height() // returns `0`
In CSS, height as a percentage doesn't work unless the parent element also has height defined. And the parent's height won't work (if it's a percentage) unless its parent has height defined, and so on.
In this case, try adding this to your CSS:
html, body {
height: 100%;
}
Update: The other reason your code is returning 0 is because the DIV doesn't have any children (not even text nodes). If you added a child node, it would return the height of that child node, but it still wouldn't return the 25% value until you add an explicit height to all parents of elements that define height in percentages.
With the code you provided, "0" is the correct answer. -- As mentioned in a comment below : Divs are block by default. The reason this resolves to "0" is because in this instance, the container that it is deriving the "%"s from, are 0. So you are essentially saying : height = 0 * .25;
You need to either specify size of the div and its parent OR there need to be child nodes which grow the div's size naturally.
Then $('#container').height() will return a value larger than 0
You can do this Height_String= new String($('#container').css('height'))
the out put is 19px as string
or
You can do this Height_Int = new Number (parseInt($(#container).css('height'), 10))
the output is 19 as integer
$('#container').css('height');
The height is returned as 0 because the computed #container height is 0. Assigning a % height to a div without any relative fixed height will be assigned to 0.
See DEMO why it returns 0.
If your block has visible height other than zero, then probably you call jQuery.height() before page is loaded. Wrap your call into $(document).ready(function() {});:
$(document).ready(function() {
/* some actions */
var h = $('#container').height(); // Height that you need.
});
With simple JavaScript syntaxe it's works perfectly, but it's return the height in percent :
document.getElementById('container').style.height
I have the following function for calculating the height of .node. It then takes away the height of a possible image, .node-image, from the height of the .node, and sets a column, .node-content-column to have a height that is the difference (i.e. 500 - 50 = 450; column becomes 450 in height).
function initColumnSizer() {
imageHeight = $('.node-image').outerHeight(true);
resizeHeight = ($('.node').outerHeight() + 75) - imageHeight;
$('.node-content-column').removeAttr('style');
$('.node-content-column').css('min-height', resizeHeight);
$('.node-content-column').css('height', 'auto !important');
$('.node-content-column').css('height', resizeHeight);
}
This function gets called on page load, and resizes .node-content-column as expected.
It also gets called when a div within .node is toggled using jQuery.toggle(), but this calculation returns a larger number everytime, instead of reverting back to the original once this toggle is reverted.
Can anyone see where I am going wrong with this calculation? Or if I am going about it the wrong way?
Thanks in advance!
Karl
1) Maybe the problem is in outerHeight() function (it takes into account padding and border). Try using just height or clientHeight:
var img = document.getElementById('imageid');
//or however you get a handle to the IMG
var width = img.clientWidth;
var height = img.clientHeight;
2) why do you need to cleanup the whole elements' style?
and then you try to assign height = auto, and after that: height = resizeHeight - what's the purpose for that ? check the logic of your code.
outerHeight(true) will return height + padding + border + margin. Possibly, you might want to use height() ?
Most possible is that "larger number everytime" have always constant difference -- for example 75.
May be you just have some dependecies between .node-content-column and .node?
If your nodes like .node-content-column, .node and .node-image are all singles, then it's better to use IDs for them -- not CSS classes.