How to get Content Editable div width while writing text inside it? - javascript

I am working on a project of HTML and javascript. I have follwing code:-
<html>
<head>
<style type="text/css">
.mainDiv
{
border:1px solid black;
width:500px;
height:340px;
left:400px;
position: absolute;
}
.textOutsideDiv
{
border: 1px dashed black;
position: absolute;
display: none;
width:20px;
height: 20px;
}
.textInsideDiv {
position:absolute;
display:none;
background: none repeat scroll 0 0 transparent;
border: medium none;
font-family: Arial,Helvetica;
line-height: 1em;
margin: 0;
min-height: 1em;
min-width: 1px;
outline: medium none;
padding: 2px;
position: relative;
white-space: nowrap;
z-index: 2;
}
</style>
<script type="text/javascript">
function makeTextCanvas(e)
{
var mouseX=e.pageX-401;
var mouseY=e.pageY-9;
var existOrNot=document.getElementById('textOutsideDiv').style.display;
if(existOrNot=="" || existOrNot=="none")
{
var outerContainer=document.getElementById('textOutsideDiv');
var innerContainer=document.getElementById('textInsideDiv');
outerContainer.style.display='block';
outerContainer.style.left=mouseX+'px';
outerContainer.style.top=mouseY+'px';
innerContainer.style.display='block';
}
}
function makeDiv()
{
//alert("Write Inside");
var outerContainer=document.getElementById('textOutsideDiv');
var innerContainer=document.getElementById('textInsideDiv');
var h=innerContainer.offsetHeight;
outerContainer.style.height=h+'px';
}
</script>
</head>
<body>
<div id="mainDiv" class="mainDiv" onclick="makeTextCanvas(event);">
<div id="textOutsideDiv" class="textOutsideDiv">
<div id="textInsideDiv" class="textInsideDiv" contenteditable="true" onkeyup="makeDiv();" style="font-size: 1em; color: rgb(0, 170, 0);"></div>
</div>
</div>
</body>
</html>
On changing content inside div, i am increasing outerContainer div's height but i am facing a problem in getting width of Content Editable div. How can i solve this problem?

First of all you say that you want to get width of the inner div, but actually you are trying to get innerContainer.offsetHeight. Second, adding text to an element that has its width set to auto does not stretch it if its parent element has fixed width.
If I understood correctly what you were trying to achieve, you want to expand your pseudo-textbox while the user is typing. Here is how you can expand it: http://jsfiddle.net/LwCWM/1/ , but there should be a better way of getting width of the text since non-monospace fonts have letters of various widths.

Related

Hover state does not work when applying z-index

