Change width of contenteditable div by chuncks based on text - javascript

I'm trying to change the width of a div based on the content of the div:
Lets say initially the div has a width of 100px, I want it to remain at that width until the user has filled up 90px with text.
When this arrive the width of the div should be incremented by a fixed value. if the user writes even more (190px) the div will again have its width incremented.
I tried using the clientWidth of the div like this:
get style(): string {
if (!this.el) {
return `
width: 100px;
line-height: ${DEFAULT_HEIGHT}px;
max-height: inherit;
`;
}
let divWidth = 100;
const maxWidth = window.innerWidth - SCROLLBAR_WIDTH;
while (this.el.clientWidth > divWidth * 0.9 && divWidth < maxWidth) {
const width = width + 100
if (width > maxWidth) {
break;
}
divWidth = width;
}
return `
width: ${divWidth}px;
line-height: ${DEFAULT_HEIGHT}px;
max-height: inherit;
`;
}
but it does compare the width of the div with itself and not the content of the div.
Thanks in advance,

You can relate to this answer to get the content width: https://stackoverflow.com/a/47224153/12933115
My recommendation is that you use two nested DIVs like this:
<div id="container">
<div id="content"></div>
</div>
<input id="txtBox" />
The div#container would have a fixed size, whereas the div#content wouldn't.
#container {
width: 100px;
}
#content {
max-width: fit-content;
max-width: -moz-fit-content; /* For Mozilla Firefox */
}
Now, you detect the typing instead of the width. Then, you check the width of the inner DIV within the event listener.
const input = document.getElementById("txtBox");
input.addEventListener("input", () => {
// Check the width of the inner DIV (#content) here...
// If the width of the inner width exceeds your limit, then you change the width
// of the container DIV (#container).
});
The above was a general explanation. You'll figure out how to apply this according to your needs.

Related

getting the width of a specific element that it actually uses

I have an application, that takes html as input, renders an image and saves it. It also requires the user to specify the width and height that the image should be. I want to automate the height and width part so the user wouldn't need to set it up manually
The Problem:
if the html is as simple as <p>text</p> the height is pretty easy to find by using clientHeight but the width will be the whole width of the viewport and most of it would be absolutely unneeded to show text, so the picture would be very narrow (height = 16px; width = 1080px) and that is not great.
The Question:
is there any way to find the width of an element that it actually uses? (for instance width required by <p>text</p> would be closer to 16px but not 1080px)
You are having this error because elements such as <p> and <div> will extend the entire width of the parent by default. You should use width: fit-content to stop that.
div {
background-color: blue;
}
p {
background-color: red;
}
.width {
width: fit-content;
}
<div>This is a DIV with width: auto</div>
<p>This is a P with width: auto</p>
<div class="width">This is a DIV with width: fit-content</div>
<p class="width">This is a P with width: fit-content</p>
clientHeight will return the height for the entire window. You should focus on just the parent of the elements you want to render to get a better reading. Use offsetWidth and offsetHeight to get the full width of the parent.
var div = document.getElementById('div');
div.innerHTML = 'Width: ' + div.offsetWidth + '<br>Height: ' + div.offsetHeight;
.square {
width: 100px;
height: 100px;
background-color: blue;
}
<div id="div" class="square"></div>

jQuery CSS method update on resize?

