Creating and showing div's with javascript - javascript

I am trying to create a list of friends and to do this I will need to create a div for each one. The code I tried hasn't worked.
Relevant JavaScript (Now at bottom of page):
document.getElementById("name").innerHTML = user;
document.getElementById("profilePic").src = "users/" + user + "/profilePic.jpg";
var friends = ["Test"];
var friendArea = document.getElementById("friendsDiv");
for (i=0; i < friends.length; i++) {
var friendDiv = document.createElement("div");
friendDiv.setAttribute("class", "friend");
var friendImage = document.createElement("img");
friendImage.setAttribute("class", "friendImage");
friendImage.setAttribute("src", "users/" + friends[i] + "/profilePic.jpg");
friendDiv.appendChild(friendImage);
friendArea.appendChild(friendDiv);
}
Relevant CSS:
.friends {
width: 100%;
height: 90%;
overflow-x: hidden;
overflow-y: auto;
}
.tools {
width: 100%;
height: 10%;
box-shadow: 0px 0px 3px 1px #898989;
}
.friend {
width: 100%;
height: 20%;
padding: 1%;
}
.friendImage {
height: 80%;
width: auto;
border: medium #CCCCCC solid;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
}
The HTML isn't really important but I'll include it anyway.
<div class="window">
<div class="rightCorner">
<img src="images/pPicTemp.png" id="profilePic">
</div>
<div class="holder" id="profileData">
<span id="name"></span>
</div>
<div class="sideBar">
<div class="friends" id="friendsDiv">
</div>
<div class="tools">
</div>
</div>

Is your script in a tag? Also is the document loaded when you attempt this? What does the console says? Is it working with no css? Also if photo path doesnt work there is no other content in the div did you try outputting something else?

You're not appending the friendImage to the friendDiv.
It should look like this:
var friends = ["Test"];
var friendArea = document.getElementById("friends");
for (i=0; i < friends.length; i++) {
var friendDiv = document.createElement("div");
friendDiv.setAttribute("class", "friend");
var friendImage = document.createElement("img");
friendImage.setAttribute("class", "friendImage");
friendImage.setAttribute("src", "users/" + friends[i] + "/profilePic.jpg");
friendDiv.appendChild(friendImage);
friendArea.appendChild(friendDiv);
}
Also, be sure to put this script at the bottom of your HTML <body></body> tag so that the HTML has loaded the entire document before the JavaScript attempts to get elements from the page.

Related

My script is not showing whats truly visible element wise

I found posts and online articles on how to do something like this but most examples are not in plain JavaScript. So this script works almost perfectly if all the sections are the same height for example 220px. So I thought I was getting closer in having this script working how I want it to work like overtime but then I realize
it had flaws when I decided to change the sections height and play around with the code more to see if it had any flaws that I was unaware of so basically this script is designed to output the name
of the sections that are visible but it is not showing the correct output for example if section 1 is the only one that is visible in the div it will say section-1 if multiple sections are visible it will say for example section-1,section-2 etc. Basically it should work like this regardless of the sections height
I know I have to change the code or altered it but I'm getting more confused the more I play around with it so how can I pull this off so I can always have the correct output? If I have to change my code completely to be able to do this then I don't mind.
This is my code
document.addEventListener('DOMContentLoaded',function(){
document.querySelector('#building').addEventListener('scroll',whichSectionsAreInSight);
function whichSectionsAreInSight(){
var building= document.querySelector('#building');
var top = building.scrollTop;
var bottom = top+building.offsetHeight;
var arr = [];
Array.prototype.forEach.call(
building.querySelectorAll('#building .sections'),
function(sections){
if ((sections.offsetTop < top && top <sections.offsetTop+sections.offsetHeight) || (sections.offsetTop < bottom && bottom < sections.offsetTop+sections.offsetHeight)){
arr.push(sections.id);
}
}
);
document.querySelector('#status').innerHTML = arr.join(',')
}
whichSectionsAreInSight();
});
h1{
margin: 0;
text-align: center;
}
#building{
background-color: gray;
height: 200px;
width: 200px;
overflow: auto;
}
.sections{
height: 80px;
width: 100%;
}
#section-1{
background-color: dodgerblue;
}
#section-2{
background-color: gold;
}
#section-3{
background-color: red;
}
#section-4{
background-color: gray;
height: 220px;
}
<p id='status'></p>
<div id='building'>
<div id='section-1' class='sections'><h1>Section 1</h1></div>
<div id='section-2' class='sections'><h1>Section 2</h1></div>
<div id='section-3' class='sections'><h1>Section 3</h1></div>
<div id='section-4' class='sections'><h1>Section 4</h1></div>
</div>
You were pretty close!
First off, you need to set the parent element to position:relative otherwise the parent that is being measured against is the document.
Also, the algorithm is simpler than what you had. Just make sure that the top of the element is less than the bottom of the parent, and the bottom of the element is greater than the top of the parent.
In your case this is offsetTop < bottom and offsetTop + offsetHeight > top
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#building').addEventListener('scroll', whichSectionsAreInSight);
function whichSectionsAreInSight() {
var building = document.querySelector('#building');
var top = building.scrollTop;
var bottom = top + building.offsetHeight;
var arr = [];
Array.prototype.forEach.call(
building.querySelectorAll('#building .sections'),
function(section) {
if (section.offsetTop < bottom && section.offsetTop + section.offsetHeight > top) {
arr.push(section.id);
}
}
);
document.querySelector('#status').innerHTML = arr.join(',')
}
whichSectionsAreInSight();
});
h1 {
margin: 0;
text-align: center;
}
#building {
background-color: gray;
height: 200px;
width: 200px;
overflow: auto;
position: relative;
}
.sections {
height: 80px;
width: 100%;
}
#section-1 {
background-color: dodgerblue;
}
#section-2 {
background-color: gold;
}
#section-3 {
background-color: red;
}
#section-4 {
background-color: gray;
height: 220px;
}
<p id='status'></p>
<div id='building'>
<div id='section-1' class='sections'>
<h1>Section 1</h1>
</div>
<div id='section-2' class='sections'>
<h1>Section 2</h1>
</div>
<div id='section-3' class='sections'>
<h1>Section 3</h1>
</div>
<div id='section-4' class='sections'>
<h1>Section 4</h1>
</div>
</div>

