Max-height based on height of other element - javascript

I would like to be able to set the max-height of one element based on the (variable) height of another one — though I'm very much a JS beginner, I'm just about positive there's a way to do so with it. This is not the parent element I want to base the max-height on. Obviously, I want this solution to work regardless of whatever the height of the element might be at any given time on any given page.
Just to be clear, I want to find the height of, let's say, an element with the class "ElementOne", and then set the max-height of "ElementTwo" to, say, height-of-ElementOne plus 113px.
How do I go about doing this?

I use this snippet by Paul Irish to do just that:
$.fn.setAllToMaxHeight = function(){
return this.height( Math.max.apply(this, $.map( this , function(e){ return $(e).height() }) ) );
}
// usage: $(‘div.unevenheights’).setAllToMaxHeight()

I think thats what you mean:
var h = document.getElementById("ElementOne").style.height;
document.getElementById("ElementTwo").style.maxHeight = h + 113 + "px";

This uses jquery to assign an event listener to the resize event of the window and ELementOne (Note: I don't think that most html trigger there own resize event). Here is a jsfiddle: http://jsfiddle.net/xiondark2008/UPqsV/
I add color to the divs so you can see them.
html:
<div class="ElementOne"></div>
<div class="ElementTwo"></div>
javascript:
function setHeight(){
var elementOne = $(".ElementOne").height();
$(".ElementTwo").height( elementOne +113);
}
$(window,".ElementOne").resize(setHeight);
setHeight();

Related

Add an ellipsis to middle of long string in React16

I am trying to add an ellipsis to the mid-point in a string with the following complications:
I don't know how long the string is going to be
I only know the max-width and min-width of the parent element
The string may or may not fit into it's parent and not require ellipses
I have a plunk here to illustrate it. The script only assumes one instance, but you should get the idea:
(function(){
// variables
var parent = document.querySelectorAll(".wrapper")[0],
parentWidth = parent.clientWidth,x = 0, elem, hellip
txtStr = document.querySelector("#shorten"),
strWidth = txtStr.clientWidth,
strTxt = txtStr.innerText,
ending = document.createElement("span"),
endTxt = strTxt.slice(Math.max(strTxt.length - (strTxt.length / 4))) || endTxt;
txtStr.style.overflow = "hidden"
txtStr.style.textOverflow = "ellipsis"
ending.appendChild(document.createTextNode(endTxt))
ending.classList.add("ellipsis")
document.querySelectorAll(".wrapper")[0].appendChild(ending)
var ell = function(a, b){
if (a <= b){
ending.classList.add("visible")
}
else {
ending.classList.remove("visible")
}
}
ell(parentWidth, strWidth) // We need to display any changes immediately
window.onresize = function(){ // if the window is resized, we also need to display changes
hellip = document.querySelectorAll(".ellipsis")[0].clientWidth
parentWidth = parent.clientWidth
// the use of 'calc()' is because the length of string in px is never known
txtStr.style.width = "calc(100% - " + hellip + "px"
ell(parentWidth, strWidth)
}
})();
It's a bit clunky, but demonstrates the idea.
The issue I am having in React 16, is that the string is not rendered at the point I need to measure it to create the bit of text at the end. Therefore, when the new node is created it has no dimensions and cannot be measured as it doesn't exist in the DOM.
The functionality works - sort of as the screen resizes, but that's beside the point. I need to get it to do the do at render time.
The actual app is proprietary, and I cannot share any of my code from that in this forum.
EDIT: Another thing to bare in mind (teaching to suck eggs, here) is that in the example, the script is loaded only after the DOM is rendered, so all of the information required is already there and measurable.
Thank you to all that looked at this, but I managed to figure out the problem.
Once I worked out the finesse of the lifecycle, it was actually still quite tricky. The issue being measuring the original string of text. Looking back now, it seems insignificant.
Essentially, I pass a few elements into the component as props: an id, any required padding, the length of the ending text required for context and the text (children).
Once they are in, I need to wait until it is mounted until I can do anything as it all depends on the DOM being rendered before anything can be measured. Therefore, componentDidMount() and componentDidUpdate() are the stages I was interested in. componentWillUnmount() is used to remove the associated event listener which in this instance is a resize event.
Once mounted, I can get the bits required for measuring: the element and importantly, its parent.
getElements(){
return {
parent: this.ellipsis.offsetParent,
string: this.props.children
}
}
Then, I need to make sure that I can actually measure the element so implement some inline styles to allow for that:
prepareParentForMeasure(){
if(this.getElements().parent != null){
this.getElements().parent.style.opacity = 0.001
this.getElements().parent.style.overflow = 'visible'
this.getElements().parent.style.width = 'auto'
}
}
As soon as I have those measurements, I removed the styles.
At this point, the script will partially work if I carry on down the same path. However, adding an additional element to work as a guide is the kicker.
The returned element is split into three elements (span tags), each with a different purpose. There is the main bit of text, or this.props.children, if you like. This is always available and is never altered. The next is the tail of the text, the 'n' number of characters at the end of the string that are used to contextually display the end of the string - this is given a class of 'ellipsis', although the ellipsis is actually added to the original and first element. The third is essentially exactly the same as the first, but is hidden and uninteractable, although it does have dimensions. This is because the first two - when rendered - have different widths and cannot be relied upon as both contribute to the width of the element, whereas the third doesn't.
<Fragment>
<span className='text'>{this.props.children}</span>
<span className='ellipsis'>{this.tail()}</span>
<span className='text guide' ref={node => this.ellipsis = node}>
{this.props.children}</span>
</Fragment>
These are in a fragment so as to not require a surrounding element.
So, I have the width of the surrounding parent and I have the width of the text element (in the third span). which means that if I find that the text string is wider than the surrounding wrapper, I add a class to the ellipsis span of 'visible', and one to the 'text' element of 'trimmed', I get an ellipsis in the middle of the string and I use the resize event to make sure that if someone does do that, all measurements are re-done and stuff is recalculated and rendered accordingly.

This object at .mouseenter() function

I'm having a simple (I hope it's simple) question. I'm using 10 divs (div1, div2...) and I want to calculate the distance between two of them. I've already clicked one, that takes the class (img.home). I have the function to calculate the distance between two objects showdistance(div1, div2), but How can I use it to calculate showdistance($('img.home').parent()[0], $(this) ) where (this) is the div, that my cursor is point at at the moment ( .mouseenter(function() {$(this).text(showdistance)}); )
Thanks in advance,
If needed, I can make a jsfiddle with the whole code, but as I believe it is a rather easy thing, that I don't know and the code is a large piece it's easier this way.
Best regards.
Store your last clicked element in a variable.
Then compare the position when you enter an element.
You can apply top, left, right or bottom, if you like.
var clicked = null;
$("someSelection").click(function() {
clicked = $(this);
});
$("someSelection").mouseenter(function() {
// if-statement to ensure that the event won't fire if you haven't clicked one
if(clicked !== null) {
console.log($(this).position().top - clicked.position().top);
console.log($(this).position().left - clicked.position().left);
}
});

