Mootools: height of hidden elements - javascript

Morning all,
I'm trying to create a Mootools effect to show and hide replies to a comment on a discussion board. When the user clicks the "replies" link in the comment I want to increase the height of the comment container and then fade in the replies content. If the replies content is already visible, clicking on the link would reverse the effect.
I've got it sort of working, but I'm having trouble getting the correct height of my hidden elements (repliesH in my JS). I've tried getDimensions(), measure() and getComputedSize(), but they all give the same result: when elements are set to display:none I get a height that is too small; when I set them to display:block the height is correct. Can any kind person spot where I'm going wrong?
http://jsfiddle.net/andfinally/tVBCa/
Cheers
Fred
=======================
A BIT LATER
Just noticed - the width of the .comments-list container seems to have something to do with this problem. When I remove that width the effect works OK. This probably means that getDimensions gets the height of an element when it's not nested in anything. Can anyone suggest how I can work out what the height'll be when it is nested?
Cheers
Fred

you could use Fx.Reveal, it's very useful when u encounter these kind of problems, and it simplifies A LOT your code, i.e. (I've forked your example) => http://jsfiddle.net/steweb/DH27F/

A simple way to workaround it:
replies.show();
var repliesH = replies.getDimensions().y;
replies.hide();
Just show it, get dimensions and hides it again. This runs so fast that neither is visible to the user.
Your updated Fiddle here.

Related

"More" functionality for comments problems

I'm trying to make a "More" functionality for comments.
How I'm trying to make it work:
I split comment in 2 parts - 1st 200 symbols and the rest of the symbols.
The rest of the symbols are placed in a <span class="hidden_comment_container" ></span> which by default gets display:none
Toggle to show the rest is placed if needed (if comment length > 200 symbols).
This is working more or less fine (jsfiddle demo) but there are 2 problems.
Upon slidedown, hidden_comment_container receives display:inline-block and messes up things a bit, since it gets transferred to a new line (check demo to see what I mean)
When sliding down and sliding up, near the end of animation you can notice some twitching.
Can anyone please help me solve these 2 problems?
The first one can be resolved by adding the following to the case when the remaining text is hidden.
$(this).next(".comment_container").children('.hidden_comment_container').slideDown('medium', function() {
$('.hidden_comment_container').css('display', 'inline');
});
Basically you're changing the display attribute of the .hidden_comment_container selector as I believe slideDown is adding a display:inline-block to it which would cause it to jump a line.
Fiddle here
Answer to point 2 can be found in Basic jQuery slideUp and slideDown driving me mad!; basically you need to explicitly add the height of the element before hiding / showing it.
As a side note the css property content can only be used with the pseudo elements :after and :before; I updated my fiddle accordingly.
An alternative solution
Have a look at this script, it does everything you need! I tested it already on another project and it works like a charm: jquery plugin to truncate elements based on height instead of number of characters

Animating a table with jQuery

I asked a question yesterday on here and got some awsome help, but I need more help concerning more or less the same, only a bit different.
This is my old thread.
So ye, I made this and the idea is that you can customize the table to see it the way you want. for now its possible to drag the columns to change the order and its possible to order the columns on alphabet or high/low. Since I got help here, its now also possible to hide the columns.
Now I want to make the hiding process a bit more smooth, since its hard to see if something is hidden after a click if you use no animation. I use .fadeOut(200); now, but when the fading is done the column just 'jumps' to fill the gap, is it possible to animate this in some sort?
Edit: After thinking some more, I thought that I could just loop a -1px width untill the element's width is 1px and then just hide it, but for some reason that wont work, the table doesnt respond to .width(xxx); or .css('width', 'xxx');. It does change the value, but the td keeps the same width.
This is somewhat of a workaround, and there might be a better solution, but here it is anyway:
Animate the opacity to 0.0. Fadeout does the same, but it also sets display:none after completely fading out. It is the display:none that causes the adjacent column to jump and fill in the gap.
Animating will cause your hidden div to remain there. Now that it is no longer visible, animate its width to 0. This will cause the adjacent div to smoothly take over its place.
Once width is 0, set display:none
Here's a working sample I whipped up. Adjust accordingly to animate width: http://jsfiddle.net/x7BEv/8/
Here's how the magic happens:
$(document).ready(function(){
$('#button').click(function(){
$('#upper').animate({opacity:0.0},'slow').animate({height:'0px'},'slow',allDone);
});
});
function allDone()
{
$('#upper').hide();
}
I'm not sure how important the allDone() method is. You could probably do away with it.
you must use jqgrid
or just for sorting you can use tablesorter which is very easy to implement

Force scrollbar to bottom

