document fragments and appending children - javascript

I'm new to the concept of document fragments and I am currently having some trouble figuring out how to append children to a fragment.
This is my html
<form>
<ul id="tweets">
<li><img src="tweetIcon.jpg"><span>This is my tweet</span></li>
</ul>
</form>
Below is my script:
var tweets = [
"When teaching math, it shouldn't just be: 'Answer this question:'. It should also be: 'Question this answer:'",
"Another reason to choose ",
" Excellent! I love the new APIs that came with it, as well as the new tags and attributes.",
"That's great. I am really grateful for your program and will definitely continue to encourage folks to enroll in courses!"
];
function init() {
var ul = document.getElementById("tweets");
var fragment = document.createDocumentFragment();
for (var i = 0; i < tweets.length; i++) {
var tweet = tweets[i];
var li = document.createElement("li");
var span = document.createElement("span");
span.innerHTML = tweet;
var img = document.createElement("img");
img.setAttribute("src", "tweetIcon.jpg");
li.appendChild(span);
ul.appendChild(li);
fragment.appendChild(img);
fragment.appendChild(li);
}
ul.appendChild(fragment);
}
Right now I see the img and the span element only once at the top of the list. Below are all the strings for the tweets correctly displayed as a list. I need to add the image and the span element to each tweet. The three lines that are commented out are where I attempted to add the image to each li element as a child, but those lines don't really do anything. Any suggestions? thanks!

Move the document.createElement("img") inside the loop, otherwise you're repeatedly moving and changing the same image object.

Related

How can i make my new bullet points display a string?

First time posting, sorry if i do something wrong.
When i try to make a new list with js, the list elements only display [object HTMLLIElement] in the DOM. I would want it to make a new bullet point which says "Hello" each time i press the button.
It only shows this https://gyazo.com/f441c11ce81d80ff14ba4e207c1a7e2d
Here's my code.
var bodyEl = document.querySelector("body");
var ulist = document.createElement("ul");
var bulletpointEl = document.createElement("li");
bulletpointEl.innerHTML = "hello"
bodyEl.appendChild(ulist);
function bulletpoint() {
ulist.innerHTML += bulletpointEl;
}
<button onclick="bulletpoint()">New bulletpoint</button>
You have to use appendChild instead of innerHTML. To create new li element in each button click, you have to create that inside the function.
I will also suggest you to use textContent instead of innerHTML when the content is simple text.
var bodyEl = document.querySelector("body");
var ulist = document.createElement("ul");
function bulletpoint(){
var bulletpointEl = document.createElement("li");
bulletpointEl.textContent = "hello"
ulist.appendChild(bulletpointEl);
bodyEl.appendChild(ulist);
}
<button onclick="bulletpoint()">New bulletpoint</button>
back
The problem is that you're trying to give innerHTML an object instead of a string.
innerHTML accepts a string - https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Syntax
If you want to append an html element to the ulist you'll need to use the .appendChild() method same as you did with the bodyEl -
function bulletpoint(){
ulist.appendChild(bulletpointEl);
}
Hope this helps!

Removing an array element by clicking an HTML <li>

