jQuery element width update problem - javascript

I want to get element width using jQuery.
The problem is when I change html inside this element.
I want to get its width and width() returns its parent width instead, it looks like html() doesn't update element width at all.
But... It works perfectly when no DOCTYPE is specified.
I'm using IE in WebBrowser control.
css:
p {
margin: 0;
padding: 0;
}
.name {
font-weight: bold;
}
.description {
color: #444;
width: 190px;
white-space: nowrap;
overflow: hidden;
}
#container {
}
html looks like this:
<div id="container">
<div id="friend0"><p class="name">Name</p><div class="description"><p>Description</p></div>
</div>
js:
var x1 = GetFriend(id).children('.description').width();
var x2 = GetFriend(id).children('.description').children('p').width();
(some jQuery animation code)
and after that:
GetFriend(id).children('.description').children('p').html('some now text here...');
var x3 = GetFriend(id).children('.description').children('p').width();
and x3 is the same as .description with value of 190
but when I don't declare DOCTYPE at the beginning of html it returns correctly updated value.
I need to have DOCTYPE declared because some animation code causes flickering of scrollbars.
Anyone know how to do it correctly?

You already are doing it correctly. Block elements like <p> will use the width of their parent; that's the way the standard box model works. It changes when you drop the DOCTYPE because you're toggling the browser in and out of quirks mode.
(Comment posted as answer ...)

Related

$('body').height() changing unpredictably

My goal is to have a white div (#containMe) stretch to the full height of the document, regardless of window size or how much content I have on the page.
I put my HTML head and JQuery in a PHP document and use PHP's require_once to put that header onto each page. However, when I've got #containMe set to the document's height with Jquery, it tries to set it to the body height instead. The body's height also seems to change each time I refresh, causing #containMe's height to change unpredictably.
The document's height appears to stay consistent, but the body's height fluctuates, and #containMe is trying to stick to the body's height instead of the document's. This happens with Chrome, Android Chrome, and Firefox. I tried the following:
$('body').height($(document).height());
But it seemed to have no effect.
Here's my Jquery in my head:
<script>
$(document).ready(function () {
$("#containMe").height($(document).height());
$("#containMe").width($(document).width() - 200);
$('.dropdown').hover(function () {
$('.dropdown-toggle', this).trigger('click');
});
});
</script>
(Note that the bootstrap dropdown is still working)
Here's my relevant CSS:
body
{
background: #333577 url(bg1.png);
height: 100%;
}
html
{
height: 100%;
}
#containMe
{
background: white;
margin-left: auto;
margin-right: auto;
padding-bottom: 25px;
padding-top: 15px;
box-shadow: 0px 0px 25px #111111;
}
Here's the relevant HTML:
<div id="containMe" class="container-fluid">
<div class="container-fluid jumbotron text-center"><h1>Web Pofrtfolio</h1>
<h2>By Rhea Herrmann</h2></div>
And here's a link to the page where the problem is occurring.
http://www.rheaherrmann.com/other/wiki.php
If you scroll to the bottom and keep refreshing, the div's height appears to fluctuate. I'm not sure what I'm doing wrong.
If i'm getting this right i think you could do the following and everything should be as you expect it to be:
Remove #containMe's height from the CSS, don't use any height at all.
Remove .container-fluid in .jumbotron. Since you already have a .container-fluid class above you don't need another .container-fluid, and as bootstrap's documentation states: containers are not nestables: http://getbootstrap.com/css/#overview-container.
Remove the .container-fluid class next to .innards (for the same reason as above). If you need to keep the paddings as it was, you could use .col-sm-12.
Remove or comment any javascript code that modify the height of #containMe.
Please let me know if this worked for you.
$(document).ready(function () {
var windowheight = $(document).height();
var windowwidth = $(document).width() - 200;
//alert (windowheight);
$('#containMe').css('height', windowheight + 'px');
$("#containMe").css('width' ,windowwidth + 'px' );
$('.dropdown').hover(function () {
$('.dropdown-toggle', this).trigger('click');
});
});
Use this in the JS
-Use 100vh instead of 100% in your css for #containMe.
-Don't nest containers with bootstrap. "Note that, due to padding and more, neither container is nestable." http://getbootstrap.com/css/#overview-container
Get rid of
height: [whatever];
In your #containMe class in the style sheet and remove it from your element style(the style attribute of the #containMe div). It has to be gone from both places.

Javascript height to impact content not just div

I am working on a form on a webpage. I want to have a button on a panel which when pressed expands a div (underneath the button) to make it visible and then invisible again when the button is pressed again - a kind of further details popout box. So far i have got this:
function blockappear() {
var ourblock = document.getElementById("theblock");
ourblock.style.transition = "all 2s";
if (ourblock.style.height == "0px") {
ourblock.style.height = "220px";
} else {
ourblock.style.height = "0px";
}
}
and this:
#theblock {
background-color: #a83455;
height: 220px;
width: 100%;
padding: 0;
margin: 0;
display: block;
}
and this:
<p><button type="button" onclick="blockappear()">Try it</button></p>
<div id="theblock">
Some text
</div>
And it seems to work which is quite pleasing (even though it has taken hours to get this far). The problem is this. I want the div to change from 200px to 0px including the contents not just to the extent it can according to the contents. At the moment the div shrinks, but the content "some text" stays put on the page. I have tried changing the display attribute of the div to 'block' and 'table' and still no joy. I thought that the point of a div was that it enclosed the content with the group tags and that the content could not exist without the div. If the div has 0px height how can the text still show?
Incidentally, if i just use display:none; on the div it works (without the transition of course). I need the content of the div to respond to the height of the div somehow - i suspect using the css properly.
I think this has been covered before by using jquery, but i want to use javascript now that i have started as it will probably take me another few hours if i start again with a whole new language :-)
Thanks for any help...
Add overflow: hidden; to your div. This will hide the content which doesn't fit into the container.
You want to use this CSS property on your div:
overflow: hidden;
This will make any content of #theblock bigger than #theblock itself invisible. So - if #theblock has height of 0px - all of its contents will be hidden.
Default value is overflow: visible;, so even content bigger than containing element itself will still be there for all to see. That's all there is to it.
Read more: overflow CSS property (MDN)

