I have this simple function:
var x = document.createTextNode("ERROR");
document.body.appendChild(x);
So then I need to create an IF to verify if this message exist [If this message has been created]. This is the problem, I don't know how to do that.
GetElementByID seems to don't work with element created by dynamically.
Any help? Thanks.
You can use document.contains to check if a element is in the DOM
Just a quick example of how it works
document.contains($('<div>')[0]); // FALSE
And
document.contains($('<div>').appendTo('body')[0]); // TRUE
jQuery only used for a shorthand to element creation
This also works for text nodes and you can use contains on any node.
document.body.contains(Node); // Example
The browser support is somewhat very good
Documentation: https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
Question specifics:
var x = document.createTextNode("ERROR");
document.body.appendChild(x);
document.contains(x); // Should be TRUE
You are creating a text node, not an element. You need to create an element and give it an id to be able to use getElementById.
I don't know of any reasonable way to search for a text node, although you could always check the text nodes of the element you attached it to and see if it's there.
var message = "ERROR";
var t = document.createTextNode(message);
var node = document.getElementById('content').appendChild(t);
if (document.getElementById('content').innerHTML !== message) {
console.log('element not added');
} else {
console.log('element added');
}
Here is a fiddle:
http://jsfiddle.net/btipling/rBg4w/
I believe this would work:
var x = document.createTextNode("ERROR");
var element = document.body.appendChild(x); //returns text node
if(!element){
//element was not added
}
although if I were you I might create a span element with an id or a class called error. This way you can apply any css styles to it.
Try this:
var x = document.createTextNode("ERROR");
document.body.appendChild(x);
if (document.body.innerText.indexOf('ERROR')>=0){
alert('"ERROR" found');
}
indexOf doesn't work in all browsers.
As #slowpython said I'd rather create a DOM element with ID or NAME.
Related
I have an element E and I'm appending some elements to it. All of a sudden, I find out that the next element to append should be the first child of E. What's the trick, how to do it? Method unshift doesn't work because E is an object, not array.
Long way would be to iterate through E's children and to move'em key++, but I'm sure that there is a prettier way.
var eElement; // some E DOM instance
var newFirstElement; //element which should be first in E
eElement.insertBefore(newFirstElement, eElement.firstChild);
2018 version - prepend
parent.prepend(newChild) // [newChild, child1, child2]
This is modern JS! It is more readable than previous options. It is currently available in Chrome, FF, and Opera.
The equivalent for adding to the end is append, replacing the old appendChild
parent.append(newChild) // [child1, child2, newChild]
Advanced usage
You can pass multiple values (or use spread operator ...).
Any string value will be added as a text element.
Examples:
parent.prepend(newChild, "foo") // [newChild, "foo", child1, child2]
const list = ["bar", newChild]
parent.append(...list, "fizz") // [child1, child2, "bar", newChild, "fizz"]
Related DOM methods
Read More - child.before and child.after
Read More - child.replaceWith
Mozilla Documentation
Can I Use
2017 version
You can use
targetElement.insertAdjacentElement('afterbegin', newFirstElement)
From MDN :
The insertAdjacentElement() method inserts a given element node at a given position relative to the element it is invoked upon.
position
A DOMString representing the position relative to the element; must be one of the following strings:
beforebegin: Before the element itself.
afterbegin: Just inside the element, before its first child.
beforeend: Just inside the element, after its last child.
afterend: After the element itself.
element
The element to be inserted into the tree.
In the family of insertAdjacent there is the sibling methods:
element.insertAdjacentHTML('afterbegin','htmlText')`
That can inject html string directly, like innerHTML but without override everything, so you can use it as a mini-template Engin and jump the oppressive process of document.createElement and even build a whole component with string manipulation process
element.insertAdjacentText for inject sanitize string into element . no more encode/decode
You can implement it directly i all your window html elements.
Like this :
HTMLElement.prototype.appendFirst = function(childNode) {
if (this.firstChild) {
this.insertBefore(childNode, this.firstChild);
}
else {
this.appendChild(childNode);
}
};
Accepted answer refactored into a function:
function prependChild(parentEle, newFirstChildEle) {
parentEle.insertBefore(newFirstChildEle, parentEle.firstChild)
}
Unless I have misunderstood:
$("e").prepend("<yourelem>Text</yourelem>");
Or
$("<yourelem>Text</yourelem>").prependTo("e");
Although it sounds like from your description that there is some condition attached, so
if (SomeCondition){
$("e").prepend("<yourelem>Text</yourelem>");
}
else{
$("e").append("<yourelem>Text</yourelem>");
}
I think you're looking for the .prepend function in jQuery. Example code:
$("#E").prepend("<p>Code goes here, yo!</p>");
I created this prototype to prepend elements to parent element.
Node.prototype.prependChild = function (child: Node) {
this.insertBefore(child, this.firstChild);
return this;
};
var newItem = document.createElement("LI"); // Create a <li> node
var textnode = document.createTextNode("Water"); // Create a text node
newItem.appendChild(textnode); // Append the text to <li>
var list = document.getElementById("myList"); // Get the <ul> element to insert a new node
list.insertBefore(newItem, list.childNodes[0]); // Insert <li> before the first child of <ul>
https://www.w3schools.com/jsref/met_node_insertbefore.asp
I am trying to Get First Child with classname Plain Javascript.
I am trying to write my own form validation and trying the error message i appended and remove it. As well as dont append if error message is already there.
If you help me with just the first part getting child with class name that whould be great.
function display_error(selector, message) {
selector.insertAdjacentHTML('afterend', "<h1 class='js-error' >" + message + "</h1>");
}
function validateForm() {
// Validate Name Field
// Check if name has les than 3
var elem = document.getElementById("name")
if (elem.value.length < 3) {
display_error(elem, "Less than 3")
return false;
} else {
// here is the error
error_label = elem.querySelector('.js-error');
error_label.textContent = "more than 3"
}
}
here is a fiddle
https://jsfiddle.net/efh941cc/3/
The beautiful thing about document.querySelector() is that you can use CSS selectors rather than the, often clunky, DOM API.
CSS provides a very simple selector called first-child which does exactly what you need.
// Find the first element that uses the .test class that is a child of another element.
var firstTest = document.querySelector(".test:first-child");
// Now that you've scanned and found the element and stored a reference to it
// in a variable, you can access any aspect of the element.
console.log(firstTest.textContent);
firstTest.innerHTML = "<span>Now, I have completely different content than before!</span>";
// Now, we can get a reference to other elements that are relative to the last
// one we found.
var firstTestError = document.querySelector(".test:first-child + .error");
firstTestError.style.backgroundColor = "aqua";
firstTestError.innerHTML = "<span>Required</span>";
<div>
<span class="test">one</span><span class="error"></span>
<div class="test">two</div>
<div class="test">three</div>
</div>
In modern JavaScript, to get the first child with a class name, you can use the following:
document.querySelector('element.class:first-child')
Here, you supply the actual element, and the actual class name.
document.querySelector is available in all modern browsers, and will take any string which matches a CSS selector. It even works in IE8, though the :first-child pseudo class is not available there.
const GetFirstChild = document.querySelector(' .PlainJavascript');
I have this in jQuery:
$(document).bind("click touchstart", function(e) {
if (e.target.class != searchControls && !searchControls.find(e.target).length) {
//do something
});
});
What this does is checks the click and if it's not the search element a child of that element, then I can run something. What I'm trying to do is find a pure JavaScript alternative to this.
So far I have:
var searchTrigger = document.querySelector(".header__search-btn"),
productSearch = document.querySelector(".product-search"),
searchControls = document.querySelectorAll(".product-search__positioner");
document.onclick = function (e) {
if (e.target.class != searchControls && e.parentNode != searchControls)
// do something
}
}
However this still fires my function inside the if statement, so clearly I'm going wrong—not sure how wrong. Help appreciated.
document.querySelectorAll returns a collection of DOM elements. e.target.class != searchControls doesn't make sense (ignoring that target.class doesn't even exist): Assuming you mean className, you are trying to compare a string with a list of DOM elements. That will always be false.
So lets ignore that part and look at e.parentNode != searchControls. The event object doesn't have a property parentNode. Again, even if you meant e.target.parentNode, it would not make much sense, since you are testing whether a single element is identical to a list of elements.
Based in your use of .find, you basically want to know whether a node is contained in another node. Every DOM node has a method .contains, so all you have to do is iterate over the collection of DOM elements and call that method:
var contained = false;
for (var i = 0; i < searchControls.length; i++) {
if (searchControls[i].contains(e.target)) {
contained = true;
break;
}
}
This can easily be moved into its own reusable function.
There is no e.target.class. If you are checking for class name then it should be
e.target.className
Then to check for parent elements class name
e.target.parentNode.className
if you are looking to search inside the parent node then use
e.target.parentNode.querySelector("pass your selector here")
if you want to search for just child elements:
e.target.querySelector("pass your selector here")
I am dynamically creating an unordered list and adding items to it on a click of a button. I append this to a section that has contenteditable attribute set true. However, I do not see it working. I did set the contenteditable attribute to true even for the list but I guess it is supposed to inherit that from the section it is appended to. Here is the code of what I am doing.
// create text input
var categoryInput = document.createElement('input')
// create button to add the text entered to a list
var btnAddToList = document.createElement('input');
btnAddToList.type ="button";
//create a section to add a list to
var section = document.createElement('section');
var ul=document.createElement('ul');
section.appendChild(ul);
section.contenteditable = "true";
ul.contenteditable = "true";
//create an event handler to add to the list
if (btnAddToList.addEventListener) { btnAddToList.addEventListener('click', function () { addToList(ul, categoryInput.value);});
} else if (btnAddToList.attachEvent) {
btnAddToList.addEvent('click', function () { addToList(ul, categoryInput.value);});
Here is the function I call
function addToList(unorderedlist, inputText) {
if(inputText.length == 0) {
alert("Add Text");
return;
}
var listitem = document.createElement('li');
var listvalue = document.createTextNode(inputText);
listitem.appendChild(listvalue);
unorderedlist.appendChild(listitem);
}
What am I doing wrong or not doing? Any help appreciated. Thanks
The property is contentEditable (note upper-case 'E'), not contenteditable.
section.contentEditable = "true";
You need to set the attribute, not the property:
section.setAttribute('contenteditable', 'true');
Instead of
section.contenteditable = "true";
Some more info here and here (in the context of jQuery, but covers the topic splendidly nonetheless).
My current understanding of the difference is that attributes are the things you can set through markup (id, class, contenteditable, etc.), whereas properties are the properties of the actual javascript objects representing the DOM nodes. As the linked article mentions, the two are often kept in sync by the browser, but not always.
Edit:
As Tim Down states in his answer, while the above works (setting the attribute), the actual problem is that the name of the property is cased wrong. It should be
section.contentEditable = "true"; //Note the upper case 'E'
The reason setting the attribute works, is that attributes are case-insensitive.
I have an element E and I'm appending some elements to it. All of a sudden, I find out that the next element to append should be the first child of E. What's the trick, how to do it? Method unshift doesn't work because E is an object, not array.
Long way would be to iterate through E's children and to move'em key++, but I'm sure that there is a prettier way.
var eElement; // some E DOM instance
var newFirstElement; //element which should be first in E
eElement.insertBefore(newFirstElement, eElement.firstChild);
2018 version - prepend
parent.prepend(newChild) // [newChild, child1, child2]
This is modern JS! It is more readable than previous options. It is currently available in Chrome, FF, and Opera.
The equivalent for adding to the end is append, replacing the old appendChild
parent.append(newChild) // [child1, child2, newChild]
Advanced usage
You can pass multiple values (or use spread operator ...).
Any string value will be added as a text element.
Examples:
parent.prepend(newChild, "foo") // [newChild, "foo", child1, child2]
const list = ["bar", newChild]
parent.append(...list, "fizz") // [child1, child2, "bar", newChild, "fizz"]
Related DOM methods
Read More - child.before and child.after
Read More - child.replaceWith
Mozilla Documentation
Can I Use
2017 version
You can use
targetElement.insertAdjacentElement('afterbegin', newFirstElement)
From MDN :
The insertAdjacentElement() method inserts a given element node at a given position relative to the element it is invoked upon.
position
A DOMString representing the position relative to the element; must be one of the following strings:
beforebegin: Before the element itself.
afterbegin: Just inside the element, before its first child.
beforeend: Just inside the element, after its last child.
afterend: After the element itself.
element
The element to be inserted into the tree.
In the family of insertAdjacent there is the sibling methods:
element.insertAdjacentHTML('afterbegin','htmlText')`
That can inject html string directly, like innerHTML but without override everything, so you can use it as a mini-template Engin and jump the oppressive process of document.createElement and even build a whole component with string manipulation process
element.insertAdjacentText for inject sanitize string into element . no more encode/decode
You can implement it directly i all your window html elements.
Like this :
HTMLElement.prototype.appendFirst = function(childNode) {
if (this.firstChild) {
this.insertBefore(childNode, this.firstChild);
}
else {
this.appendChild(childNode);
}
};
Accepted answer refactored into a function:
function prependChild(parentEle, newFirstChildEle) {
parentEle.insertBefore(newFirstChildEle, parentEle.firstChild)
}
Unless I have misunderstood:
$("e").prepend("<yourelem>Text</yourelem>");
Or
$("<yourelem>Text</yourelem>").prependTo("e");
Although it sounds like from your description that there is some condition attached, so
if (SomeCondition){
$("e").prepend("<yourelem>Text</yourelem>");
}
else{
$("e").append("<yourelem>Text</yourelem>");
}
I think you're looking for the .prepend function in jQuery. Example code:
$("#E").prepend("<p>Code goes here, yo!</p>");
I created this prototype to prepend elements to parent element.
Node.prototype.prependChild = function (child: Node) {
this.insertBefore(child, this.firstChild);
return this;
};
var newItem = document.createElement("LI"); // Create a <li> node
var textnode = document.createTextNode("Water"); // Create a text node
newItem.appendChild(textnode); // Append the text to <li>
var list = document.getElementById("myList"); // Get the <ul> element to insert a new node
list.insertBefore(newItem, list.childNodes[0]); // Insert <li> before the first child of <ul>
https://www.w3schools.com/jsref/met_node_insertbefore.asp