The problem is I have 2 divs: one container a link and another a box shaped container. The link has a position:fixed; and it flies over the container div, so I tried to give the link a z-index with a negative value, turns out the
hover state does not work when applying z-index with a negative value for the anchor Unless I scroll the same amount of the height of the container div. So I scroll like 3 times and the hover state works again.
HTML
<div id="div-1">
<div class="container"></div>
</div>
<!-- other divs like 5 or 6 of 'em -->
<div id="div-2">
This is a link
</div>
CSS
#div-2 a{
width:13%;
height:auto;
padding:0.5em 2.3em;
display:block;
position:fixed;
font-weight:500;
font-size:1.09em;
text-align: center;
background-color: none;
text-decoration:none;
outline:none;
z-index:0;
}
#div-1{
width:100%;
height:290px;
overflow-y:auto;
overflow-x: hidden;
box-sizing: border-box;
display: block;
}
an important thing is:
The container is hidden by Jquery, unless I click a certain button.
$(document).ready(function(){
$(".container").hide();
$("#button-f").click(function(e){
$(".container").toggle();
var target = $(e.target);
if (!target.is("##button-f")) {
$(".container").toggle();
}
});
});
I have resorted to every possible (other ideas) I could think of. I tried to do the opposite meaning giving the container a z-index positive vales and leave the anchor, but that leaves the same problem
update
I will try to change the css property "z-index"but only when the the container button is toggled on
so the link will have z-index:-9; but only when the container is toggled to be viewed and when it is toggled back off the z-index will be removed or not applied.
I can't really figure how this will be written with jquery I tried this
$(document).ready(function(){
$(".container").hide();
$("#button-f").click(function(e){
$(".container").toggle();
$("#div-2 a").css("z-index", -9);
var target = $(e.target);
if (!target.is("##button-f")) {
$(".container").toggle();
}
});
});
this only result when I toggled the container on the z-index will be applied, but when i toggle it of it remains, how to remove the z-index or make it equal to z-inedx:99; when the container is toggled off?
Only any other answer for the problem is appreciated.
It's not clear what you want exactly, but the pics helped, although it appears that you want the link above the container, it looks as if you don't?
the whole purpose is to make the anchor in a lower index, so when the container is toggled on/ viewed, the link won't be setting on top of the container.
But you want the link to always react when hovered upon. So I assume that you can't figure out why it's not hovering when the container is open and you can still see the link, so logically you'd expect to at least be able to hover over the visible portion of the link.
It's not jQuery and it's not the .container. It's the .container's container A.K.A. #div-1. #div-1 width is always 100% and even if you didn't have that style, it would be 100% still because that's what blocks have if there isn't an explicit width assigned to it.
Solution: Give #div-1 a smaller width.
You have a fixed link yet no coords. You can't expect a fixed element to stand it's ground and behave like a fixed element if it doesn't know where to stand. Also if you have any positioned elements and you want interaction between other elements, make those elements positioned as well, div-1 is now position:relative and the z-index properties of the link and div-1 function correctly now.
Solution: Give #div-2 a top and left or right and bottom properties. Give #div-1 a position property so that the z-index functions properly.
All details are commented in the source.
PLUNKER
SNIPPET
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<style>
html,
body {
height: 100%;
width: 100%;
}
#div-1 {
overflow-y: auto;
overflow-x: hidden;
box-sizing: border-box;
position: relative;
z-index: 1;
border: 1px solid red;
width: 200px;
/*Enable this and it will block link*/
/*width:100%;*/
height: 290px;
}
.container {
/* This saves you an unnecessary step in jQuery */
display: none;
width: 200px;
height: 290px;
background: orange;
}
#div-2 a {
width: 13%;
height: auto;
padding: 0.5em 2.3em;
display: block;
position: fixed;
font-weight: 500;
font-size: 1.09em;
text-align: center;
background-color: none;
text-decoration: none;
outline: none;
/* It's not clear whether you want the link above or
| below the container. If above, simply change to
| z-index: 2
*/
z-index: 0;
/* If you have a fixed element give it coords, otherwise
| it doesn't know where it should stand and behavior
| will be unexpected.
*/
top: 10%;
left: 125px;
}
#div-2 a:hover {
background: red;
color: white;
}
/* FLAG is just to test the accessibility of the link */
#FLAG {
display: none;
}
#FLAG:target {
display: block;
font-size: 48px;
color: red;
}
</style>
</head>
<body>
<button id='button-f'>F</button>
<div id="div-1">
<div class="container">Container is open</div>
</div>
<!-- other divs like 5 or 6 of 'em -->
<div id="div-2">
This is a link
<span id='FLAG'>This link is accessible now!</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script>
/* This is the jQuery you need to accomplish what you want.
| The rest was redundant and unnecessary.
*/
$(document).ready(function() {
$("#button-f").click(function(e) {
$(".container").toggle();
});
});
</script>
</body>
</html>
Have you tried assigning a z-index to #div-2?
You'll need to assign it a position to be able to give it a z-index. Try this:
#div-2 a{
width:13%;
height:auto;
padding:0.5em 2.3em;
display:block;
position:fixed;
font-weight:500;
font-size:1.09em;
text-align: center;
background-color: none;
text-decoration:none;
outline:none;
z-index:2;
}
#div-1{
width:100%;
height:290px;
overflow-y:auto;
overflow-x: hidden;
box-sizing: border-box;
display: block;
position: relative;
z-index:1;
}
I don't know what actually in your code but the js you provide look at the if section you have (##button-f) so we find an error here and do we actually need this line ??like we also don't need the line 'container'.hide() in JS. Now you have to scroll for the 'a' certain height because yous set height for #div-1 which is not hidden. So that's amount of height you have to scroll.
So What I change on your code
1. cut the height of div-1 and place it to .container class. you dont provide the a:hover class so I add that to and remove some unnecessary css you have. If you have any other Question ask me in comment LIVE ON FIDDLE
$(document).ready(function() {
$("#button-f").click(function() {
$(".container").toggle();
});
});
button {
width: 13%;
height: auto;
}
#div-1{
width:100%;
overflow-y:auto;
overflow-x: hidden;
box-sizing: border-box;
display: block;
}
.container {
height:290px;
display:none;
border: 1px solid red;
}
#div-2 a {
width: 13%;
height: auto;
padding: 0.5em 2.3em;
display: block;
positon:fixed;
float:right;
font-weight: 500;
font-size: 1.09em;
text-align: center;
text-decoration: none;
border-radius: 10px;
}
#div-2 a:hover {
background: black;
color: white;
}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<body>
<button id="button-f">
button
</button>
<div id="div-1">
<div class="container">tagasdgasdgasdgas</div>
</div>
<!-- other divs like 5 or 6 of 'em -->
<div id="div-2">
<a href='#'>This is a link</a>
</div>
</body>