Fill parent div with the image being hovered over

I am still fairly new to JS, and I am trying to replace the HTML of a div with a picture that is being moused over, and when the mouse leaves I want it to return to it's normal state. I thought that I did everything right but my code doesn't seem to be working. I've looked through stack overflow and I see a lot of jQuery solutions to my 'problem,' but I would like an answer in pure JavaScript (I'm trying to "maser" this first), along with an explanation so I can understand why the answer IS the answer. Thanks.
I'll try to explain myself (my code). I grabbed reference to the image holder, and I grabbed reference to the the images. I thought I made a function that looped through the array of images and added an event listener to whichever image ( image[i] ) was being moused over. Then, I added an event listener that is supposed to return the image holder to it's default state by inserting the original HTML. I just don't understand how to fix this.
var holder = document.getElementById('holder');
var images = document.getElementsByTagName('img');
var popImage = function () {
for (i = 0; i < images.length; i++) {
images[i].addEventListener('mouseover', = function () {
holder.innerHTML = images[i];
});
images[i].addEventListener('mouseout', function () {
holder.innerHTML =
'<div class='col-md-3 img-fluid' id='img1'><img src='photo1.jpg'></div>
<div class='col-md-3 img-fluid' id='img2'><img src='photo2.jpg'></div>
<div class='col-md-3 img-fluid' id='img3'><img src='photo3.2.jpg'></div>
<div class='col-md-3 img-fluid' id='img4'><img src='photo4.jpg'></div>'
});
};
};
popImage();
You said you are new to JS and just learning which is great but an important part of learning JS is learning when not to use it. As #Yoda said if this was for production you really should use CSS instead of JS.
Here is one way you could accomplish this with pure CSS
<style>
.img {
width: 100px;
height: 100px;
background: #bada55;
border: 2px solid #333;
float: left;
}
.holder:hover > .img {
opacity: 0;
}
.holder:hover > .img:hover {
opacity: 1;
}
</style>
<div class="holder">
<!-- Using div.img for simplicity, these whould be your <img/> tags -->
<div class="img">1</div>
<div class="img">2</div>
<div class="img">3</div>
<div class="img">4</div>
</div>
For the purpose of learning, here's how you'd do it in JS:
var holder = document.getElementById('holder');
var images = document.querySelectorAll('.img');
var filter = false;
function popImage () {
// Use for (var i = 0 . . .
// Instead of for (i = 0 . . .
// Because without var, i will be stored in the global scope
for (var i = 0; i < images.length; i++) {
(function (_i) {
images[_i].addEventListener('mouseover', function () {
holder.innerHTML = '';
// We can't set innerHTML to images[_i]
// because it's a DomNode not a string
holder.appendChild(images[_i]);
});
})(i);
}
holder.addEventListener('mouseout', function (e) {
if (e.target !== holder)
return;
holder.innerHTML = '';
// Again, use var j = 0 . . .
for (var j = 0; j < images.length; j++) {
holder.appendChild(images[j]);
}
});
}
popImage();
.img {
width: 100px;
height: 100px;
background: #bada55;
border: 2px solid #333;
display: inline-block;
}
#holder {
position: relative;
width: 100%;// So doesn't collape and trigger mouseout
height: 100px;
background: red;
padding: 20px 0;
}
<div id="holder">
<!-- Again, these would be your image tags -->
<div class="img">1</div>
<div class="img">2</div>
<div class="img">3</div>
<div class="img">4</div>
</div>
I had 10 mins before leaving work so I had a crack at this to see how I would do it and give you some ideas.
Here is my implementation (https://jsfiddle.net/hg7s1pyh/)
I guess the main thing here is that I've broken it down into lots of smaller parts, this makes solving problems far easier, each method is concerned with doing one thing only.
You will also note the use of classes to show and hide content rather than removing it entirely, this takes lots of the arduous work out of this feature.
function attachEvents() {
var images = getImages();
images.forEach(function(image) {
attachMouseOverEvent(image);
attachMouseLeaveEvent(image);
});
}
function attachMouseOverEvent(element) {
element.addEventListener('mouseover', function(e) {
var clonedImage = e.target.cloneNode();
addImageToPreview(clonedImage);
});
}
function attachMouseLeaveEvent(element) {
element.addEventListener('mouseleave', function(e) {
removeImageFromPreview();
});
}
function getImages() {
return document.querySelectorAll('.js-image');
}
function getImagePreviewElement() {
return document.querySelector('.js-image-box');
}
function addImageToPreview(imageElement) {
var previewElement = getImagePreviewElement();
previewElement.classList.add('previewing');
previewElement.appendChild(imageElement);
}
function removeImageFromPreview() {
var previewElement = getImagePreviewElement();
previewElement.classList.remove('previewing');
var image = previewElement.querySelector('.js-image');
image.remove();
}
attachEvents();
.image-box {
position: relative;
min-height: 400px;
width: 400px;
border: 1px solid #000;
text-align: center;
}
.image-box .placeholder {
position: absolute;
top: 50%;
text-align: center;
transform: translateY(-50%);
width: 100%;
}
.image-box.previewing .placeholder {
display: none;
}
.image-box .image {
position: absolute;
top: 50%;
text-align: center;
transform: translate(-50%, -50%);
height: 100%;
width: 100%;
}
.images {
margin-top: 10px;
}
<div class="js-image-box image-box">
<div class="placeholder">
Placeholder
</div>
</div>
<div class="images">
<div class="col-md-3 img-fluid"><img class="js-image image" src="http://placehold.it/350x150"></div>
<div class="col-md-3 img-fluid"><img class="js-image image" src="http://placehold.it/150x150"></div>
<div class="col-md-3 img-fluid"><img class="js-image image" src="http://placehold.it/400x400"></div>
<div class="col-md-3 img-fluid"><img class="js-image image" src="http://placehold.it/350x150"></div>
</div>

Stick a div underneath thumbnails + limit the width

Alright. This might sound a little bit complicated. I've got a script which fetches thumbnails from a JSON. It fetches 9 thumbnails and onclick of the #load it fetches 9 more. How can I set the Load more button underneath the thumbnails and how to make it stick to the bottom of them each time you click it? ( I do not want it like it's now, on the side, but right in the middle and underneath them ).
+BONUS question: How can I fixate the thumbnails so they always show up 3 in a row. Since now, when I resize the window they change ( as you can see in the fiddle, there's only 2 per row now ).
jsfiddle.net/z6ge55ky/
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<div id="twitch">
<script src="js/main.js"></script>
<div id="load">
<img class="hvr-pulse" src="http://i.imgur.com/KHIYHFz.png?1">
</div>
</div>
$(function() {
var i=0;
var twitchApi = "https://api.twitch.tv/kraken/streams";
var twitchData;
$.getJSON(twitchApi, function(json) {
twitchData = json.streams;
setData()
});
function setData(){
var j = twitchData.length > (i + 9) ? (i + 9) : twitchData.length;
for (; i < j; i++) {
var streamGame = twitchData[i].game;
var streamThumb = twitchData[i].preview.medium;
var streamVideo = twitchData[i].channel.name;
var img = $('<img style="width: 250px; height: 250px;" src="' + streamThumb + '"/>')
$('#twitch').append(img);
img.click(function(){
$('#twitch iframe').remove()
$('#twitchframe').append( '<iframe frameborder="0" style="overflow:hidden; margin-left: 25px; width:400px; height:250px; position: fixed; top: 0; margin-top: 23.55%;" src="http://player.twitch.tv/?channel=' + streamVideo + '"></iframe>');
});
}
}
$('#load').click(function() {
setData();
});
});
#twitch {
width: 60%;
position: absolute;
left: 20%;
text-align: center;
}
#twitch img {
border: 5px solid rgba(0,0,0,0);
margin: 0 auto;
cursor: pointer;
}
#load {
bottom: 0;
position: absolute;
}
You have declared the width for #twitch 60% remove that and for #load use top:100%
DEMO on jsfiddle