After struggling to vertically centre a div inside the body element using the "conventional" methods, I've decided to create a small jQuery function that figures out how far from the top an element needs to be to be "centred".
It works like this:
Get container height,
Get child height,
"top" = "(container.height - child.height) / 2"
Set margin top of child to the value of "top".
For example if the body had a width and height of 1000px and this body had a div.inner child that had a width and height of 400px the margin-top of div.inner would be 300px because (1000-400) / 2 = 300.
Here is a diagram to further explain what I mean:
NOTE: X represents the margin-top of the div.inner (as I didn't have enough space for "Margin Top = ").
To my amazement this actually works!!! Here is the test code:
// set the margin top for ".vertical-centre" elements
$(".vertical-centre").each(function() {
// set the margin-top for the child
$(this).css("margin-top", function() {
// NOTE: margin = (container.height - child.height) / 2
var margin = ($(this).parent().height() - $(this).height()) / 2;
// default the margin to zero if it's a negative number
// round the margin down to the nearest whole number
// specify that the margin-top is in pixels
return Math.floor(Math.max(0, margin)) + "px";
});
});
body {
width: 100px;
height: 100px;
margin: 0;
padding: 0;
border: 1px solid black
}
div.inner {
width: 40px;
height: 40px;
background-color: blue
}
.horizontal-centre {
display: block;
margin-left: auto;
margin-right: auto
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="inner horizontal-centre vertical-centre"></div>
NOTE: I made the example above smaller so you could see it properly.
Unfortunately though, there is now another problem, when I resize the browser the margin-top of the div.inner element stays the same.
I would like for it to be responsive and update it's margin-top property to the appropriate value when the window has been resized otherwise div.inner will go out of view and the page will look a like this:
You could use https://api.jquery.com/resize/
Create a function of your code
function init_center() {..
Try calling the init_center function from the resize event of window
SNIPPET
function init_center() {
// set the margin top for ".vertical-centre" elements
$(".vertical-centre").each(function() {
// set the margin-top for the child
$(this).css("margin-top", function() {
// NOTE: margin = (container.height - child.height) / 2
var margin = ($(this).parent().height() - $(this).height()) / 2;
// default the margin to zero if it's a negative number
// round the margin down to the nearest whole number
// specify that the margin-top is in pixels
return Math.floor(Math.max(0, margin)) + "px";
});
});
}
$( window ).resize(init_center); // Handle resize of window
init_center(); // Doing it first time
body {
width: 400px;
height: 400px;
margin: 0;
padding: 0;
border: 1px solid black
}
div.inner {
width: 200px;
height: 200px;
background-color: blue
}
.horizontal-centre {
display: block;
margin-left: auto;
margin-right: auto
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="inner horizontal-centre vertical-centre"></div>
Wrap you code in a function
function align() {
$(".vertical-centre").each(function() {
// set the margin-top for the child
$(this).css("margin-top", function() {
// NOTE: margin = (container.height - child.height) / 2
var margin = ($(this).parent().height() - $(this).height()) / 2;
// default the margin to zero if it's a negative number
// round the margin down to the nearest whole number
// specify that the margin-top is in pixels
return Math.floor(Math.max(0, margin)) + "px";
});
});
}
And run it on window resize as well
align(); // first run
$(window).on('resize', align); // when window resize

How to get the height and width of window in bootstrap

In bootstrap I have a fixed top nav bar and fixed bottom nav bar. I want to show a large image in the background between the space of those two nav bars and I also want to cover the width of the window. How can I dynamically get the height between the navbars and the width of the window? The window size may change depending on device.So I need it dynamic
Requires jquery:
var viewport = {
width : $(window).width(),
height : $(window).height()
};
//can access dimensions like this:
//viewport.height
Though you won't always get perfect results, different devices behave differently and this gives the viewport dimensions, not the screen dimensions.
Alternatively you could check the width of a data-role="page" element to find the device-width (since it's set to 100% of the device-width):
var deviceWidth = 0;
$(window).bind('resize', function () {
deviceWidth = $('[data-role="page"]').first().width();
}).trigger('resize');​​​
$(window).resize(function() {
var top_nav_height = $("#id_of_top_nav").height();
var bottom_nav_height = $("#id_of_bottom_nav").height();
var window_height = $(window).height();
var height_of_open_space = window_height - (top_nav_height+bottom_nav_height);
$("#id_of_img").css({
height:height_of_open_space+'px';
});
});
this will be fine with if 0px padding and margin, if not also get that values and subtract from height_of_open_space before applying to img height
It is a bit hard to tell without seeing any of your markup, but it should be feasable with pure css. I set up a very basic example to demonstrate:
http://codepen.io/anon/pen/XbGJJO
HTML:
<div class='top'>
top navbar
</div>
<div class='content'>
<p> some content </p>
</div>
<div class='bottom'>
bottom navbar
</div>
CSS:
.top, .bottom {
height: 40px;
background: red;
position: fixed;
width: 100%;
}
.top {
top: 0;
}
.bottom {
bottom: 0;
}
.content {
margin: 40px 0;
min-height: calc(100vh - 80px);
background: green; /* background goes here */
}
The trick lies in the following line:
min-height: calc(100vh - 80px);
This tells your content to at least take up 100% of the vertical height, minus the height of the top and bottom bar. Let me know if you want me to explain further.

Get height of a division tag in jQuery

My division tag with id "container" has the following style
<style>
#container {
background: #000;
width: 100%;
height: 100%;
}
</style>
I am retrieving the height and width as follows
var WIDTH = $("#container").width();
var HEIGHT = $("#container").height();
this height and width is required by me to set up my view in WEBGL.
Am getting the width correct but height() returns 0. Initially I thought am not populating my division tag with any data before I get height and width, may be that's the reason why height() returns 0 but if that is the case how am I getting width() correct?
If I set my width and height in terms of pixels they work fine, but the problem is I want to be accurate when the webpage is being viewed on different screens.
You should use html,body{height: 100%;} then only it works. Otherwise you could apply your div to be position absolute then only works.
#container {
background: #000;
width: 100%;
height: 100%;
position: absolute;
}
And to place where the div is wrap it with a div and apply position to relative.
You have to include or write something into the div. When there is no content in the div how can it give the height of the div?
Try out the demo http://jsfiddle.net/T8D7V/
$(document).ready(function(){
var w=$('#container').css('width');
var h=$('#container').css('height');
alert(" height"+h+" width"+w);
});
I hope you wanted to achieve this....
The is calculated with respect to the height of the containing block. If the height of the containing block is not specified explicitly, the value computes to auto.
so if the containing block of #container did not has an explicit height.
the height of #container will be the height of its content
if the the containing block of #container is set explicit such as 100px
the height of #container will calculate with the value (100px in this example)
http://jsfiddle.net/PL595/ i have some example here
mdn : https://developer.mozilla.org/en-US/docs/Web/CSS/height
it should be:
var WIDTH = $("#container").css('width').replace('px','');
var HEIGHT = $("#container").css('height').replace('px','');
Or
var WIDTH = document.getElementById('container').offsetWidth;
var HEIGHT = document.getElementById('container').offsetHeight;

Animation for the automatic height change when content is resized with javascript

I want to control the automatic height change of the container when I add something that changes the lenght of the content. Right now, if I apply a innerHTML change on the content, the height is changed accordingly. I want to apply a transition to that height change. How can I do that? ( I can also use jQuery )
Record the height before changing the content, change the content, record the height after, set the height to the former height, and animate to the latter height. When the animation has completed, set the height to be automatic again. You can do this using height and animate.
Try it on JSFiddle.
var texts = [
"This is just some sample text that's being used to demonstrate animating the height when content changes.",
"Shorter."
];
var div = $('div').click(changeContent);
function changeContent() {
var oldHeight = div.height();
texts.push(div.text());
div.text(texts.shift());
var newHeight = div.height();
div.height(oldHeight);
div.animate({height: newHeight}, 'fast', function() {
div.height('auto');
});
}
div {
width: 150px;
background: lightgray;
overflow-y: hidden;
}
<div>This is some example content.</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="containter" style="overflow:hidden">
<div>
Content.....
</div>
</div>
//add something...
$('#container').animate({height:$('#container').content().outerHeight()});
or:
$('#container').animate({height:$('#container').children().first().outerHeight()});
and when adding append to the div inside the containter:
$('#container').children().first().append(somethingNew);
Based on icktoofay's answer.
I make the button disabled while changing the height and add a fading effect. This solution is useful for updating of the products filter and so on.
Also I check the box-sizing property. If it's box-sizing then I get newHeight by .outerHeigth() instead of .height() to prevent the height fluctuation when new content has the same height. You can check this situation, for example by setting the random variable to value 5. The reason is that
.height() will always return the content height, regardless of the value of the CSS box-sizing property.
CodePen
$('#button').click(function() {
var $button = $(this),
buttonOriginalText = $button.html();
$button.prop('disabled', true).html('Updating...');
$('#content').animate({
opacity: 0
}, 'fast', function() {
var newHeight,
$content = $(this),
oldHeight = $content.height();
$content.html(getRandomContent());
newHeight = ('border-box' === $content.css('box-sizing') ? $content.outerHeight() : $content.height());
$content.height(oldHeight).animate({
height: newHeight,
opacity: 1
}, 'slow', function() {
$content.height('auto');
$button.prop('disabled', false).html(buttonOriginalText);
});
});
});
function getRandomContent() {
var random = 1 + Math.round(Math.random() * 11), // 1..12
paragraph = '<p>Paragraph</p>';
return paragraph.repeat(random);
}
* {
box-sizing: border-box; /* comment out to test "content-box" */
font: 16px Helvetica, 'sans-serif';
}
.content {
counter-reset: content;
padding: 6px 18px;
}
.content p {
counter-increment: content;
}
.content p:after {
content: ' ' counter(content) '.';
}
.content-box {
border: 2px solid red;
margin-top: 24px;
max-width: 220px;
}
<button id="button" class="button">Update the content</button>
<div class="content-box">
<div id="content" class="content">Animatie the automatic height when content is resized.</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

Categories