jquery ui draggable restricting div to up and down drag within containment

I have been learning Javascript lately. As an exercise I wanted to create a Dominoes board. I am trying to drag a tile around the board. The approach I took is to create a tile within the board and set it to draggable with jquery ui.
However, somehow the drag is confined to up and down movement only. Why is that??
Html:
<div id="board">
<div id="tile_1-0" >
<div class="dominoe"> </div>
</div>
</div>
css:
.dominoe {
/* Dominoe shape */
position: relative;
height:60px;
width:30px;
background-color:white;
border: 2px solid black;
/* Rounded Corners */
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
padding:2px;
}
#board {
margin: auto;
width: 200px;
height: 200px;
background-color: #0A9D2D;
}
javascript:
$( "#tile_1-0" ).draggable({containment:'#board'});
Please take a look at the embedded fiddle:
https://jsfiddle.net/totoorozco/t5nnd95j/
Because the div it's in takes up the full width of the 'board'. Fix that by setting the display of that div to inline-block:
#tile_1-0 {
display: inline-block;
}
jsFiddle example
add this to your css:
#tile_1-0{
position: absolute;
}

Modify pseudo-element :after's width using javascript [duplicate]

This question already has answers here:
Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)
(26 answers)
Closed 5 years ago.
Markup:
<h1 class="title">Hello World</h1>
CSS:
.title {
border-bottom: 3px solid #aaa;
position: relative;
}
.title:after {
content: "";
width: 100px;
border-bottom: 3px solid red;
display: block;
position: absolute;
}
Demo: http://codepen.io/anon/pen/HDBqe
I wanted to change the .title:after's width based on the text's width, how do I change :after's width using javascript?
$.fn.textWidth = function(){
var html_org = $(this).html();
var html_calc = '<span>' + html_org + '</span>';
$(this).html(html_calc);
var width = $(this).find('span:first').width();
$(this).html(html_org);
return width;
};
$('.title').each(function(){
// Change :after's width based on the text's width
// .css('width', $(this).textWidth());
});
I've found a trick which works in this case. I've updated your demo:
http://codepen.io/anon/pen/bHLtk
.title {
border-bottom: 3px solid #aaa;
position: relative;
min-width: 100%;
}
.title:after {
content: "";
width: inherit;
border-bottom: 3px solid red;
display: block;
position: absolute;
}
Notice, that .title:after has width set to inherit but his parent (.title) has overridden width with min-width. Now I can freely to set width by JavaScript to title and it take effect only on his nested pseudoelement:
$('.title').each(function(){
$(this).css('width', $(this).textWidth());
});
A pseudo-element is not part of the DOM. Therefore, you cannot change its CSS properties directly through JS.
In order to get your desired effect the way you want it, my best guess would be YUI.StyleSheet and manipulate the stylesheet itself, although I have to admit I haven't tested it myself in recent years.
Including such a utility and doing all of this calculation seems like a lot of work for width matching.
If you are willing to compromise a little bit on the semantic HTML, there is a working technique:
Your element takes the entire width of the screen. Wrapping the text with a span and adding the pseudo-element to that, as an inline-block should allow you to get the border under the text only
HTML:
<h1 class="title"><span>Hello World</span></h1>
CSS:
.title {
border-bottom: 3px solid #aaa;
position: relative;
}
.title span{
display:inline-block;
position:relative;
}
.title span:after {
content: "";
width: 100%;
border-bottom: 3px solid red;
display: block;
position: absolute;
}
Here is my version of the codePen.
For future reference:
There is a W3C Candidate Recommendation that suggests the capability of using attributes for CSS properties other than content.
This way, if and when the recommendation is approved and implemented, it might be possible to have the pseudo-element reflect the parent's attributes, as such:
this.setAttribute("length", $(this).textWidth());
And the relevant CSS:
.title:after {
...
width: attr(length px);
...
}
How's this for a different approach.... http://jsfiddle.net/mayYt/
Added CSS
.title span {
border-bottom: 3px solid red;
}
JQuery
$('.title').wrapInner('<span />');
With just a simple trick any pseudo-element can be changed (or at least replaced with something else):
$('.something').click(function(){
$(this).toggleClass('to_show');
});
.something
{
background: red;
height: 40px;
width: 120px;
position: relative;
}
.something.to_show:after
{
content: "X";
color: white;
background: green;
width: 20px;
height: 20px;
position: absolute;
right: 0px;
top: 0px;
display: block;
text-align: center;
}
.something:after
{
content: "O";
color: white;
background: blue;
width: 30px;
height: 25px;
position: absolute;
right: 0px;
top: 0px;
display: block;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<div class="something">
click here!
</div>
</body>
</html>

Vertically center div with Javascript (variable height)

I'm trying to vertically center a div with Javascript. Because the text is going to be changing, I cannot use a fixed height.
I'd like to do this without Jquery.
#box2 {
width: 100%;
height: 100%;
position:relative;
background-color: orange;
}
#informationBox {
padding: 0.5em;
background-color: #fff;
border-radius: 12pt;
border: solid black 3pt;
max-width: 683px;
margin: 0 auto;
text-align: center;
}
Javascript:
var container = document.getElementById("#box2");
var inner = document.getElementById("#informationBox");
var inHeight = inner.offsetHeight;
container.style.height=(window.innerHeight);
container.style.width=window.innerWidth;
var conHeight=container.offsetHeight;
inner.style.marginTop=((conHeight-inHeight)/2);
Any help would be great :)
http://jsfiddle.net/tmyie/EttZQ/
You pretty much have it, you just need to change a couple things. First, getElementById takes just an id-string, not a selector. Secondly, you need to add 'px' to your style declration.
var container = document.getElementById("box2");
var inner = document.getElementById("informationBox");
var inHeight = inner.offsetHeight;
container.style.height = window.innerHeight;
container.style.width = window.innerWidth;
var conHeight = container.offsetHeight;
inner.style.marginTop = ((conHeight-inHeight)/2)+'px';
Here's an updated fiddle: http://jsfiddle.net/EttZQ/1/
Using js with line-height property.
less javascript, and precise centering.
box/info can have min/max-width/height & % or px ...
also resizes with the window.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>center</title>
<style>
html,body{
width:100%;
height:100%;
margin:0;
padding:0;
}
#box{
width:100%;
height:100%;
text-align:center;
}
#info{
display:inline-block;
margin:0;padding:0 16px;
line-height:24px;
border-radius: 12pt;
border: solid black 3pt;
text-align: center;
vertical-align:middle;
box-sizing: border-box;
}
</style>
<script>
var center=function(){
var b=document.getElementById('box');
b.style['line-height']=b.offsetHeight+'px';
}
window.onload=center;
window.onresize=center;
</script>
</head>
<body>
<div id="box"><div id="info">center me pls<br>test</div></div>
</body>
</html>
One simple CSS solution.
http://jsfiddle.net/antouank/EttZQ/2/
body {
margin: 0;
}
#box2 {
width: 100%;
height: 100%;
position:absolute;
background-color: orange;
}
#informationBox {
padding: 0.5em;
background-color: #fff;
border-radius: 12pt;
border: solid black 3pt;
max-width: 100px;
margin: 0 auto;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
}
You only need to calculate the width/height of your element, and change 50% to whatever you need to center it.
Make container pos anything other than static.
Box : pos absolute. top:50%
When box height changes, set margin top of box to -1 * height/2.

