I am trying to make a function that creates divs containing text and puts them in another div called "history".
The problem is that the text in the divs come out as single lines like this
2/2=1
instead of this
2/2
=1
It may also be caused by the height limitation of the div, if so how do I automatically adjust the size with javascript.
function creatediv() {
var element = document.createElement("div");
var doc = "2/2" + "\n" + "=1";
const es = element.style;
element.appendChild(document.createTextNode(doc));
document.getElementById('history').appendChild(element);
es.backgroundColor = "azure";
es.margin = "3px"
es.borderRadius = "5px";
es.padding = "2px"
}
Use the CSS property white-space: pre which makes line-breaks (and other whitespace) inside HTML #text nodes visible.
white-space is exposed in the DOM as CSSStyleDeclaration.whiteSpace.
Values are set as normal strings, e.g. 'pre' or 'normal'.
e.g.: document.getElementById('abc123').style.whiteSpace = 'pre';
You don't need element.appendChild(document.createTextNode(doc));, you can set .textContent directly.
Like so (click "Run code snippet"):
function createDiv() {
const div = document.createElement("div");
div.textContent = "2/2\n=1";
const s = div.style;
s.backgroundColor = "azure";
s.margin = "3px";
s.borderRadius = "5px";
s.padding = "2px";
s.whiteSpace = 'pre'; // <-- Right here.
document.getElementById('history').appendChild( div );
}
<button type="button" onclick="createDiv()">Create DIV</button>
<div id="history" style="border: 3px inset #999"></div>
Related
I'm attempting to create a text element and then add CSS attributes
I've tried to use the code below
function create(text){
var t = document.createTextNode(text);
t.style.color = "black"
t.style.backgroundColor="white"
t.style.borderRadius="20px"
t.style.border="4px solid black"
document.body.appendChild(t);
}
create("hello");
I expect to create a text with a white background and 20px border radius with a 4px solid black border
Instead of a text node, which I don't think you can add styles to, just use a span instead
function create(text){
var t = document.createElement("span");
t.innerText = text;
t.style.color = "black"
t.style.backgroundColor="white"
t.style.borderRadius="20px"
t.style.border="4px solid black"
document.body.appendChild(t);
}
create("hello");
You are having trouble because text nodes are not meant to be styled.
You should create a DOM element instead. I took your code and update it in order to create a <p> (the nearest element of text node I guess) with your CSS:
function create(text) {
var t = document.createElement('p');
t.innerText = text;
t.style.color = "black"
t.style.backgroundColor="white"
t.style.borderRadius="20px"
t.style.border="4px solid black"
document.body.appendChild(t);
}
create("hello");
You are on the right direction. The only thing you need to do is change document.createTextNode(text) with:
var t = document.createElement('span');
t.innerText = text;
\\...
document.body.appendChild(t);
The reason why your code doesn't work is that you can only style HTML tags, and the the text node you created only contains the string you added, without a surrounding tag.
For example:
<span>
hello
</span>
is a tag with some text with it, while the hello text in the middle is a TextNode.
Hope this makes sense.
Reference:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode
I've managed to create a huge div that contains many small divs appended to it, so it creates a grid. My goal is to be able to store two variables within each of the smaller divs (tiles). Currently, I'm able to store one value within the smaller tiles by changing the innerHTML, however, I would like to be able to store more than just that one value.
The following is my code to create the tiles:
var id = 0; // variable for generating unique id for divs
var x = 0; //default value within each tile
function cdiv(ele) {
var div = document.createElement("div");
div.innerHTML = 'div' + id;
div.id = 'div' + id++; // det unique id and increment id value
div.style.width = "50px";
div.style.height = "50px";
div.style.background = "red"; //default color of tile
div.style.color = "black"; //color of value within tile
div.style.display = "inline-block"; //some amount of tiles per line
div.addEventListener("click", clr);
div.innerHTML = x; //this is what shows inside each tile
ele.appendChild(div); //adds this tile to an element
}
//my master container
var div = document.createElement("div");
div.style.width = "500px"; ///10 times of inner divs
div.style["overflow-x"]= "visible"; // to show overflow
document.body.appendChild(div);
//following function generates my grid within the above master container
for (i = 0; i < 10; i++) {
for (b = 0; b < 10; b++) {
cdiv(div);
}
}
//following function increments the value inside the tile per click
function clr(e) {
var clickedElement = document.getElementById(e.currentTarget.id);
var currentXValue = clickedElement.innerHTML;
clickedElement.style.background = "green";
currentXValue++
clickedElement.innerHTML = currentXValue;
}
How can I add variables to the tiles (divs within the large container div), so that I can later call that variable and pass it onto another div to display?
I would like to have the following three variables:
The number of clicks on the current clicked tile, as I have in my
code above, except not to display within that tile. Merely, store it
as a value for that tile in some variable
X-coordinate of the tile clicked on
Y-coordinate of the tile clicked on
you can create infinite data-[whatever] attributes to store any variables you'd like
you can then access this variable with element.getAttribute('data-example-name');
here's an example:
var testElement = document.getElementsByClassName('test')[0];
var result = document.getElementById('result');
result.textContent = testElement.getAttribute('data-my-tag');
.test {
background: blue;
color: white;
padding: 20px 30px;
width: 300px;
text-align: center;
}
<div class="test" data-my-tag="5">
<h2>testing a made-up attribute, <br>
data-my-tag =
<span id="result">{should be a number}</span>
</h2>
</div>
same code via jsfiddle
I can think of two ways to store information with each div:
(1) Storing a hidden <input type="hidden" value="something" /> file in the div
(2) Adding the data-something="Some information" attribute to the div. Code would look like:
div.dataset.something = "Some information to pass along";
Here's more information on (2):
Set data attribute using JavaScript
https://developer.mozilla.org/en/docs/Web/Guide/HTML/Using_data_attributes
https://www.sitepoint.com/use-html5-data-attributes/
The data attribute can be used with many HTML tags, including <img data-desc="Photo of a dog" />
Actually, you can add any property (or even function) to your element. Like if you have a div variable for your element, you can do just
div.someProperty = someValue;
div.myFunction = function(...) { ... };
The only thing you should care about is not to overwrite some "system" property like style and others.
I wonder if there's any way to get the JS code of an existing HTML element using any existing method. I am trying to print the code generator of any DOM element, so when the user clicks on any HTML element of the webpage, a message will be shown with the source code to create that element in Javascript.
For example, I have a Div created:
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";
And then I was trying to obtain the source code, but:
document.body.appendChild(div.innerHTML);
This option only writes the textual content: "I'm the div". SO I tryed:
document.body.appendChild(div.outerHTML);
But it writes the HTML code without the onmouseover function: "I'm the div"
What I really need is to show this code (or something similar):
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";
http://jsfiddle.net/x2zJs/
Do you have any idea where can I start reading?
Thanks a lot,
outerHTML
outerHTML is a good choice with several limitations:
today (2014) you can't get attached listeners natively
outerHTML uses html node serialization, which uses uses xml attributes serialization algorithm
In other words, IDL attributes are ignored, only content attributes are serialized.
Events by IDL attributes are coded as
div.onmouseover=function(){div.style.color = "red"};
div.addEventListener("mouseover",function() {div.style.backgroundColor="blue";});
See more about events
Whereas events by content attributes are coded as
div.setAttribute("onmouseover","this.style.color='red'");
Using content attribute, the outerHTML looks like this:
<div onmouseover="this.style.color='red'" style="border: 1px dotted red;">
I'm the div
</div>
See your updated fiddle.
Long story short, there are two ways to code a handler:
var setColor = function(e) { e.target.style.color = "red"; }
div.onmouseover = setColor; // IDL, not seen by outerHTML
div.setAttribute("onmouseover","setColor(event)"); // content, seen by outerHTML
eventListenerList
If you want to retrieve the IDL events somehow, nice proposed eventListenerList property was removed from DOM3 spec proposal (see here).
If you want to write a firefox addon (something like code inspector), extending the Element.prototype will do the trick (as I tested, it works in Firefox, Chrome and Opera, it doesn't work in IE7):
(function() {
Element.prototype.eventListenerList = {};
Element.prototype._addEventListener = Element.prototype.addEventListener;
Element.prototype.addEventListener = function(a,b,c) {
this._addEventListener(a,b,c);
if(!this.eventListenerList[a]) this.eventListenerList[a] = [];
this.eventListenerList[a].push(b);
};
})();
To be precise, you should also override the Element.prototype.removeEventListener to remove the event from the custom EventListenerList.
Now you can add the events by addEventListener as usual:
function handlerA() { alert('a'); }
function handlerB() { alert('b'); }
function handlerC() { alert('c'); }
// attach handlers
div.onclick = handlerC;
div.addEventListener("click",handlerA);
div.addEventListener("click",handlerB);
...and to display the code of the listeners. I will do this for onclick event, in your code you should iterate through every possible event. Don't forget the eventual onclick listener (you can't override Element.prototype.onclick because it is non-configurable property):
var clickListeners = "";
if(div.eventListenerList.click)
div.eventListenerList.click.forEach(function(f) {
clickListeners+= f.toString();
});
if(div.onclick) clickListeners+= div.onclick.toString();
alert(clickListeners);
See and test the fiddle. Put these pieces together as it suits to your addon.
There is nothing built-in that will give you what you want, try the "aardvark bookmarklet" it has a somewhat nice js generating command.
http://karmatics.com/aardvark/bookmarklet.html
Well, you could wrap the creation of your div element with a function and then parse and print contents of that function.
Following is a working example (tested in Chrome, Firefox and Safari):
Also here http://jsfiddle.net/smnh/x2zJs/2/
function createDiv() {
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover = function() {div.style.color = "red"};
div.innerHTML = "I'm the div";
div.creationString = getFunctionContnet(createDiv); // noprint
return div; // noprint
}
function getFunctionContnet(func) {
var regExp = /function[^(]*\([^)]*\)[^{]*{(?:\s*\n)?(\s*)([\s\S]*)(?:\n\s*)}/,
match,
indention, indentionRE,
noprintRE = /\/\/.*noprint.*/,
content = null,
lines, i;
match = regExp.exec(func.toString());
if (match !== null) {
indention = match[1];
content = match[2];
lines = content.split("\n");
// if first line of the function is indented,
// remove that indention from all function lines.
if (typeof indention !== "undefined") {
indentionRE = new RegExp("^" + indention);
for (i = 0; i < lines.length; i++) {
if (indentionRE.test(lines[i])) {
lines[i] = lines[i].substr(indention.length);
}
}
}
// don't print lines with "// noprint"
for (i = lines.length - 1; i >= 0; i--) {
if (noprintRE.test(lines[i])) {
lines.splice(i, 1);
}
}
content = lines.join("\n");
}
return content;
}
Here if you create your div and log the creationString you will get the text of the function.
div = createDiv();
console.log(div.creationString);
If you have control over the creation of the elements you could ensure that each element is created in it's own separate function. Then a simple function can get the function body.
function createElement1() {
var div = document.createElement("div");
div.style.border = "1px dotted red";
div.onmouseover=function(){div.style.color = "red"};
div.innerHTML = "I'm the div";
}
function getFunctionBody(func) {
var functionText = func.toString();
return functionText.slice(functionText.indexOf("{") + 1, functionText.lastIndexOf("}"));
}
Here's a working example. http://jsfiddle.net/C5b7n/
So... I want to add the following right before the /body of a document, I can't seem to find a way to make it work:
document.body.innerHTML+="<div style=\"position:absolute; right:-10px; bottom:10px;\">response</div>\"");
Especially with the <body> element, you shouldn't be using innerHTML to append elements to an element. An easier way is with DOM methods like createElement, insertBefore or appendChild.
https://developer.mozilla.org/en-US/docs/DOM/document.createElement
https://developer.mozilla.org/en-US/docs/DOM/Node.insertBefore
https://developer.mozilla.org/en-US/docs/DOM/Node.appendChild
Try this:
var div = document.createElement("div");
div.style.position = "absolute";
div.style.right = "-10px";
div.style.bottom = "10px";
div.innerHTML = "response";
var lastChild = document.body.lastChild;
document.body.insertBefore(div, lastChild.nextSibling);
Although I guess it would make sense to just append it to the body:
document.body.appendChild(div);
(instead of the last two lines in my first example)
It also depends on when you're calling this code. Of course it will work if executed in the middle of the <body>, but you probably want to wait until the body (DOM) is ready so that the element is actually appended at the real end of the body. By using something like:
window.onload = function () {
// Your code from above
};
This will make sure the original <body> contents are ready.
Don't add stuff like that! Instead, do this:
var newDiv = document.createElement('div')
newDiv.style.position = 'absolute'
newDiv.id = 'myDiv'
newDiv.innerHTML = 'hello'
//etc.
document.body.appendChild(newDiv)
Change code to
document.body.innerHTML="<div style=\"position:absolute; right:-10px; bottom:10px;\">response</div>\"";
Remove ) at the end
What about:
var div = document.createElement("div");
// it's better use a CSS here instead
div.style.position = "absolute";
div.style.right = "-10px";
div.style.bottom = "10px";
div.innerHTML = "response";
document.body.appendChild(div);
?
I'm using JavaScript to dynamically generate a dialogue box (it's a div element), containing a textbox and a submit button. I plan on submitting the value in the textbox to another page using AJAX.
My problem is that I can generate my textbox just fine, but I can't get the value from it. innerHTML comes back blank every time. I'm not sure what I'm doing wrong.
// Generate dialogue box using div
function create_div_dynamic()
{
//Create the div element
dv = document.createElement('div');
//unique tags
var unique_div_id = 'mydiv' + Math.random() * .3245;
var unique_textbox_id = 'mytext' + Math.random() * .3245;
//Set div id
dv.setAttribute('id',unique_div_id);
//Set div style
dv.style.position = 'absolute';
dv.style.left = '100 px';
dv.style.top = '100 px';
dv.style.width = '500px';
dv.style.height = '100px';
dv.style.padding = '7px';
dv.style.backgroundColor = '#fdfdf1';
dv.style.border = '1px solid #CCCCCC';
dv.style.fontFamily = 'Trebuchet MS';
dv.style.fontSize = '13px';
//Create textbox element
txt = document.createElement('input');
txt.setAttribute('id',unique_textbox_id);
txt.setAttribute('type','text');
txt.style.marginRight = '10px';
//Add textbox element to div
dv.appendChild(txt)
//Add the div to the document
document.body.appendChild(dv);
dv.innerHTML += '<input type="button" id="mysubmit" value="Read Textbox" onclick="javascript:alert(\'' + document.getElementById(unique_textbox_id).innerHTML + '\');" />';
}
Textarea elements don't have an innerHTML property. Just read the value property like you would with any other form element.
document.getElementById(unique_textbox_id).value
The input type="text" fields have no innerHTML, they are usually represented as self-closing tags.
Use the value attribute instead:
document.getElementById(unique_textbox_id).value
I have to create the div element, add it to the document, and THEN add the children (textbox and submit button).
No, you don't in general have to do that. What was causing your problem was this:
...'onclick="javascript:alert(\'' + document.getElementById(unique_textbox_id).innerHTML + '\');" />';
That access to document.getElementById().innerHTML is occurring at the time you create the string, that is during the execution of create_div_dynamic(), not when the button is pressed. At that point, the field has just been created and has no .value. (It also has no .innerHTML, but then it never will as it's an input element.)
Your revised code uses a proper JavaScript function which is called at onclick time, and fixes the property to value, so that's OK. This approach also doesn't die when there are apostrophes or backslashes in the value string.
dv.innerHTML += '<input ...
This serialises all the content in ‘dv’ to HTML text, then adds the string, and parses all the HTML back into DOM objects. This is really inefficient, and in the process you lose all JavaScript properties on the object, including event handlers and listeners.
“innerHTML+=” is always a mistake. Never use it.
txt.setAttribute('id',unique_textbox_id);
Don't use setAttribute(), it doesn't work for certain attributes under IE. Instead use the more readable DOM-HTML properties:
txt.type= 'text';
txt.id= unique_textbox_id;
For others in my boat, I want to show the solution. It turns out that I was adding elements in the wrong order.
I have to create the div element, add it to the document, and THEN add the children (textbox and submit button).
//DIV
dv = document.createElement('div');
dv.setAttribute('id',unique_div_id);
dv.style.position = 'absolute';
dv.style.left = xx + 'px';
dv.style.top = yy + 'px';
dv.style.width = '500px';
dv.style.height = '20px';
dv.style.padding = '7px';
dv.style.backgroundColor = '#fdfdf1';
dv.style.border = '1px solid #CCCCCC';
dv.style.fontFamily = 'Trebuchet MS';
dv.style.fontSize = '13px';
//Add div element to body
document.body.appendChild(dv);
//TEXTBOX
txt = document.createElement('input');
txt.setAttribute('id',unique_textbox_id);
txt.setAttribute('type','text');
txt.style.marginRight = '10px';
//Add textbox to div element
document.getElementById('mydiv').appendChild(txt);
var sbt = document.createElement('input');
sbt.setAttribute('id','mysubmit');
sbt.setAttribute('type','submit');
sbt.setAttribute('value','GO');
sbt.onclick = function() { alert(document.getElementById('mytext').value); };
//Add submit to div element
document.getElementById('mydiv').appendChild(sbt);
Once this is done, and I use the .value, all goes well.
$cid =$_REQUEST['cid'];
$name =addslashes($_REQUEST['name']);
$email =$_REQUEST['email'];
$comments =$_REQUEST['comments'];
$comment_type=$_REQUEST['type'];
$gstatus =(isset($_REQUEST['gstatus'])) ? $_REQUEST['gstatus'] : 'no';
$user_type =(!empty($_SESSION['user_id'])) ? 'author' : 'user';