Add a div on the left side of a any page

I developing a plugin and want to add on any page a div on the left side, like a console.
I saw CSS styles, but testing the plugin on greasymonkey not always show me the div, how can i do?
The CSS code that I'm using is this:
var div_console = document.createElement("div");
div_consola.id = "div_consola";
div_consola.style.cssText = "overflow:scroll;
z-index:300;position:fixed;left:0px; width: auto;
height: 100%; border: solid 1px #e1e1e1;
vertical-align: middle; background: #ffdab9;text-align: center;";
var body = document.getElementsByTagName('body')[0];
body.appendChild(div_consola);
So, when loading any page I add with Javascript this div and then populate with data.
Any help?
Thank you!!
A couple of things:
You have typos in the variable name. I assume you mean div_console and not div_consola
You are assuming that a z-index of 300 will suffice, which may or may not be true. A page could choose to implement a z-index of 301.
Is the rest of your css being applied to the div you wish to affect?
You have specified
overflow: scroll;
width: auto;
Depend of your browser, maybe your div have an undefined size and the scrollbar which pop hide your div.
That's what happened to me when I tried your code on jsFiddle.
Here is the result when I change it to
overflow : hidden;
width: 50px;
JsFiddle
Edit : If it doesn't resolve your problem, could you please precise the conditions (browser, etc) when it doesn't work ?
div_consola.id = "div_consola";
div.setAttribute("id", "div_consola"); <------ Try using setAttribute to set Id.
EDIT:
Using same Id name and variable name is also one of the issue.
When I changed the variable name in your code, it worked fine.
var div_consola = document.createElement("div");
var div = document.createElement("div"); <------ variable name changed

