Mootools textarea scrollHeight - javascript

How can I access the scrollHeight using mootools or some other property that contains the height so I can resize it to make an autogrow textarea?

Mootools offers a variety of Element 'dimension' functions that give you information on the scrollable and absolute element sizes. Full docs available here: http://mootools.net/docs/core/Element/Element.Dimensions
What you want to do is compare the return values of your element's getScrollSize() function to your element's getSize() function - in particular the 'y' member, which represents element and scrollable area height, respectively. Something along the lines of this should work:
var myElement = $('myElement'); // get a reference to your element
var scrollSize = myElement.getScrollSize(); // MooTools-specific function.
var elementSize = myElement.getSize(); // MooTools-specific function.
if (scrollSize.y > elementSize.y) {
// determine whether the scrollable area is greater than the dimensions
// of the element. If so, resize the element to match the scrollable area.
myElement.setStyle('height', scrollSize.y + 'px');
}

David Walsh created an excellent plugin for just this purpose:
http://davidwalsh.name/flext-textrea

Here's a simple method I'm using that expands but also contracts the textarea.
The issue you're always going to have is styling on the textare (padding/border).
The first thing to know is that getSize() will get the size of the textarea from absolute top to the absolute bottom, taking into account padding and borders. However, the actual style height of the text area .getStyle('height').toInt(), is the inside of the text box without padding and border. This is the part you need to be interested in as, when you set your height, it sets that, it doesn't set the full height of the textarea from absolute top to bottom.
Here's a working example, with a textarea that's styled (See Demo)
This will also resize the element correctly if you ran it inside domReady.
function expBox(el){
var e = $(el.id);
if(typeof(e._expBox) == "undefined"){
var v = e.value;
e.value = "";
var ss = e.getScrollSize();
var s = e.getSize();
var h = e.getStyle("height").toInt();
e._expBox = (s.y-h)-(s.y-ss.y);
e.value = v;
}
var k = event.keyCode || event.charCode;
if(k == 8 || k == 46){
e.setStyle("height","auto");
}
var ss = e.getScrollSize();
e.setStyle("height",(ss.y-e._expBox));
}
Demo:
http://jsfiddle.net/greatbigmassive/M6X5j/

Related

Does Jquery/Javascript require an elem to be in the DOM to use .css()?

if(typeof this.description === 'undefined') {alert('No Description Set!'); return false;}
var tempDiv = document.createElement('div'); //create a div outside of the DOM
tempDiv.className = 'descriptionColumn formBox contentRow'; //make sure and use the
//same/equivlent class(s) to ensure accuracy
tempDiv.innerHTML = this.description; //insert the text
document.body.appendChild(tempDiv); //render div
lineHeight = parseInt($(tempDiv).css('line-height')); //get the line-height (make sure this is specified in CSS!)
//also we use Jquery here to handle any vender inconsistencies,
divHeight = tempDiv.clientHeight; //get the div height
tempDiv.parentNode.removeChild(tempDiv); //clean up, delete div
delete tempDiv;
return divHeight/lineHeight; //divide the height by the line-height and return
This code works, I am trying to calculate the number of lines in a div. That said I wasn't able to get the line-height until after I added this element to the DOM.
Origionally I planned on not adding it at all because I only use it to calcuate the number of lines in the DIV.
It makes sense that it wouldn't have a height until I added it, I am just wondering if I did the right thing, or if there is a way to get the line-height without adding it to the DOM in the first place.
Rendering/Layout decision by browser is taken by browser 2 conditions:
1)new element is inserted
2)some element's style has been changed
3)sometimes when window is resized
so until the element is in DOM Tree browser will not give Layout related style to it.
consider following code:
var div = document.createElement(div);
var style = window.getComputedStyle(div);
console.log( style.color );//prints "" (empty string)
why??
because window.getComputedStyle() returns the CSS style which are actully present in DOM(browser).
now,
document.body.appendChild(div);
var style = window.getComputedStyle(div);
console.log( style.color );//prints rgb(somevalue)
why??
because rendering engine has decided the CSS properties.
//One gotcha
var div2 = document.createElement("div");
div2.style.color = "red";
console.log( $(div2).css("color") ); //prints red because jQuery gives preference to div2.style.color over window.getComputedStyle(div2);
but console.log ( window.getComputedStyle(div2).color );//prints "" .... this proves that browser has not yet decided the properties of div2
Yes, it is. But ... if you have jQuery on your page, why don't you use it?
var $div = $('<div/>', {
class: 'descriptionColumn formBox contentRow',
text: 'Description',
css: {
position: 'absolute',
left: '-99999px'
}
}).prependTo('body'); // element wouldn't be visible for user on this step
//your calculations
$div.remove();

