I am learning how to write object oriented javascript. I have a simple class to create div elements, but when I test the code no new elements are created. Am I doing this correctly? I am using the following code:
function elementCreation(elementParent, elementId, elementText) {
this.elementParent = document.getElementsByTagName(elementParent)[0];
this.elementId = elementId;
this.elementHtml = elementText;
this.elementMake = function (type) {
newElement = document.createElement(type);
// add new element to the dom
this.elementParent.appendChild(newElement);
};
}
var newObject = new elementCreation('body', 'testdiv', 'some text here!!!');
newObject.elementMake('div');
Your code works perfectly, congratulations.
You simply can't see an empty div without styling.
See here a demonstration with styling :
div {
width:100px;
height:100px;
background-color:red;
}
Note that if your construction parameters were intended for the construction of the child element, you have to put them to some use. For example :
function elementCreation(elementParent, elementId, elementText) {
this.elementParent = document.getElementsByTagName(elementParent)[0];
this.elementId = elementId;
this.elementHtml = elementText;
this.elementMake = function (type) {
newElement = document.createElement(type);
// add new element to the dom
this.elementParent.appendChild(newElement);
newElement.innerHTML = elementText;
};
}
Demonstration
I won't try to use the elementId parameter : if you define a function, it's probably to call it more than once and an id can't be used more than once in HTML.
The div is being created but you aren't setting it's content as your third argument elementText.
newElement = document.createElement(type);
newElement.innerHTML = this.elementHtml; // <-- set its content
newElement.id = this.elementId; // <-- set the ID
// add new element to the dom
this.elementParent.appendChild(newElement);
Added compatibility with firefox when setting text content, then associated the id attribute to the new element. I also tried another approach that could be easier to complexify.
What about:
function elementCreation(args) {
this.parent = args.parent;
this.id = args.id;
this.text = args.text;
this.make = function(type) {
var el = document.createElement(type);
el.id = this.id;
// firefox do not support innerText, some others do not support textContent
if (typeof el.innerText != "undefined") {
el.innerText = this.text;
} else {
el.textContent = this.text;
}
this.parent.appendChild(el);
}
}
new elementCreation({
parent: document.body,
id: 'div1',
text: 'some text here!!!'
}).make('div');
You can try it with this jsfiddle.
Related
Can you target new instances of an object uniquely without passing them an id as a parameter?
If you create new objects from a constructor and each instance has access to some html (presentation) stored as a variable in the constructor, when new instances of the object are created and html is output from the presentation variable, how do you target each of these instances in a unique way? How could you style one instance differently from the other?
function MyObj() {
this.content = "<div class = 'someclass'>Some text </div>";
}
var newObj1 = new MyObj();
console.log(newObj1.content); //outputs Some text
var newObj2 = new MyObj();
console.log(newObj2.content); //outputs Some text
If you wanted to target the css of all new classes you could use:
var target1 = $('.someclass').css('color,'orange');
But how to target one differently from the other?
You can pass in something that is unique to acknowledge each object. Below I pass in a name to be added to the elements class attribute.
Note if you are using the CSS elsewhere then this is fine, but if it's just used once then why not add an id to distinguish the areas uniquely. That is, that is what an id is meant for.
function MyObj(name) {
if(name != undefined) {
this.content = "<div class = 'default " + name + "'>Some text </div>";
} else {
this.content = "<div class = 'default'>Some text </div>";
}
}
var newObj1 = new MyObj('blue-rows');
console.log(newObj1.content); //outputs Some text
var newObj2 = new MyObj('orange-rows');
console.log(newObj2.content); //outputs Some text
var newObj3 = new MyObj();
console.log(newObj3.content); //outputs Some text
var container = document.getElementById('container');
container.innerHTML += newObj1.content;
container.innerHTML += newObj2.content;
container.innerHTML += newObj3.content;
.default {
color: red;
}
.blue-rows {
color: blue;
}
.orange-rows {
color: orange;
}
<div id="container">
</div>
That depends on how you'd like to target the other instance. One option is to use the :nth-child, :first-child, or :last-child selectors. As an example:
$('.someclass:nth-child(even)').css('color','orange');
$('.someclass:nth-child(odd)').css('color','blue');
$('.someclass:nth-child(1)').css('color','green');
$('.someclass:first-child').css('color','red');
What would be the shortest way to do the following :
var div = document.createElement('div');
div.className = 'divClass';
div.innerHTML = 'Div Content';
... without any external libraries
class Div {
constructor(className, innerHTML) {
let div = document.createElement("div");
div.className = className;
div.innerHTML = innerHTML;
return div;
}
}
let innerHTML = "LOL"
new Div(divClass, innerHTML);
This would be the shortest way to doing it again and again while still having some order inside your code, IMO.
Write a function to do it in one line:
function tag(tagNameAndClass, innerHTML) {
var parts = (tagNameAndClass || 'div').split(/\./g);
var elem = document.createElement(parts.shift());
elem.className = parts.join(' ');
if (innerHTML) elem.innerHTML = innerHTML;
return elem;
}
Examples of uses:
tag('div.divClass', 'Div Content') // <div class="divClass">Div Content</div>
tag('.class-one.class-two', 'Content') // <div class="class-one class-two">Content</div>
tag('h1.super', 'My Super Heading') // <h1 class="super">My Super Heading</h1>
What would be the shortest way to do the following [...]
We can imagine a situation in which the div already exists in the DOM while the CSS style rule display:none ensures it remains absent from the visible document flow.
The following single line in javascript will make the element reappear into the visible document flow:
document.getElementsByClassName('divClass')[0].style.display = 'block';
Probably the best solution I have came up with so far :
var el = function(type,props,appends){
var el = document.createElement(type);
if(props) for(var x in props) el[x] = props[x];
if(appends) for(var x in appends) el.appendChild(appends[x]);
return el;
}
and then when using it (creating a popup with header and body example) :
$title = el('div',{className:'title',innerHTML:'Item Title'});
$remove = el('div',{className:'remove',innerHTML:'X'});
$header = el('div',{className:'header'},[$title,$remove,el('div',{className:'clear'})]);
$body = el('div',{className:'body',innerHTML:'body'});
$el = el('div',{className:'item'},[$header,$body]);
<!DOCTYPE html>
<html><body>
<p id="intro">Hello <em id="abcd">intro</em> World!</p>
<script type="text/javascript">
var txt=document.getElementById("intro").innerHTML;
var el = document.createElement("span");
el.innerHTML = txt;
var aa = el.getElementById("abcd").innerHTML;
alert( aa );
</script>
</body></html>
The above is a simple snippet. Actually I have an HTML editor and when the user saves the data I should save only the required content. Here I am getting the content of an element and manipulating it with DOM and pass the details to the server. This way I will not change the page content (user view remains the same) and he/she will continue editing the document.
The above is a simple example but in the real case I have to remove, change and move certain elements. The above code fails el.getElementById("abcd").innerHTML. Appreciate any pointers.
You can create a hidden iframe to manipulate all your changes, thus creating a separate DOM, then simply pull back the results you want.
var iframe;
if (document.createElement && (iframe = document.createElement('iframe'))) {
iframe.name = iframe.id = "externalDocument";
iframe.className = "hidden";
document.body.appendChild(iframe);
var externalDocument;
if (iframe.contentDocument) {
externalDocument = iframe.contentDocument;
} else if (iframe.contentWindow) {
externalDocument = iframe.contentWindow.document;
}
else if (window.frames[iframe.name]) {
externalDocument = window.frames[iframe.name].document;
}
if (externalDocument) {
externalDocument.open();
externalDocument.write('<html><body><\/body><\/html>');
externalDocument.close();
/* Run your manipulations here */
var txt = document.getElementById("intro").innerHTML;
var el = document.createElement("span");
el.innerHTML = txt;
/* Attach your objects to the externalDocument */
externalDocument.body.appendChild(el);
/* Reference the externalDocument to manipulate */
var aa = externalDocument.getElementById("abcd").innerHTML;
alert(aa);
}
/* Completed manipulation - Remove iFrame */
document.removeChild(iframe);
}
I have it working here:
http://jsfiddle.net/ucpvP/
Try using jQuery like given below.
function SaveData() //Your add function
{
var txt=$("#intro").html();
$(document).append("<span id='abcd'>" + txt+ "</span>");
var aa = $("#abcd").hmtl();
alert(aa);
}
You can use a DOM Element that is never appended to the DOM.
I use this 'cleanup' function:
function cleanup(str){
var tester = document.createElement('div'),
invalid, result;
tester.innerHTML = str;
//elements I don't allow
invalid = tester.querySelectorAll('script,object,iframe,style,hr,canvas');
// the cleanup (remove unwanted elements)
for (var i=0;i<invalid.length;(i+=1)){
invalid[i].parentNode.removeChild(invalid[i]);
}
result = tester.innerHTML;
tester = invalid = null;
//diacritics to html-encoded
return result.replace(/[\u0080-\u024F]/g,
function(a) {return '&#'+a.charCodeAt(0)+';';}
)
.replace(/%/g,'%25');
}
//usage:
cleanup(document.getElementById("intro").innerHTML);
You can extend the function with your own code to remove, change and move certain elements.
I'm trying to modify this code to also give this div item an ID, however I have not found anything on google, and idName does not work. I read something about append, however it seems pretty complicated for a task that seems pretty simple, so is there an alternative? Thanks :)
g=document.createElement('div'); g.className='tclose'; g.v=0;
You should use the .setAttribute() method:
g = document.createElement('div');
g.setAttribute("id", "Div1");
You can use g.id = 'desiredId' from your example to set the id of the element you've created.
var g = document.createElement('div');
g.id = 'someId';
You can use Element.setAttribute
Examples:
g.setAttribute("id","yourId")
g.setAttribute("class","tclose")
Here's my function for doing this better:
function createElement(element, attribute, inner) {
if (typeof(element) === "undefined") {
return false;
}
if (typeof(inner) === "undefined") {
inner = "";
}
var el = document.createElement(element);
if (typeof(attribute) === 'object') {
for (var key in attribute) {
el.setAttribute(key, attribute[key]);
}
}
if (!Array.isArray(inner)) {
inner = [inner];
}
for (var k = 0; k < inner.length; k++) {
if (inner[k].tagName) {
el.appendChild(inner[k]);
} else {
el.appendChild(document.createTextNode(inner[k]));
}
}
return el;
}
Example 1:
createElement("div");
will return this:
<div></div>
Example 2:
createElement("a",{"href":"http://google.com","style":"color:#FFF;background:#333;"},"google");`
will return this:
google
Example 3:
var google = createElement("a",{"href":"http://google.com"},"google"),
youtube = createElement("a",{"href":"http://youtube.com"},"youtube"),
facebook = createElement("a",{"href":"http://facebook.com"},"facebook"),
links_conteiner = createElement("div",{"id":"links"},[google,youtube,facebook]);
will return this:
<div id="links">
google
youtube
facebook
</div>
You can create new elements and set attribute(s) and append child(s)
createElement("tag",{attr:val,attr:val},[element1,"some text",element2,element3,"or some text again :)"]);
There is no limit for attr or child element(s)
Why not do this with jQuery?
var newDiv= $('<div/>', { id: 'foo', class: 'tclose'})
var element = document.createElement('tagname');
element.className= "classname";
element.id= "id";
try this you want.
that is simple, just to make a new element with an id :
var myCreatedElement = document.createElement("div");
var myContainer = document.getElementById("container");
//setAttribute() is used to create attributes or change it:
myCreatedElement.setAttribute("id","myId");
//here you add the element you created using appendChild()
myContainer.appendChild(myCreatedElement);
that is all
I'm not sure if you are trying to set an ID so you can style it in CSS but if that's the case what you can also try:
var g = document.createElement('div');
g.className= "g";
and that will name your div so you can target it.
window.addEventListener('DOMContentLoaded', (event) => {
var g = document.createElement('div');
g.setAttribute("id", "google_translate_elementMobile");
document.querySelector('Selector will here').appendChild(g);
});
What will be the dojo equivalent code of following.?
var msgContainer = document.createElement('div');
msgContainer.id = 'alert'; // set id of div
msgContainer.setAttribute('role', 'alert');
msgContainer.className = 'contenthide' // set class name
msgContainer.appendChild(document.createTextNode(msg));
document.body.appendChild(msgContainer);
var div = dojo.byId('alert');
while (div) {
div.parentNode.removeChild(div);
div = dojo.byId('alert');
}
var msgContainer = dojo.create("div", {
id:"alert",
role:"alert",
"class":"contenthide",
innerText:msg }, dojo.body());
Please check on the Dojo Toolkit's documentation for more DOM functions.