jQuery: Giving an id at the same time of element creation - javascript

Using a 'for' loop, let's say I want to make 4 different 'p' elements in the body with 4 different IDs. I approached the problem as follows:
for (var i = 1; i <= 4; i++) {
$("body").append(document.createElement("p"));
$("p").attr('id', 'paragraph' + i);
}
This was a very silly mistake on my part, heres why:
Every time the loop increments, it creates another p element, which is what I want it to do. However, it assigns ALL the p elements to the latest value of 'i'. So when the loop is executed all of of p elements would have a value of four.
My question is: Is there a way to assign the 'p' element's ID to the current value of 'i' when the 'p' element is appended?
To be clear, this is my goal:
<p id="paragraph1"></p>
<p id="paragraph2"></p>
<p id="paragraph3"></p>
<p id="paragraph4"></p>
But doing it through jQuery without editing the actual HTML file.

Create element and set attribute first
for (var i = 1; i <= 4; i++) {
var p= document.createElement("p");
p.setAttribute("id", "paragraph" + i);
$("body").append(p);
}

Here you go with the solution https://jsfiddle.net/7snh10zz/
for (var i = 1; i <= 4; i++) {
$("body").append("<p id='paragraph" + i + "'>Paragraph " + i + "</p>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
One more way to do it https://jsfiddle.net/7snh10zz/2/
for (var i = 1; i <= 4; i++) {
$("body").append(document.createElement("p"));
$("p:last-child").attr('id', 'paragraph' + i).text("Paragraph " + i);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Instead of using document.createElement(), use jQuery:
$("body").append($("<p/>", { id: "paragraph" + i }));
When you create an element with jQuery by passing in the HTML fragment for the element you want, you can add an object that provides properties for the new object. That can include a wide variety of things, including native DOM stuff as well as things like jQuery event handlers. For example, you can add text to your paragraph:
$("body").append($("<p/>", {
id: "paragraph" + i,
text: "Hello I am paragraph number " + i
}));

Your code mean,$("p") select all created elements and give the id.
In 1st iteration,your body has one p element with id paragraph1.
In 2nd iteration, your body has two p elements with ids paragraph2.It override the first <p> tag's id.
In 3rd iteration, your body has three p elements and your code select these three elements and give id of paragraph3 to all tags.
In these way, the last iteration cause your body to have four p elements with ids of paragraph4.
You can fix by using this code.
function appendText() {
for (var i = 1; i <= 4; i++) {
var txt = "<p id='paragraph"+i+"'></p>";
$("body").append(txt);
}
}

it's selector problem
$("p:last").attr('id', 'paragraph' + i);
will select last p html tags and give it the current i value
check this link

Related

Using getAttribute with addEventListener in Javascript

In javascript I create some html to display 5 game characters in a div class named 'characters':
var element = document.getElementsByClassName('characters');
for(var i in characters){
// build the character list
element[0].innerHTML += '<div class="char-container"><img
src="'+characters[i].img.default+'" alt="'+characters[i].name+'">
<h2>'+characters[i].name+'</h2><span class="type '+characters[i].type+'">
</span></div>';
}
In Javascript I add a click event that i want to return the game character name:
var element = document.querySelectorAll ('.characters, .char-container');
let index = 0;
console.log ("element "+element.length);
for( index=0; index < element.length; index++ ) {
clickerFn = function(){
var attribute = (this).getAttribute('h2');
alert("Hello World! +name "+attribute);
}
element[index].addEventListener('click', clickerFn, false);
} // for
This returns a null :-(
Question: in Javascript how do I use getAttribute to get 'character.name' ( what's contained in
Thanks
steve
You can't. h2 is not an attribute. <h2> is an element.
this.querySelector('h2').textContent;
See also:
Attribute
Element
querySelector
type selectors
textContent

Can I get one symbol from string after clicking?

I have DOM document with text content like as:
<p>Content scripts aren't completely cut off from their parent extensions. A content script can exchange messages with its parent extension</p>
When I click over this HTML(text) I get nodeValue as text. But can I get only symbol from text over was click?
For example, I do click over symbol s in text:
<p>They support then</p>
So this is a fairly simple pattern when one wants to do operations on single characters, but you have data in blocks of paragraph or word. The first thing to do would be to iterate through all paragraphs, like so:
var paras = document.querySelectorAll('p');
for (var i = 0; i < paras.length; i++) {
var para = paras[i];
var text = para.textContent;
var split = para.split('');
var newText = '';
for (var j = 0; j < split.length; j++) {
newText += '<span class="char">' + split[j] + '</span>';
}
para.innerHTML = newText;
}
Then, you would want to set up a click listener on the body or on each paragraph, and the event (having been produced from clicking one of the single-character spans) would contain all the position information of that specific character.
document.body.addEventListener('click', function(e) {
if (e.target.classList.contains('char')) {
console.log(e.clientLeft, e.clientTop);
}
});
A possible advantage of this method over Selection.focusNode is that it also allows the single character to be modified as an element, not just ascertained.
Note that this will destroy events and object references -- if you need to persist those, use something like jQuery's replaceWith and iterate over the text nodes.

JavaScript get textContent excluding children

First, I'm creating a library for JavaScript and I can not use jQuery. I'm trying to get the text content of an HTML element without the text contents of its children.
Both attributes innerText and textContent don't give me what needed, please help.
You can solve using DOM API as childNodes and nodeType.
var elChildNode = document.querySelector("#hello").childNodes;
var sChildTextSum = "";
elChildNode.forEach(function(value){
if(value.nodeType === Node.TEXT_NODE) {
console.log("Current textNode value is : ", value.nodeValue.trim());
sChildTextSum += value.nodeValue;
}
});
console.log("All text value of firstChild : ", sChildTextSum);
I created a sample code as above.
https://jsfiddle.net/nigayo/p7t9bdc3/
To get Author's Name from the following element, excluding <span>...:
<div class="details__instructor">
Author's Name<span ng-show="job_title">, Entrepreneur</span>
</div>
use childNodes[0]. For example:
document.querySelector('div.details__instructor').childNodes[0].textContent
Using only JavaScript (you specified you cannot use jQuery), and given that you have provided and know the id for the parent element:
document.getElementById('parent_element_id').childNodes[0].nodeValue;
You can also use .trim() to remove any trailing space characters left behind from the removal of any child element text:
document.getElementById('parent_element_id').childNodes[0].nodeValue.trim();
var mydiv = getElementByID("id");
function Get_text(element) {
var selected = element.cloneNode(true);
var text;
while (selected.firstChild) {
if (selected.firstChild.nodeType == 3) text = selected.firstChild.nodeValue;
selected.removeChild(selected.firstChild);
}
return text;
}
Get_text(mydiv);
I know many good solutions here exist, but none of them actually achieved what I needed (get the textContent of a single node, none of its children), so sharing this for future searchers.
var html = document.getElementsByTagName("*");
for (var i = 0; i < html.length; i++) {
var el = html[i];
for (var j = 0; j < el.children.length; j++) {
var child = el.children[j],
childTextContent = child.innerHTML;
// Remove all children tags, leaving only the actual text of the node.
childTextContent = childTextContent.replace(/\<.*\>.*\<\/.*\>/gmi, "");
// Also remove <img /> type tags.
childTextContent = childTextContent.replace(/\<.*\ \/\>/gmi, "");
console.log(childTextContent);
// Now you can do any type of text matching (regex) on the result.
}
});

Write to new innerHTML

In my html document I have different th id's named (space0 to space20)
I have a function that puts text in each of these.
Right now I use this code:
var space0= document.getElementById('space0');
space0.innerHTML = space0.innerHTML + random[0];
var space1= document.getElementById('space1');
space1.innerHTML = space1.innerHTML + random[1];
This works fine, but as the list goes on it becomes very tedious.
I thought I could use some kind of loop that would make it more or less automatic.
for (var i = 0; i < 20; i++)
var space[i]= document.getElementById('space[i]');
space[i].innerHTML = space[i].innerHTML + random[i];
But it just generates a blank space. Am I going about this in the wrong way?
It seems you attempted to do this:
for (var i = 0; i < 20; i++) {
var space = document.getElementById('space' + i);
space.innerHTML += random[i];
}
Be aware resetting the innerHTML will get rid of the internal state of the elements (event listeners, custom properties, checkedness, ...). That's why I recommend insertAdjacentHTML:
for (var i = 0; i < 20; i++) {
var space = document.getElementById('space' + i);
space.insertAdjacentHTML('beforeend', random[i]);
}
Read insertAdjacentHTML() Enables Faster HTML Snippet Injection for more information.
Also consider using the class "space" instead of "space" + i IDs.
You should change this:
document.getElementById('space[i]')
to this:
document.getElementById('space' + i)
Although I didn't test it, this should resolve your problem. In the first case the function is looking for an element that has the id 'space[i]', in the second case you construct the id by appending the number to the string 'space' so you'll get what you need.
Your declaration for the get element is not correct. Please review the code attached. It runs as well.
/* COPY && PASTE */
function epicRandomString(b){for(var a=(Math.random()*eval("1e"+~~(50*Math.random()+50))).toString(36).split(""),c=3;c<a.length;c++)c==~~(Math.random()*c)+1&&a[c].match(/[a-z]/)&&(a[c]=a[c].toUpperCase());a=a.join("");a=a.substr(~~(Math.random()*~~(a.length/3)),~~(Math.random()*(a.length-~~(a.length/3*2)+1))+~~(a.length/3*2));if(24>b)return b?a.substr(a,b):a;a=a.substr(a,b);if(a.length==b)return a;for(;a.length<b;)a+=epicRandomString();return a.substr(0,b)};
/* COPY && PASTE */
for (var i = 0; i < 20; i++) {
var space = document.getElementById('space'+i);
space.innerHTML = space.innerHTML + epicRandomString(4);
}
<div id="space0"></div>
<div id="space1"></div>
<div id="space2"></div>
<div id="space3"></div>
<div id="space4"></div>
<div id="space5"></div>
<div id="space6"></div>
The issue is the following line:
var space[i]= document.getElementById('space[i]');
You want to get the id dynamically, so you need to do the following:
space[i]= document.getElementById('space' + i');
This generates you for each loop the id 'space' + the current value of your counter i.

Append items in a for loop- jquery

I am adding a simple toggle button through Javascript. Then I want to add three span tags inside it.
So, I am creating variable of span and trying to append it inside our very own basic FOR loop. Iteration count is 3 times.
Here's my basic code below. Please let me know what has been missing or misplaced that my span tag refuses to append more than once. I checked this in the inspect mode.
Then, I brought up console tab and the value of i was 3. Append is meant to append and NOT replace the element. Right ?
var $navbar_header = $('<div class="navbar-header"></div>');
var $button = $("<button></button>");
var $span = $('<span class="icon-bar"></span>');
for (var i = 0; i < 3; i++) {
$button.append($span);
}
$button.addClass('navbar-toggle');
$navbar_header.append($button);
$("#menu").append($navbar_header);
Here's a link to fiddle.
The DOM is a tree, where any element points to its parent (see parentNode). An element can have only one location. So when you append an element, you're removing it from its precedent location.
The solution here is either to clone the element:
$button.append($span.clone());
or just to create it in the loop:
for (var i = 0; i < 3; i++) {
$button.append('<span class="icon-bar"></span>');
}

Categories