How to get margin value of a div in plain JavaScript?

I can get height in jQuery with
$(item).outerHeight(true);
but how do I with JS?
I can get the height of the li with
document.getElementById(item).offsetHeight
but i will always get "" when I try margin-top:
document.getElementById(item).style.marginTop
The properties on the style object are only the styles applied directly to the element (e.g., via a style attribute or in code). So .style.marginTop will only have something in it if you have something specifically assigned to that element (not assigned via a style sheet, etc.).
To get the current calculated style of the object, you use either the currentStyle property (Microsoft) or the getComputedStyle function (pretty much everyone else).
Example:
var p = document.getElementById("target");
var style = p.currentStyle || window.getComputedStyle(p);
display("Current marginTop: " + style.marginTop);
Fair warning: What you get back may not be in pixels. For instance, if I run the above on a p element in IE9, I get back "1em".
Live Copy | Source
Also, you can create your own outerHeight for HTML elements. I don't know if it works in IE, but it works in Chrome. Perhaps, you can enhance the code below using currentStyle, suggested in the answer above.
Object.defineProperty(Element.prototype, 'outerHeight', {
'get': function(){
var height = this.clientHeight;
var computedStyle = window.getComputedStyle(this);
height += parseInt(computedStyle.marginTop, 10);
height += parseInt(computedStyle.marginBottom, 10);
height += parseInt(computedStyle.borderTopWidth, 10);
height += parseInt(computedStyle.borderBottomWidth, 10);
return height;
}
});
This piece of code allow you to do something like this:
document.getElementById('foo').outerHeight
According to caniuse.com, getComputedStyle is supported by main browsers (IE, Chrome, Firefox).
I found something very useful on this site when I was searching for an answer on this question. You can check it out at http://www.codingforums.com/javascript-programming/230503-how-get-margin-left-value.html. The part that helped me was the following:
/***
* get live runtime value of an element's css style
* http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element
* note: "styleName" is in CSS form (i.e. 'font-size', not 'fontSize').
***/
var getStyle = function(e, styleName) {
var styleValue = "";
if (document.defaultView && document.defaultView.getComputedStyle) {
styleValue = document.defaultView.getComputedStyle(e, "").getPropertyValue(styleName);
} else if (e.currentStyle) {
styleName = styleName.replace(/\-(\w)/g, function(strMatch, p1) {
return p1.toUpperCase();
});
styleValue = e.currentStyle[styleName];
}
return styleValue;
}
////////////////////////////////////
var e = document.getElementById('yourElement');
var marLeft = getStyle(e, 'margin-left');
console.log(marLeft); // 10px
#yourElement {
margin-left: 10px;
}
<div id="yourElement"></div>
Here is my solution:
Step 1: Select the element
Step 2: Use getComputedStyle and provide the element to it
Step 3: Now access all the properties
const item = document.getElementbyId('your-element-id');
const style= getComputedStyle(item);
const itemTopmargin = style.marginTop;
console.log(itemTopmargin)
It will give you margin with px units like "16px" which you might not want.
You can extract the value using parseInt()
const marginTopNumber = parseInt(itemTopmargin)
console.log(marginTopNumber)
It will give you the numerical value only (without any units).

Can you detect when a dom node's style is set to 'auto'?