position relative div wrapping input box

A little warning: I'm just starting out with css and js/html.
I'm trying to get a wrapper to wrap around a text box. As I understand it, divs without explicit dimensions wrap their content (height/width: auto). I'm using jquery to wrap an element element with a wrapper for a label. I'd like it to wrap the entire input box (as I believe it should considering the input box is within the div), but it doesn't seem to be as simple as wanting...
For some reason, I can't get the properties of my wrapper to change after setting them - even using the Chrome JS console. So even going in and manually setting the height of the wrapper div to 40 doesn't change anything.
Here's the fiddle everyone so far has been asking for - there's not much more to this question. I just want the div to wrap the input, which it isn't.
http://jsfiddle.net/5vBz4/
As far as I know, my input styles aren't conflicting, either:
input.floatlabel {
font-family: Helvetica;
font-weight: 100;
font-size: 15px;
height: 40px;
width: 40%;
text-align: center;
}
This is what I have so far, and the result.
As I understand it, you want:
.wrapper {
display: block;
}
Fiddle

textarea immitation is not working well. any replacements?

I have this html and css: http://jsfiddle.net/b7rDL/6/
HTML:
<div class="text-block" contenteditable="true" spellcheck="false">Some Text</div>
css:
.text-block {
resize: none;
font-size:40px;
border: none;
line-height: 1;
-moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
min-width: 30px;
overflow: visible;
white-space: nowrap;
display: inline-block;
}
This code allows me to write text with no width limit or height limit. It displays no scroll bar and it grows with the text. Those are basically the features I need.
How can I convert this to regular textarea that will act the same? I want this to work on browser that doesn't implemented "contenteditable". Therefore I want to replace the div with textarea or other basiv element. How can I do it? (I don't mind using JavaScript).
How can I disable the spellchecker? spellcheck=false doesn't work. In the example, when I focus on the text box, I get that buggy red line. I am using Firefox.
How can I get rid of the border when I am focused? - SOLVED
I don't mind using JavaScript to solve those issues.
Any answer for those questions will help me.
Thanks
UPDATES:
#Oylex helped me with 3
#1
Working fiddle is here: http://jsfiddle.net/d9H9w/11/ (tested in IE8, Chrome and Firefox)
What you need is to set the width and height attributes as a user is typing within a text box.
Height
This is pretty straightforward:
Get the content of the textarea
Match for newline characters
Set the height to total number of newline characters(plus one for the first line and 1.5 for wiggle room) in em's.
Setting the height in em's makes this font-size agnostic, so it'll work with multiple font-sizes.
function getNewlines(){
// get the value(text) of the textarea
var content = textEl.value;
//use regex to find all the newline characters
var newLines = content.match(/\n/g);
// use the count of newlines(+1 for the first line + 1 for a buffer)
// to set the height of the textarea.
textEl.style.height = ((newLines && newLines.length || 0)+2.5)+'em';
};
Width
This is fairly easy, too, with one gotcha.
Get the content of the textarea
Split on newline characters to get an array consisting of lines of the textarea
Sort to get the longest line
Set the width to the length of the longest string in em's, multiplied by about .6(emRatio in my code), plus 2 ems for buffer space.
That last part is the kicker. The 'em' measurement is supposed to be a square representing the width and height that a single character takes up. This doesn't take kerning into account, so the height of a char is usually accurate, but the width is dependent on the chars around it. So, by guess and check, I figured that .6 em is about the average width of a character after kerning. .6 is pretty close, so I add 2 ems to the width for a bit of buffer space.
var emRatio = .6;
function longestLine(){
// get the value(text) of the textarea
var content = textEl.value;
// split on newline's. this creates an array, where each item in
// the array is the text of one line
var a = content.split('\n');
// use a sorting function to order the items in the array:
// longest string to shortest string
a.sort(function(a,b){return b.length - a.length});
// use the longest string * the emRatio to set the width
// Due to kerning, the letters aren't ever really 1em x 1em
// So I'm multiplying by an approximate ratio here (guess and check)
textEl.style.width = (a[0].length * emRatio + 2)+ 'em';
};
Existing problems with this implementation
To support resizing during long-held key presses, an onkeydown handler has to be included as well(this is not optimal for all cases that don't include long key presses)
All things considered, I think this fits what you need.
EDITS
Instead of having emRatio be .7, I changed it to .6 and added a buffer of 2 ems to the width. This addresses both issues #Naor mentioned in his comments.
I've updated the fiddle link and the Width section to reflect the changes.
EDIT 0
Request #1 Update
Working Solution: http://jsfiddle.net/7aeU2/
JQuery
$(function() {
// changes mouse cursor when highlighting loawer right of box
$("textarea").mousemove(function(e) {
var myPos = $(this).offset();
myPos.bottom = $(this).offset().top + $(this).outerHeight();
myPos.right = $(this).offset().left + $(this).outerWidth();
if (myPos.bottom > e.pageY && e.pageY > myPos.bottom - 16 && myPos.right > e.pageX && e.pageX > myPos.right - 16) {
$(this).css({ cursor: "nw-resize" });
}
else {
$(this).css({ cursor: "" });
}
})
// the following simple make the textbox "Auto-Expand" as it is typed in
.keyup(function(e) {
// the following will help the text expand as typing takes place
while($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))) {
$(this).height($(this).height()+1);
};
});
});​
Request #2 Update
Also, here's a good explanation of why you can't outright disable spell check.
This does not belong to the realm of CSS (which is optional
presentational suggestions). It is not about stylistic features of
rendering data but about processing data interactively.
On browsers that support “spell checking” (which may involve grammar
and style checks), the HTML attribute spellcheck or the corresponding
IDL (DOM) attribute, settable in JavaScript, is effective.
In practice, those browsers tend to have “spelling checking” enabled
by default for textareas only, and as textareas normally contain human
language texts, turning it off does not sound useful. It is in any
case user-controllable (the user can switch it off or select
language).
via https://stackoverflow.com/a/9209791/1085891
Request #1
Simple Solution is pretty straight forward.
Working example: http://jsfiddle.net/b7rDL/12/
JQuery
$("#Solution0").keyup(function(e) {
while($(this).outerHeight() < this.scrollHeight) {
$(this).width($(this).width()+50);
};
});
HTML
<textarea id="Solution0" rows="1" style="height: 1.2em;"></textarea>
Fancier solution that will require some updating if you want the
width, rather than the height, to expand. Still, it's pretty nice.
http://jsfiddle.net/edelman/HrnHb/
https://github.com/ultimatedelman/autogrow
Other solutions - I know these all expand height. Let me know if you need width implementation of one of the below solutions.
http://bgrins.github.com/ExpandingTextareas/
http://blogs.sitepointstatic.com/examples/tech/textarea-expander/index.html
http://code.google.com/p/xautoresize-jquery/downloads/list
http://www.impressivewebs.com/textarea-auto-resize/
http://www.technoreply.com/autogrow-textarea-plugin-3-0/
Request #2
spellcheck="true" should work as described in the Mozilla docs: Controlling spell checking in HTML forms. It works for me in my first simple example running in Firefox 13.0.1. What version are you running?
for #3, the css option you are looking for is: outline: none;
I was having trouble figuring out the bounds of the textarea's content, so with this approach I'm copying the content of the textarea into a similarly styled p element, which is set to float: left; and then resizing the textarea based on the size of the p. This handles both width and height.
I've tested on Mac 10.8.1 FF 18.0, Safari 6.0, Chrome 25.0.1362.0 canary, iOS Safari 6.0.1 and iOS Simulator 5.1 (272.21). I don't have a PC or IE handy.
http://jsfiddle.net/b7rDL/34/
HTML
<textarea id="tx" class="text-block" spellcheck="false"></textarea>
<p id="dupe" class="text-block"></p>
CSS
.text-block {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
resize: none;
font-size:14px;
border: none;
line-height: 1;
min-width: 30px;
overflow: hidden;
white-space: pre;
display: block;
outline: none;
width: 30px;
height: auto;
border: 1px solid #ddd;
background-color: #f7f7f7;
}
#dupe {
float: left;
display: none;
width: auto;
height: auto;
}
I added a background and border so I could see what's going on.
JavaScript
// no `var` so they are global and easier to work
// with in the inspector when using jsFiddle
$tx = $('#tx');
$dupe = $('#dupe');
lineH = Number($tx.css('line-height').replace('px',''));
update();
$tx.on('keydown', function() {
setTimeout(update, 0);
});
$tx.on('propertychange input keyup change', update);
function update() {
$dupe.text($tx.val());
$tx.css({
width: $dupe.width() + 7,
height: $dupe.height() + lineH
});
}
// not sure if this is needed, leaving it because
// I don't have many browsers to test on
$tx.on('scroll', function() {
tx.scrollLeft = 0;
tx.scrollTop = 0;
});
I'm adding extra space on the right and at the bottom because it seems to perform more consistently that way. Also, in the HTML, the wrap="off" is necessary for the version of Firefox, I'm using.
I got some good tips from this blog post.
Request #2
Working Demo
<body spellcheck="false">
<div class="text-block" contenteditable="true">
Some Text SpellCheck</div>
Hi Naor, The only problem with this thing is it will disable the spellcheck for all the elements in the <body> tag. If it doesn't matter you then you can go with it.
Your question is really interesting and challenging really liked it. I hope this may help you..!!
Best efficient way which was worked for me while I did something very close in the past was creating hidden out of flow div with the same exactly styles as the textarea has. And than setting out the timeout to update its html source based on information from textarea. This sounds bit scary but yet, after some testing and playing around nothing was better, that was already suggested, so just my variant.
http://jsfiddle.net/f2gAD/16/
and jQuery based script:
var textarea = $('textarea'),
textBlock = $('div.text-block'),
interval, value, freq = 10,
doTextAreaAdjust = function(){
textarea.css({
height: textBlock.outerHeight(),
width: textBlock.outerWidth()
});
};
doTextAreaAdjust();
textarea
.focus(function(){
interval = window.setInterval(
function() {
value = textarea.val().replace(/(\r\n|\n|\r)/gm, '[rnnr]');
value = value.replace(/</gm, '||'); // break html tags
value = value.replace(/\[rnnr\]/gm, '<br>');
value = value + '|'; // or <span>|</span> for better pixel perfect
textBlock.html(value);
doTextAreaAdjust();
}, freq
);console.log(interval);
})
.blur(function(){
window.clearInterval(interval);
});
​
For performance wise did it as self starting/stopping timeout on focus/blur, though here is yet some workaround is required. While testing in Chrome noted that interval not properly stopped if you made blur by clicking on another tab. So probably replacement for self calling function into the setTimeout will be better.
It works more or less fine in IE 7-8 which suppose the main targets but still some text jumps time to time occur, while for others it is okay, but guess you will use editable feature for modern browsers. Would recommend use modernizer for its detection.
Working here
http://jsfiddle.net/H2GSx/
Code here:
HTML:
<div style="overflow: scroll; width: 200px; height: 100px;">
<div class="text-block" contenteditable="true" spellcheck="false">Some Text</div>
</div>​
CSS:
.text-block {
resize: none;
font-size:40px;
border: none;
line-height: 1;
-moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
min-width: 30px;
overflow: visible;
white-space: nowrap;
display: inline-block;
}
​

Categories