Width absorbing HTML elements

Im trying to think how to do this with html elements.
There is nothing special about the colors, so I don't need to make them images.
Do note that the text is right aligned. Also, the color bar goes up to the text from the left.
So this could be implemented by having the text float right with background color white, and a div with the background color set right next to it (and then a clear).
Or instead of floats, I can do text align-right and get a similar effect.
Here is the kicker.
I'm using a javascript library (shouldn't matter which one) to create an animation. The animation is the bars shrink to the left, and end up like so:
The problem with the float or text-align methods are that too many values have to be changed to transition between the two states. The javascript animation effects tend to want to change a couple predefined values, like width or font-size. In order to transfer from picture 1 to picture 2 using the float or text-align methods, I must remove the floating/text-align then set the width of the bar color, but that doesn't work if I want to keep the javascript overhead minimal for such a simple task.
I've tried absolute positioning/widths, but I can't get anything to make the text right aligned AND have the bars meet at the same point on the left.
I'm hoping maybe I'm just blind of a simple solution, but as I see it, I need one element that has the text positioned to the right somehow, and an element that takes up as much room possible beside it for the color... AND the element that has the color should be able to take a width, while having the text follow beside it.
Thank you.
Here's my attempt. Note: to the horror of some anti-table zealots this does use tables. Floats just can't do "take up all available space" like tables can.
<html>
<head>
<style type="text/css">
table { width: 300px; background: #DDD; empty-cells: show; }
th { padding-left: 8px; width: 100%; height: 1em; }
td { padding-left: 12px; width: auto; }
div { white-space: nowrap; }
#row1 th { background: red; }
#row2 th { background: blue; }
#row3 th { background: green; }
#row4 th { background: yellow; }
#row5 th { background: pink; }
#row6 th { background: gray; }
</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.3.2");
google.setOnLoadCallback(function() {
$(function() {
$("th").animate({ width: 0 }, 2000);
});
});
</script>
</head>
<body>
<table><tr id="row1"><th></th><td><div>FOO</div></td></tr></table>
<table><tr id="row2"><th></th><td><div>BAR</div></td></tr></table>
<table><tr id="row3"><th></th><td><div>THESE PRETZELS ARE</div></td></tr></table>
<table><tr id="row4"><th></th><td><div>MAKING ME THIRSTY</div></td></tr></table>
<table><tr id="row5"><th></th><td><div>BLAH</div></td></tr></table>
<table><tr id="row6"><th></th><td><div>BLAH</div></td></tr></table>
</body>
</html>
I thought of a non-tables way of doing it that works pretty well, so here it is:
<html>
<head>
<style type="text/css">
div div { height: 1.3em; }
#wrapper { width: 300px; overflow: hidden; }
div.text { float: right; white-space: nowrap; clear: both; background: white; padding-left: 12px; text-align: left; }
#row1, #row2, #row3, #row4, #row5, #row6 { width: 270px; margin-bottom: 4px; }
#row1 { background: red; }
#row2 { background: blue; }
#row3 { background: green; }
#row4 { background: yellow; }
#row5 { background: pink; }
#row6 { background: gray; }
</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.3.2");
google.setOnLoadCallback(function() {
$(function() {
$("div.text").animate({ width: "90%" }, 2000);
});
});
</script>
</head>
<body>
<div id="wrapper">
<div class="text">FOO</div><div id="row1"></div>
<div class="text">BAR</div><div id="row2"></div>
<div class="text">THESE PRETZELS ARE</div><div id="row3"></div>
<div class="text">MAKING ME THIRSTY</div><div id="row4"></div>
<div class="text">BLAH</div><div id="row5"></div>
<div class="text">BLAH</div><div id="row6"></div>
</div>
</body>
</html>
This is tested and it works perfectly (no stupid tables and very simple CSS/jQuery):
<style type="text/css">
.crazy_slider { display:block; height:25px; width:500px; clear:both; position:relative; z-index:0; text-decoration:none; }
.crazy_slider_text { position:absolute; right:0px; top:0px; height:100%; background-color:white; color:#666; font-size:1em; display:block; text-align:left; z-index:1px; padding-left:10px; }
#red { background-color:red; }
#blue { background-color:blue; }
#green { background-color:green; }
#yellow { background-color:yellow; }
#pink { background-color:pink; }
#grey { background-color:grey; }
</style>
<script type="text/javascript">
$(function() {
$('.crazy_slider').hover(
function() {
var bar_width = $(this).width();
var $crazy_slider_text = $(this).children('.crazy_slider_text');
if($crazy_slider_text.data('original_width') == null || $crazy_slider_text.data('original_width') == undefined || !$crazy_slider_text.data('original_width')) {
var original_width = $crazy_slider_text.width();
$crazy_slider_text.data('original_width',original_width);
}
$crazy_slider_text.stop().animate({width:95+'%'},500);
},
function() {
var $crazy_slider_text = $(this).children('.crazy_slider_text');
var text_width = $crazy_slider_text.data('original_width');
$crazy_slider_text.stop().animate({width:text_width+"px"},500);
}
);
});
</script>
<div class="crazy_slider_text">FOO</div>
<div class="crazy_slider_text">BAR</div>
<div class="crazy_slider_text">BAZ</div>
<div class="crazy_slider_text">FOOBAR</div>
<div class="crazy_slider_text">FOOBARBAZ</div>
<div class="crazy_slider_text">BAZAGAIN</div>
Edit:
I was assuming you were tying to make some kind of navigation elements with these so I added the mouse interaction logic. In any case, it might be useful, haha?
Second Edit:
I've changed the code to be more efficient and more predictable... if anyone cares. ;)
Do the coloured bars need to be a particular width, or just fill the space between the words on the right and the origin on the left? Assuming that my assumption's correct:
<style>
#container {width: 50%;
margin: 0 auto;
}
span {width: 100%;
display: block;
text-align: right;
margin: 0.2em 0;
}
span p {text-align: right;
background-color: #fff;
color: #333;
display: inline-block;
padding: 0 0 0 0.4em;
line-height: 1.4em;
font-weight: bold;
}
span#foo {background-color: #f00;
}
span#bar {background-color: #0f0;
}
span#foobar {background-color: #00f;
}
</style>
<div id="container">
<span id="foo">
<p>foo</p>
</span>
<span id="bar">
<p>bar</p>
</span>
<span id="foobar">
<p>foobar</p>
</span>
</div>
Working demo: http://davidrhysthomas.co.uk/so/colouredfoobars.html

Categories