With the example CSS:
.thing { height: auto }
and HTML:
<div class="thing">The quick brown fox jumps over a lazy dog.</div>
is it possible to detect that the height of .thing is set to 'auto'?
The following methods return values:
jQuery('.thing').height() // n
jQuery('.thing').css('height') // 'npx'
getComputedStyle(node).height // 'npx'
Is there any method that will tell me that the browser is calculating these values from 'auto'?
Yes there is a way, but it's not a funny one. What you have to do is:
Loop through all styletags and linked stylesheets.
Then get the selectorText for all cssRules in all style tags
styletag.sheet.cssRules.selectorText
or for IE < 9
styletag.styleSheet.cssRules.selectorText
Get all of your elements parents id, class and tagName to find out what possible ways for the tag to get the attribute.
Find all possible combinations that point towards your element in your
list of cssRules
check those cssRules at cssRules.style.width if it is auto.
or do it some reverse way and find all cssRules with style.width == 'auto'; either way its not something easy to get without a lot of code
jQuery('.thing').each(function (i,n){
console.log( $(n).style.height);// if not then just try to simply find the n.style.height
});
//this is another way // at least in ff it would work :)
window.document.styleSheets[0].cssRules[0].style.height
hope it helps, otherwise you have alot of digging to do :)
For the second option where you see [0] means you have to loop as there may be different file names, etc etc...
full example :
var ss = window.document.styleSheets;
for(i=0;i<ss.length;i++){
var rules = ss[i].cssRules;
for(j=0;j<rules.length;j++){//loop style sheets
var rule = rules[j];
if(rule.selectorText=='thing'){//loop each stylesheet rule
console.log(rule.style.height);
// should return height for everytime height is used with every .thing in any of your stylesheets attached :)
}
}
}
PLEASE NOTE
You must escape those from cross domain.e.g. if you have included
<link ....="...jquery.com.../ui.css" /> it will not work as this might be considered as security risk (cross domain)...
This isn't the most efficient solution, particularly for old IE versions, but it should work pretty well:
Measure the height of your element
Append some content to the element e.g. <div style="clear: left; height: 30px">Test</div>
Test the new height, if it has changed your element has height auto
Remove the content
Here's my implementation:
$.fn.hasAutoHeight = function() {
if (this.length === 0) return;
var self = this.first();
var height = self.css("height");
var position = self.css("position");
// Check for inline elements
if (self.css("display") === "inline" && self.css("float") === "none") {
var position = self.css("position");
if (position === "static" || position === "relative") return true;
}
// Quick check to see if a style height is set
if ($.style(self[0], "height") !== "") return false;
// Otherwise use the long route
var test = $('<div style="clear: both; height: 30px">Test</div>');
self.append(test);
var hasAutoHeight = self.css("height") !== height;
test.css("color", "red").remove();
return hasAutoHeight;
};
Notes:
The 'quick check' line might not work correctly if there is a height: auto !important; rule in the CSS, in which case you'd always have to go the long route.
This is not efficient in terms of DOM interactions so your application would want to cache this result whenever possible.
I'm reluctant to cache the result internally in the plugin because classes/CSS rules might change and invalidate the result.
This won't work for elements with no body, such as <img> and <br>
Here's a more complete implementation of the above suggestions:
$("*").data("autoHeight", "false");
var stylesheets = window.document.styleSheets;
for (i=0; i < stylesheets.length; i++) {
var rules = stylesheets[i].cssRules;
for (j = 0; j < rules.length; j++) {
var rule = rules[j];
var style = rule.style.getPropertyValue("height");
var auto = !style || style.match(/^\s*auto\s*(!important)?$/);
$(rule.selectorText).each(function() {
var elem = $(this);
if (asSpecific(rule.selectorText, $(elem).data("autoHeightSelector"))) {
$(elem).data("autoHeight", !!auto);
$(elem).data("autoHeightSelector", rule.selectorText);
}
});
}
}
You'll need to implement asSpecific(a, b) which should work out if css selector a is at least as specific as selector b, e.g. p#foo a#bar is more specific than p.foo. You also need to take into account the !important flag.
This might be useful: http://www.w3.org/TR/CSS2/cascade.html#specificity
This should add a data property to each element specifying whether or not it has an auto height style in the CSS, but you'll also need to check the style attribute and think about default styles.