How to get width of each input with specified class

Ok so I have fairly simple thing but something is not working properly.
The first thing I have is a couple of <input /> buttons and what I want is to set automatically width for each button wrap.
For some reason whatever I try I get the value 0 [3x]. For example something like this...
$('.button_holder .proceed').each(function() {
console.log( parseInt( $(this).outerWidth() ) );
});
The console.log gives me "0".
Here's a fiddle for a preview and it works there... Quite odd.
JS Fiddle Example
I don't understand why, any tips ?
EDIT 1:
My project has #container set to display: none and JS does some fadeIn effect. Removed that and it appears that it is working properly now.
Any ideas why and how to make it work with fadeIn() of container ?
When the element is set to display:none the element is technically not present on the page. So the width will be 0.. If you want it to work write your code in the callback of fadein
$('#container').fadeIn( 300, function() {
$('.button_holder .proceed').each(function() {
console.log( parseInt( $(this).outerWidth(), 10 ) );
});
});
So after the container is visible on the page, which is in the callback function , iterate over the elements and it should work fine.
And don't forget to add the radix parameter when you use parseint

How to calculate each element's height and use these values as a variable in function?

I am trying to create a simple text accordion which calculates each panel's height and return this value as a variable. I can get values with if statements like if ( i === 0 ) { $(this).height(); } but can't get this variable to the outside.I can do this without using variable but it became useless in long term.
Brıefly: I want to calculate each element's height and use this variable inside click function.
Here is jsFiddle which includes the problem.
var panel = $('.holder div');
var trigger = $('a');
panel.each(function(i) {
//problem starts when i try to calculate each ele's height
var eachEleHeight = i.height();
trigger.click(function() {
$(this).prev('div').animate({'height':eachEleHeight+'px'},500);
//this works widthout var eachEleHeight but became useless
//$(this).prev('div').animate({'height':'300px'},500);
});
//this is for hiding text at doc.ready
panel.css('height','56px');
});​
If I well understood, try this :
panel.each(function(i, el) {
// create a reference to te current panel
var $el = $(el);
// execute a function immediately, passing both the panel and its height
(function(p, h) {
// the trigger is targeted as the next link after the current panel
p.next('a').click(function() {
p.animate({ height : h + 'px'},500);
});
}($el, $el.height()));
// set each panel height
$el.css('height','56px');
});
Example fiddle : http://jsfiddle.net/Aw39W/55/
There is a problem with the code you posted. i is the index of the current element. Not the element itself.
Try var eachEleHeight = $(this).height();
Fiddle
The sequence of events you've used seems a bit weird. You're actually binding a click event to all a tags for each panel element. Try this: Fiddle
I just used the min-height and max-height css attributes to store the initial to/from height variables. This will automatically get you your starting heights.
If I understand the question, you want to have the elements height for the accordion animation function. This is a trick but it works. I frequently use Mootools so I'll write using it. You should be able to figure it out.
var orgHeight = i.offsetHeight;
i.setStyle('height','100%');
var eachEleHeight = i.offsetHeight;
i.setStyle('height',orgHeight);
Essentially you would be flipping the element to reveal it's height and flipping it back before the document has time to make it visible on screen.
Not sure this is exactly what you were looking for, but hope it helps.

Getting Constant Height Of Element

I'm trying to make auto-scroll for my div. Whenever I'm check height of that div, it gives me "200px" as it is in CSS. I think that it somehow because of CSS styles. How to fix it?
Idea of this all is that users may submit messages to chat, then they will appear in that box. I need to auto-scroll that box to the bottom...
$('div').prop('scrollHeight');
before jQuery 1.6, prop should be attr.
or just hit the HTML property:
$('div')[0].scrollHeight;
Why not use JQuery and either use the ScrollTo plugin to scroll your content with animation, or use ScrollTop and just set the scroll to the scrollheight, like so;
$("div").ScrollTop($("div").ScrollTop());
You probably don't even need to find out the height of the div. Based on your goals, you could just scroll it to max. Try something like this, inside the same function that adds new elements to your div:
<script>
$('#screameria form').submit(function() {
var screams = $('#screameria .screams');
screams.append(
'<div>'
+ new Date()
+ ': '
+ $(this.scream).val()
+ '</div>'
);
screams.scrollTop(999999999);
return false;
});
</script>
Here's a jsFiddle with it

Categories

Resources