I am making a little messaging / chat system that is working nice and fine. The problem is, the <div> which the messages are outputted to does not scroll the way I need it to.
All the new messages are added to the bottom of the div and when more are added and the scrollbar shows up, the scrolling stays at the top of the <div>. I need this to be reversed, so that the scrolling always sticks to the bottom of the <div>.
A good example of what I want would be Steam's chat windows, or even this text input which I am using to fill out the question.
As I would like to avoid jQuery, this has me completely stuck. If you could point me in the correct direction that would be great! I am not sure if HTML and CSS can handle this, or if JavaScript is necessary at all.
The Javascript code below should keep your div's scrollbar positioned at the bottom like you described:
var objDiv = document.getElementById("divExample");
objDiv.scrollTop = objDiv.scrollHeight;
This solution and more information can be found on the link below:
http://web.archive.org/web/20080821211053/http://radio.javaranch.com/pascarello/2005/12/14/1134573598403.html
I think this is a better solution:
element.scrollTop = element.scrollHeight - element.clientHeight;
For Kotlin I have used the following:
val element = view?.findViewById<ScrollView>(R.id.uidScrollElement)
element?.smoothScrollTo(0,element.measuredHeight)

Ajax Div Maintain Height

Greetings,
I have a list of user comments on a page, with a next button which makes an Ajax call to get the second set of comments.
The problem is, the height of the comments div temporarily becomes very small while the loading bar is in place. This makes the user need to scroll back down to see the new comments
The issue can be seen at the bottom of this page by clicking "Next" comments.
Is there a way to force the div to maintain its height through Javascript? I do not want to hard code the div height in case a page has 3 or less comments.
before loading your ajax-content into the comments section set the height of the comments container like this (jQuery):
// #comments is just an example. It may not be the same as your comments section.
$("#comments").css("height",$("#comments").height);
then after loading your comments (the ajax complete/success callback) unset the height like this:
$("#comments").css("height","auto");
Add only height() (parenthesis)
here
$("#comments").css("height",$("#comments").height);
I know this is an older question but this worked for me.
var containerHeight = $("#comments").height();
$("#comments").css("height",containerHeight);
Then set it to "height auto" when you load in the content.
$("#comments").css("height","auto");

Javascript clientHeight and alternatives

I am currently trying to modify a Javascript function that "slides in" a <div>. The script as it is requires you to define the height of the div, so it is mostly useless in dynamically filled <div>s. I found some text on the clientHeight property in javascript, but it would appear that it doesn't support <div>s with display set to none (which is the method used to slide the div in). That makes sense, as the height of that div in the client window is nothing.
Basically I was wondering what other methods you all know of, or if there's a way to get around the clientHeight = 0 when display: none.
Thanks!
Oh, and here's the function I'm using:
function getDivHeight(objName) {
return boxHeight = document.getElementById(objName).clientHeight;
}
A simple solution is to set it's visibility to "hidden" and it's display to "block" and measure it. However, some modern browsers will manage to update the page layout during this short time and you will get a nasty flicker. The easiest way to overcome this is to place the element in an absolutely positioned container with overflow set to "hidden".
I've had luck cloning the element, moving it offscreen, then displaying it to get the client height:
var original = document.getElementById(some_id);
var new_item = original.cloneNode(true);
document.body.appendChild(new_item); // item already hidden, so it won't show yet.
// you may wish to validate it is hidden first
new_item.style.position = "absolute";
new_item.style.left = "-1000px";
new_item.style.display = "block";
var height = new_item.clientHeight;
EDIT: Looking through the jQuery code, they do exactly what Tsvetomir Tsonev suggests. jQuery temporarily sets the style to "display: block; position: absolute; visibility: none", and then measures the height, swapping the properties back after the measurement.
So, it looks like you're stuck with having to do something hackish, whether it's cloning the node or risking having it flicker in some browsers... I like Tsvetomir's suggestion better than my initial hack as it, at least, doesn't involve cloning a node into the DOM that you don't need. Either way, the element must not be set to "display: none" in order to measure it's height. Isn't the DOM wonderful? :-)
EDIT 2: Also worth noting that, after jQuery gathers the height, it adds allowances for padding, margin and border sizes, so you may need to as well.
Yes, an element that is not displayed on the page has no dimensions.
It kind of makes sense. Consider an element that has been created and filled with a bunch of text, but not yet added to the document tree. How high is it? Depends on font-size. How big is font-size? Depends where in the document that div is inserted; its parent font-size would inherit through.
Similarly for an element with “display: none”. It's not rendered, so it has no dimensions. Couldn't we ask “how high would this be if it were ‘display: block’”? Turns out no, because if it were displayed, that in itself could change the dimensions of its parent block, and then the dimension of displayed elements would be inconsistent with the dimensions of non-displayed elements!
The typical solution is to unset “display: none”, measure the height of the element, and then immediately re-set “display: none”. The browser won't redraw in the middle of a bit of JavaScript, so you won't see a flicker on the page.
I nkow you guys solved this a long time ago but I thought I should share this since it quite tricky to get the height of a hidden div tag.
heres what I did after reading your post,
I placed the div i want to slide inside a 1px height div with overflow set to hidden.
you dont even need to set the display of the inner div to none since it is already there and if you use offsetHeight it should return the proper height for all browsers and you can use that height to slide your div up an down.
PEACE!!!
In IE you could try scrollHeight, but I'm not sure if it will work or if it is cross browser.

Categories

Resources