How can I find the position of an HTML element relative to the entire desktop screen using JavaScript?

How do i find the X,Y coordinates of a particular html element ( eg. div, table, lable, etc...) relative to the desktop screen (i.e. outside the browser window) using JavaScript?
I can find the height and width of the element by using offsetHeight and offsetWidth, but can't find anything that can give me exact X,Y coordinate of the element relative to the user’s entire desktop screen.
I think you have to follow the tree up, through the parents, and keep adding the offsets, like described here:
http://bytes.com/topic/javascript/answers/90547-how-get-absolute-position-element
function getY( oElement )
{
var iReturnValue = 0;
while( oElement != null ) {
iReturnValue += oElement.offsetTop;
oElement = oElement.offsetParent;
}
return iReturnValue;
}
I don't think it is not possible even it is quite simple.
Find the position of browser relative to screen
Find the element position relative to view port.
Add the coordinates and you will have the output you want
Follow the piece of code I written:
var element = document.getElementById("ID of the element");// you can use any method to find the element ..
var position = getPosition(element);
function getPositions(obj)
{
var p = [];
var position = obj.getBoundingClientRect();
p[0] = window.screenX + position.left;
p[1] = window.screenY + position.top;
p[2] = position.width;
p[3] = position.height;
return p;
}

How to find the width of a div using vanilla JavaScript?

How do you find the current width of a <div> in a cross-browser compatible way without using a library like jQuery?
document.getElementById("mydiv").offsetWidth
element.offsetWidth (MDC)
You can use clientWidth or offsetWidth Mozilla developer network reference
It would be like:
document.getElementById("yourDiv").clientWidth; // returns number, like 728
or with borders width :
document.getElementById("yourDiv").offsetWidth; // 728 + borders width
All Answers are right, but i still want to give some other alternatives that may work.
If you are looking for the assigned width (ignoring padding, margin and so on) you could use.
getComputedStyle(element).width; //returns value in px like "727.7px"
getComputedStyle allows you to access all styles of that elements. For example: padding, paddingLeft, margin, border-top-left-radius and so on.
Another option is to use the getBoundingClientRect function. Please note that getBoundingClientRect will return an empty rect if the element's display is 'none'.
var elem = document.getElementById("myDiv");
if(elem) {
var rect = elem.getBoundingClientRect();
console.log(rect.width);
}
You can also search the DOM using ClassName. For example:
document.getElementsByClassName("myDiv")
This will return an array. If there is one particular property you are interested in. For example:
var divWidth = document.getElementsByClassName("myDiv")[0].clientWidth;
divWidth will now be equal to the the width of the first element in your div array.
Actually, you don't have to use document.getElementById("mydiv") .
You can simply use the id of the div, like:
var w = mydiv.clientWidth;
or
var w = mydiv.offsetWidth;
etc.
call below method on div or body tag onclick="show(event);"
function show(event) {
var x = event.clientX;
var y = event.clientY;
var ele = document.getElementById("tt");
var width = ele.offsetWidth;
var height = ele.offsetHeight;
var half=(width/2);
if(x>half)
{
// alert('right click');
gallery.next();
}
else
{
// alert('left click');
gallery.prev();
}
}
The correct way of getting computed style is waiting till page is rendered. It can be done in the following manner. Pay attention to timeout on getting auto values.
function getStyleInfo() {
setTimeout(function() {
const style = window.getComputedStyle(document.getElementById('__root__'));
if (style.height == 'auto') {
getStyleInfo();
}
// IF we got here we can do actual business logic staff
console.log(style.height, style.width);
}, 100);
};
window.onload=function() { getStyleInfo(); };
If you use just
window.onload=function() {
var computedStyle = window.getComputedStyle(document.getElementById('__root__'));
}
you can get auto values for width and height because browsers does not render till full load is performed.

Categories