So I'm doing a playlist manager for youtube (using the ytb api) and for the graphic part I'm doing, such as youtube has, a list of every thumbnail there is in a given playlist. I use an HTML 'ul' and add every thumbnail as a 'li'.
Everything is working fine but id like to add a feature so the user could click on one of the thumbnails to remove it from the playlist.
First, let me explain how the important part is coded.
I use an array as a queue to stock every video ID that will be played (this is the playlist) :
var queue = []
And for the thumbnail list I use this function :
function refreshThumbnailsQueue() {
var thumbnailsUl = document.getElementById('thumbnailslist');
while(thumbnailsUl.firstChild) {
thumbnailsUl.removeChild(thumbnailsUl.firstChild );
}
for (var i = 0; i <= queue.length - 1; i++) {
var thumbnail = 'http://img.youtube.com/vi/' + queue[i] + '/maxresdefault.jpg';
var newLi = document.createElement('li');
newLi.className = 'thumbnailLi';
newLi.onclick = function() {
removeFromQueue();
}
var newImg = document.createElement('img');
newImg.className = 'thumbnailImg';
newImg.src = thumbnail;
newLi.appendChild(newImg);
thumbnailsUl.appendChild(newLi);
}
}
So I'm just removing every child the ul has and then filling it with every thumbnail of the video IDs there are in my queue var.
As you can see, there is a removeFromQueue() function called with an onclick event on each li in the code, and this is what I try to code.
Basicaly, if you click the third li, it should remove the third element of my queue var.
If you have any ideas, please let me know. (and BTW sorry for the mistakes English isn't my main language)
Thanks!
Note : I dont want to use jQuery.
If jQuery is an option, you can simply do the following :
$( "li" ).click(function(){
$( this ).remove();
})
As simple as that. If you want more information, I'll update my answer.
You can also visit this page for plain old javascript. Here is the important part :
var elem = document.getElementById("myDiv");
elem.parentNode.removeChild(elem);
As for the index of the li element
When you insert the list item in the DOM, you also set it's ID like this :
function refreshThumbnailsQueue() {
...
for (var i = 0; i <= queue.length - 1; i++) {
...
// Create the li.
var newLi = document.createElement('li');
newLi.id = "song-" + i;
// Create the onclick listening
li.onclick = function(){
// Remove from DOM.
var elem = document.getElementById(this.id);
elem.parentNode.removeChild(elem);
// We keep only the integer (index)
// In this example, '5' cuts away the "song-".
var index = parseInt((this.id+"").substring(5));
// Then, we remove it from the list.
YourProgram.removeIndex(index);
}
...
thumbnailsUl.appendChild(newLi);
}
}
This way, you know what it's index is.
Hope it helps.
Pass the index of the element to remove to the removeFromQueue(), like removeFromQueue(i). Then remove the item from queue.
function removeFromQueue(index) {
queue.splice(index, 1)
refreshThumbnailsQueue()
}

Nesting dynamic links into a dynamic list with Javascript

I have tried to create a function that creates a dynamic menu. Ive been able to create the "a" tags and give them individual links while also assigning them ID's. The problem is that I cant get the links inside of a list where my CSS applies its rules.
function write_navBar() {
var links = ["intro.html", "art.html", "portfolio.html", "guides.html", "about_me.html"]
var ul = document.createElement("ul");
document.getElementById("mainNav").appendChild(ul);
for (i = 0 ; i < links.length ; i++) {
var ul = document.createElement("ul");
var a = document.createElement("a");
var text = document.createTextNode(links[i]);
a.href = links[i];
a.id = "mainNav";
a.text = links[i];
document.getElementById("mainNav").appendChild(a);
}
}
Any suggestions on cleaning the code while keeping to javascript would be appreciated. And also any explanation of syntax would be also appreciated.
Thank you!
function write_navBar() {
var links = ["intro.html", "art.html", "portfolio.html", "guides.html", "about_me.html"];
var ul = document.createElement("ul");
var li, a, text;
for (var i = 0, l = links.length; i < l; ++i) {
li = document.createElement('li');
a = document.createElement('a');
text = document.createTextNode(links[i]);
a.href = links[i];
a.setAttribute("class", "some-class-name");
a.appendChild(text);
li.appendChild(a);
ul.appendChild(li);
}
document.querySelector("#mainNav").appendChild(ul);
}
• Use querySelector over getElementById. Both work, but theres a performance boost to querySelector. The API is close to jQuery and most (if not all) newer browsers support querySelector.
• Append the ul AFTER you've added the elements again for performance reasons.
• Use an LI to hold the link element, a second UL wont do what you want.
• Don't resuse id's, the thing you would want to use is a class, they basically do the same thing but javascript treats id's and classes differently. If that doesnt fit your needs, try a compound CSS selector in your css such as:
#mainNav ul li a { /* styles here */ }
You have to ensure that you append the correct items to the correct parents. Scanning your code I assume you want the following HTML output:
<div id="mainNav"> // this is already there
<ul>
<li>
intro.html
</li>
... // repeat for other items in the array
</ul>
</div>
You can modify your code like this to get the above result:
function write_navBar() {
var links = ["intro.html", "art.html", "portfolio.html", "guides.html", "about_me.html"]
var ul = document.createElement("ul");
document.getElementById("mainNav").appendChild(ul);
for (i = 0 ; i < links.length ; i++) {
var li = document.createElement("li");
var a = document.createElement("a");
a.href = links[i];
a.className = "some-class-to-target-in-your-css";
a.innerText = links[i];
ul.appendChild(li);
li.appendChild(a);
}
}
Your approach isn't that bad. I at one time took a similar outlook towards doing these. However, I am now of the belief it is far more testable, reliable, and easier to build these as actual templates, clone them, and populate them through a factory pattern.
In your setup, you have a parent ul, and then build multiple ul's with a's in them -- I am going to assume you meant to nest li elements -- and so that is what this will do.
Here is how I would approach that in your scenario.
Step 1: Build a the template, and create the styling and visual effect.
.navLink a{
padding:3px;
}
<ul class="menuTemplate">
<li class="navLink"><a></a></li>
</ul>
Simple style, I know. But it is just for simplicity, you can really do whatever you want there to style the example. Note that it is a simple structure, so all you are really seeing in there is a template, an li element, and the a element.
What we are also going to add to the style definition in our use case is
.menuTemplate{
display:none;
}
Because we don't actually want to see the template, we just want to use it. Next, we will create a factory for these.
var navFactory = new function(){
var template = document.querySelector('.menuTemplate .navLink');
this.Create = function(text,href){
var nav = template.cloneNode(true);
var link = nav.querySelector('a');
link.href = href;
link.innerText = text;
return nav;
}
};
The last step is to simply take your element that will hold the nav elements - you named this "mainNav" above - and fill it in from the factory.
var navFactory = new function(){
var template = document.querySelector('.menuTemplate .navLink');
this.Create = function(text,href){
var nav = template.cloneNode(true);
var link = nav.querySelector('a');
link.href = href;
link.innerText = text;
return nav;
}
};
function write_navBar() {
var links = ["intro.html", "art.html", "portfolio.html", "guides.html", "about_me.html"];
var navUl = document.querySelector('#mainNav ul');
for(var i = 0; i < links.length; i++){
navUl.appendChild(navFactory.Create(links[i],links[i]));
}
}
write_navBar();
.menuTemplate{
display:none;
}
.navLink a{
padding:3px;
opacity:0.85
}
.navLink a:hover{
opacity:1;
}
<ul class="menuTemplate">
<li class="navLink"><a></a></li>
</ul>
<div id="mainNav">
<ul></ul>
</div>

On img click display a div

I'm trying to make a Javascript code that if you click on of the "cards" then a div will display above it.
Here is my current code but I can't figure out how to make it display more than just text. I would like to be able to display images or create shapes inside, etc.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].addEventListener('click', function () {
var newdiv = document.createElement('div');
newdiv.innerHTML = 'Hello';
document.body.appendChild(newdiv);
});
}
Here is my full code:
http://pastebin.com/ueqiywFu
I know my full code is not organized, many of my friends have told me. I am planning on organizing it after it is complete. Anyway please help me..
Try appending elements to it:
var newdiv = document.createElement('div');
newdiv.innerHTML = 'first div text';
var otherdiv = document.createElement('div');
otherdiv.innerHTML = 'second div text';
newdiv.appendChild(otherdiv);
document.body.appendChild(newdiv);
DEMO
PS:
As Terry says, this is Javascript, not JQuery. This is JQuery.