Using jquery append() puts the appended content outside of the appended background

I'm using the append function to add different divs, images, links and text onto my html. When I do this though, the content that I get from a JSON file that I'm trying to append is being placed outside of the background that I want it to be placed on. Here is what the content is supposed to look like:
http://i.stack.imgur.com/iShVe.png
The image and text is placed onto the gray background when I create this html content myself, but when I try to create all this content with append(), it puts all the content to the left of the background:
Here is also the codepen that I'm doing it on if you needed to see that: http://codepen.io/JaGr/pen/XXMPQY
html:
<link href='https://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Droid+Serif' rel='stylesheet' type='text/css'>
<div>
<div class="header">
<div>
Camper
</div>
<div>
News
</div>
</div>
<div class="stories">
<div class="story">
<img src="http://a5.mzstatic.com/us/r30/Purple5/v4/5a/2e/e9/5a2ee9b3-8f0e-4f8b-4043-dd3e3ea29766/icon128-2x.png" class="profilePicture">
<div class="headline">Test Headline</div>
<div class="author">by - TestName</div>
<div class="likes"><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-ios7-heart-128.png" class="heartIcon"> 13</div>
</div>
</div>
</div>
css:
body {
background-image: url("http://s22.postimg.org/bondz7241/grey_wash_wall.png")
}
.header {
font-family: 'Oswald', sans-serif;
font-size: 100px;
float: left;
color: #A9A9A9;
border-right-style: solid;
border-bottom-style: solid;
margin-left: 20px;
margin-top: 10px;
padding-right: 135px;
padding-bottom: 18px;
width: 210px;
margin-bottom: 29px;
}
.story {
text-align: center;
float: right;
background-color: #A9A9A9;
width: 230px;
height: 330px;
margin-bottom: 30px;
margin-right: 30px;
box-shadow: 2px 2px 13px;
}
.headline, .author, .likes {
padding-top: 7px;
font-family: 'Droid Serif', serif;
}
.likes {
vertical-align:middle
padding-top: 5px;
}
a {
text-decoration: none;
color: #0052cc;
}
.profilePicture {
width: 230px;
height: 230px;
}
.heartIcon {
width: 15px;
height: 15px;
}
javascript:
$(document).ready(function() {
$.getJSON("http://www.freecodecamp.com/news/hot", function(json) {
for (var x = 0; x < json.length; x++) {
var headline = json[x].headline;
var headlineLink = json[x].link;
var authorName = json[x].author.username;
var authorNameLink = "http://www.freecodecamp.com/" + authorName;
var authorPicture = json[x].author.picture;
var likes = json[x].rank;
if (headline.length > 15) {
headline = headline.slice(0, 16);
}
var divStory = '<div class="story">'
var profilePic = '<img src="' + authorPicture + '"' + ' class="profilePicture">'
var divHeadline = '<div class="headline">' + headline + '</div>'
var divAuthor = '<div class="author">by - ' + authorName + '</div>'
var divLikes = '<div class="likes"><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-ios7-heart-128.png" class="heartIcon">' + likes + '</div>'
var lastDiv = '</div>'
$(".stories").append(divStory, profilePic, divHeadline, divAuthor, divLikes, lastDiv)
}
});
});
I think my html and css is OK, it works alright when I type in the code myself; it's just the javascript that introduces the problem. I've checked the variables and incoming JSON and they both seem fine as well, so I think the problem is just with append() itself, but I don't know exactly whats causing it.
It is the jquery append multiple elements.
$(".stories").append(divStory, profilePic, divHeadline, divAuthor, divLikes, lastDiv)
I haven't found out exactly why it created the issue, but change it to will fix the problem.
$(".stories").append(divStory + profilePic + divHeadline + divAuthor + divLikes + lastDiv)
Check fix here
Did u ever use the devtools? (F12)
They're pretty useful, and you can see on first sight that your elements aren't wrapped into the .story-tags.
I'd do it like this:
var tplStory = '\
<div class="story">\
<img src="{{authorPicture}}" class="profilePicture">\
<div class="headline">{{headline}}</div>\
<div class="author">by - {{authorName}}</div>\
<div class="likes"><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-ios7-heart-128.png" class="heartIcon">{{likes}}</div>\
</div>';
$(".stories").append(
divStory
.replace('{{authorPicture}}', authorPicture)
.replace(...)
)

javascript chatbox / messenger script

I'm trying to write a facebook like chatbox, but i've encountered a small problem.
I'm using the following code (it's only test code, so it's not really clean):
css code:
#messenger {
position: fixed;
bottom: 0px;
right: 10px;
width: 200px;
height: 300px;
z-index: 4;
background-color: #ECECEC;
border: 1px solid #000;
}
#messenger.p {
text-align: right;
}
#contacts {
margin: 5px 5px 5px 5px;
}
#chatspace {
position: fixed;
bottom: 0px;
right: 240px;
height: 20px;
left: 20px;
background-color: #ECECEC;
border: 1px solid #000;
z-index: 4;
}
.chatbox {
position: absolute;
bottom: 0px;
width: 200px;
height: 200px;
z-index: 4;
background-color: #ECECEC;
border: 1px solid #000;
}
html/javascript code:
<script type="text/javascript">
var i = 0;
function oc_chatbox() {
if (i == 0) {
document.getElementById('contacts').style.visibility = 'hidden';
document.getElementById('messenger').style.height = '20px';
i = 1;
}
else {
document.getElementById('contacts').style.visibility = 'visible';
document.getElementById('messenger').style.height = '300px';
i = 0;
}
}
function new_chat(userid) {
var new_right;
new_right = document.getElementById('messenger').style.right;
//alert('old value: '+ new_right);
new_right += 20;
//alert('New value of right: '+ new_right);
document.getElementById('chatspace').innerHTML = '<div id="'+userid+'" class="chatbox" style="right: '+new_right+'px;"></div>';
//document.write('<div id="'+userid+'" class="chatbox" style="right: '+new_right+'px;"></div>');
}
</script>
<div id="chatspace"></div>
<div id="messenger">
<p>Collapse</p>
<div id="contacts">
<ul>
<li>contact A</li>
</ul>
</div>
</div>
the problem is, that when I try to add new chats to the chatbar, i can't seem the place them next to each other.
anyone who can help ?
EDIT:
so i changed to javascript code to:
var last = null;
function new_chat(userid) {
if(userid==null)
userid = "user666";
var new_right;
var margin = 10;
var messenger = window.last==null?document.getElementById('messenger'):window.last; //Take the messenger or the last added chat
new_right = document.body.clientWidth-messenger.offsetLeft; //Compute the window size
console.log(new_right); //Log the number
new_right += margin; //keep spaces between divs
var newChat = document.createElement("div"); //DOM create DIV
newChat.id = userid;
newChat.className = "chatbox shadow";
newChat.style.right = new_right+"px";
newChat.innerHTML = '<p>'+userid+'</p><p><textarea></textarea></p>';
window.last = newChat; //Remember whichever is last
document.body.appendChild(newChat);
}
and now it works, thanks !
You cannot get an element right offset using its style, unlest the style is set and valid. Instead you must get element.offsetLeft and size of window area and do this:
new_right = windowSize()[0]-messenger.offsetLeft;
Where window size is this function.
Here is my, working, version of your function:
var last = null;
function new_chat(userid) {
if(userid==null)
userid = "user666";
var new_right;
var margin = 20;
var messenger = window.last==null?document.getElementById('messenger'):window.last; //Take the messenger or the last added chat
new_right = windowSize()[0]-messenger.offsetLeft; //Compute the window size
console.log(new_right); //Log the number
new_right += margin; //keep spaces between divs
var newChat = document.createElement("div"); //DOM create DIV
newChat.id = userid;
newChat.className = "chatbox";
newChat.style.right = new_right+"px";
window.last = newChat; //Remember whichever is last
document.body.appendChild(newChat);
}
You may get errors if console is not defined in your brouwser. But in such case you should take a better browser. Normally, the if(console!=null) is put in code.
And here is the link.
You should try adding a float style.
.chatbox {
float: right;
}
Add that to your chatbox styles. You may need to mess around a bit to make sure the float doesn't mess with your other elements. You may need a better container for them.
If you want to get really fun, you can add .draggable() from jQuery, and you can have them snap to your chat bar. You can then change the order of your chats.

Categories