Create link in an html table with javascript

I am using the following code to add columns dynamically to a html table:
var tblHeadObj = window.opener.document.getElementById("maintable").tHead;
var j=0;
while(j < fname.length)
{
if(tblHeadObj != null)
{
for(var h = 0; h < tblHeadObj.rows.length; h++)
{
var newTH = window.opener.document.createElement('th');
tblHeadObj.rows[h].appendChild(newTH);
//newTH.innerHTML='[th]row:'+h+'cell:'+(tblHeadObj.rows[h].cells.length-1)
}
}
var tblBodyObj = window.opener.document.getElementById("maintable").tBodies[0];
//for(var i = 0; i < tblBodyObj.rows.length; i++) {
var newCell=tblBodyObj.rows[0].insertCell(-1);
var newCell=tblBodyObj.rows[0].insertCell(-1);
// newCell.innerHTML = (tblBodyObj.rows[0].cells.length - 1)
newCell.innerHTML= fname[j];
j++;
}
Now i want to make columns as link.How can i do that?
Thanks
As others have noted, it is quite unclear what you mean by "make columns as link". However, we as a community have become accustomed to making guesses about the real problem and providing a solution based on that assumption. As we gain experience tackling more and more unclear questions, our ESP skill become more honed.
It appears that you are creating an HTML table via DOM methods. I will assume that you want to create a link within the created tablecell and here is my suggestion:
Use the same createElement method to create any elements you need. For instance, a link (anchor) can be created with the following code:
var link = document.createElement("a");
link.setAttribute("href", "http://www.microsoft.com")
link.className = "someCSSclass";
// For IE only, you can simply set the innerText of the node.
// The below code, however, should work on all browsers.
var linkText = document.createTextNode("Click me");
link.appendChild(linkText);
// Add the link to the previously created TableCell.
newCell.appendChild(link);
Alternatively, you can also set the innerHTML of the TableCell as #Anonymous has suggested.
If you're trying to put the cell contents into an anchor, then one way is to change
newCell.innerHTML= fname[j];
to
newCell.innerHTML= ''+fname[j]+'';
where whatever is a variable holding an appropriate string.
Beware that the contents of fname[j] are all inline (eg, not tables or blocks like div, headings, forms -- but form inputs are okay) or the anchor will be closed by most browsers prematurely. If need be, you could put the anchor only around parts of the cell's contents, but the easiest way to do that would depend on what the contents are.
This are all good but I needed an image in the link so here is that code:
cell[k] = document.createElement('td');
var link = document.createElement('a');
link.setAttribute('href', "http://www.ilovethismusic.com");
link.setAttribute('target', "_blank");
var newimg = document.createElement('img');
newimg.src = "http://www.ilovethismusic.com/Views/Images/bg_header.jpg";
newimg.alt = "imageMissing";
newimg.width = "95";
newimg.height = "45";
newimg.border = "0";
link.appendChild(newimg);
cell[k].appendChild(link);

Categories

Resources