How to change document.write into a function for ASCII art - javascript

I am fairly new in development so I am going to try my best in phrasing my question accurately. Well, it is pretty simple, I have written a script below which draws a Christmass Tree as ASCII art on the webpage. I have used document.write. I want to however:
Check if my code can be made simpler
Convert it into a function and still make it display on to the webpage
I am not very familiar with using the DOM yet and tried console.log but I am sure I am doing something wrong there considering my relatively low experience. Would be great if someone could guide me and show me how this can be made into a solid function which still displays the christmas tree on the browser.
Thanks!
<!DOCTYPE html>
<html>
<body>
<p></p>
<script>
//define height and star parameter
var height=5;
var star=true;
//add or remove star
if(star===true){
for (u=0;u<1;u++) {
for (r=0;r<height-1;r++) {
document.write("&nbsp");
}
document.write("*</br>");
}
} else {
document.write("");
};
//create a loop for the pyramid in the tree
for (i=0; i<height; i++) {
for(r=height-1; r>i; r--) {
document.write("&nbsp");
}
for (k=0; k<=(i*1); k++) {
document.write("x");
}
document.write("</br>");
};
//create trunk of tree
for (u=0;u<1;u++) {
for (r=0;r<height-1;r++) {
document.write("&nbsp");
}
document.write("I</br>");
}
</script>
</body>
</html>

Related

Assigning string to div value from javascript function across pages

I have a web app that outputs the results of a function as a double. The function compares two text documents and returns the percentage indicating the percentage of similarity between the two documents. When the user clicks a Compare button, the function runs and takes the user from the compare.jsp page to the results.jsp page, and displays a loading-bar that is filled in like so:
<div id="levenshtein-distance"
class="ldBar label-center levenshtein-distance"
data-preset="fan"
data-value="${result.percentage}"
data-stroke="">
</div>
This works fine, the fan bar gets the correct percentage. However, I am also trying to color the fan bar using the data-stroke value based on this percentage. I have a simple javascript function to do this, but can't figure out how to pass the value. I've tried running the function in the body tag of the results.jsp page using "onload", but this doesn't work. Here is my JavaScript function:
function barSetLD(percent) {
var red = "red";
var green = "green";
var orange = "orange";
var elem = document.getElementById("levenshtein-distance");
if (percent <= 40.00) {
elem.setAttribute("data-stroke", green);
} else if (percent > 40.00 && percent <= 70.00) {
elem.setAttribute("data-stroke", orange);
} else {
elem.setAttribute("data-stroke", red);
}
}
I've done quite a bit of searching and can't seem to find an example that helped me solve this. Any help is very much appreciated.
////Update:
Trinh, that worked to change the color, thanks! My problem now is that I do, in fact, have multiple 'levenshtein-distance' ids and I am looping through them. So currently everything is being set to the same color. I should have mentioned this initially, sorry. I am comparing multiple pairs of files and outputting the loading-bar for each pair. If you have some idea about how to resolve the looping issue, that would be great, but thanks for the original solution either way! I updated my javascript function as follows:
function barSetLD(percent) {
var red = "red";
var green = "green";
var orange = "orange";
var elem = document.querySelectorAll("[id^=levenshtein-distance]");
for (var i in elem) {
if (percent <= 40.00) {
elem[i].setAttribute("data-stroke", green);
} else if (percent > 40.00 && percent <= 70.00) {
elem[i].setAttribute("data-stroke", orange);
} else {
elem[i].setAttribute("data-stroke", red);
}
}
}
And the full bit of code with the html loop is, and I am now calling the barSetLD(percent) at the very bottom of the page as you suggested:
<c:forEach items="${studentResults}" var="result" varStatus="loop">
<div id="levenshtein-distance"
class="ldBar label-center levenshtein-distance"
data-preset="fan"
data-value="${result.percentage}">
</div>
</c:forEach>
<script type="text/javascript">
barSetLD("${result.percentage}");
</script>
Put your code at the very bottom of the page where all DOM has been loaded. Or at least make sure <div id="levenshtein-distance"/> exist and fully loaded before calling this document.getElementById("levenshtein-distance");. Also double check if you have multiple levenshtein-distance id...

Javascript in SharePoint CEWP not working

I wrote a simple javascript to change the color of an html class based on its textcontent/innerHTML. When writing the script, it works fine when I put it directly in to the developer tools console (F12) for Chrome. But when I try to call the script from a CEWP, it doesn't work. What am I missing? Here is the html I embedded in the CEWP. Long time administrator, first time diving into CSOM development. I'm sure this is something extremely simple but I am at a loss..
<script type="text/javascript">
var status_array =document.getElementsByClassName("sefl_status");
var pattern = new RegExp("Effective");
for (i=0; i < status_array.length; i++)
{
if (pattern.test(status_array[i].innerHTML)===true)
{
status_array[i].style.color="green"
}
};
</script>
I modify the code as below for your reference:
<script type="text/javascript">
window.onload=function(){
var status_array =document.getElementsByClassName("sefl_status");
var pattern = new RegExp("Effective");
for (var i=0; i < status_array.length; i++)
{
if (pattern.test(status_array[i].innerHTML)===true)
{
status_array[i].style.color="green";
}
}
}
</script>

Placing elements within a container div into an array - jQuery or JavaScript

I have a div that contains a number of Instagram images, produced by the instafeed.js plugin. After running the plugin, the resultant HTML looks like this:
<div id="instafeed">
<a><img /></a>
<a><img /></a>
<a><img /></a>
etc...
</div>
I am trying to find a way to load the contents of this div into an array; I believe that the easiest way would be to just take the tags, which is fine.
I'm pretty inexperienced with both JS and jQuery, which is why I'm having difficulty achieving this and I've not been able to find any forum posts that quite do what I'm hoping to achieve.
So far, all I'm trying to do is load the contents of the div into an array and print it back out to the document, which should (in my mind anyway) add the tags back into the HTML. I'm trying with both JavaScript and jQuery and having little success with either. I'd appreciate any thoughts:
JS:
var containerDiv = document.getElementById('instafeed');
var pics = containerDiv.getElementsByTagName('img');
console.log(pics); //Tells me at least that I have an array of img
for (var i = 0; i < pics.length; i++) {
document.write(pics[i]);
} //Seemingly does nothing
jQuery:
(I'm really sorry if this code is just all wrong, I really don't know jQuery very well at all)
$(document).ready(function() {
var pics = [];
$('#instafeed').find('img').each(function() {
pics.push($(this));
});
for (i = 0; i < pics.length; i++) {
console.log(pics[i]);
}
});
Any thoughts, tips or pointers would be much appreciated.
Edit:
Just to add a little background to my problem, to avoid causing any more confusion.
I'm trying to pull four random images from a user-specific Instagram feed for display on a website. instafeed.js can pull just four images and it can randomise the images, but Instagram itself always sends the four most recent images, so the plugin is just randomising the order of the same four pictures each time.
I'm trying to let the plugin send through every picture, which will go into the div instafeed. From here I want to load all of the contained images into an array so that I can randomly pick four images for display on the site.
JQuery code that you write is correct. Only you need the div where you need to put the images.
$(document).ready(function() {
var pics = [];
$('#instafeed').find('img').each(function() {
pics.push($(this));
});
for (i = 0; i < pics.length; i++) {
$('div#yourDiv').append(pics[i]);
}
});
See the line of the for()
You can extract only the SRC of the images and then make like you want
$('#instafeed').find('img').each(function() {
pics.push($(this).attr('src'));
});
console.log(pics); // returns an array of src.
Thank you to everyone who has tried to help me along with this. It turns out that the problem I was having stemmed from my query attempting to run before instafeed.js had been able to pull the images through from Instagram, and so there was nothing for it to find in the div. I've managed to fix this with a setTimeout.
For anyone who is interested, and just in case anyone else might come across this in future with a similar problem, here is my complete code (it's a little inelegant I'm sure, but I'm still a relative novice at JS.)
function snagImages() {
var pics = [];
$('div#instafeed').find('img').each(function() {
pics.push($(this).attr('src'));
});
reduceGallery(4, pics);
}
function reduceGallery(limit, pics) {
if (limit === undefined) {
limit = 4;
}
var gallery = [];
while (gallery.length < limit) {
var j = Math.floor(Math.random() * pics.length);
if ( gallery.indexOf(pics[j]) > -1) {
continue;
}
gallery.push(pics[j]);
}
displayPics(gallery);
}
function displayPics(gallery) {
for (var i = 0; i < gallery.length; i++) {
document.getElementById('gallery').innerHTML += '' + '<img src="' + gallery[i] + '" alt="Gallery Image" />' + '';
}
}
var userFeed = new Instafeed( {
options
});
userFeed.run();
setTimeout(function() { snagImages() }, 500);

Replacing Document.write Problems(I did some research but still failed)

I got a great answer to this but have more questions. :) I was told that having javascript declared in two different places was bad and messy(you can see in the answer below), but I'm learning from a book right now and it told me to put my variables, arrays, functions etc. in the head of the html and the rest in the body.(that's why I have javascript declared in two different places) Is that wrong and why? He also recommended using a developer tool. I'm very new to coding in general and don't know much about these could anyone recommend a developer tool for chrome? Also what would a developer tool do? Thanks!
This was fixed:
Hi I was converting the card war game so it worked on a page instead of in the console and here was my original code http://pastebin.com/AgLgy97F. I was trying to use document.write to write out the code on a web, but I found out that document.write rewrote the whole page and removed the button I put there to progress to the next turn.
I looked on the forums and I looked online and came to the conclusion that I shoud replace it using this<div id="play"></div> and document.getElementById("play").innerHTML="I'm a string!". So I made this http://pastebin.com/29mVqp67. I tried it out and nothing happened -_-. What did I do wrong replacing document.write?
The new code I made is here too:
<html>
<head>
<script language="JavaScript">
<!--
var disp = function() {
document.getElementByID("play").innerHTML="You drew a "+user_disp+".";
document.getElementByID("play").innerHTML="Your opponent drew a "+cpu_disp+".";
document.getElementByID("play").innerHTML=statement;
};
var war = function() {
document.getElementByID("play").innerHTML="W-A-R spells WAR!";
disp();
};
var full = [1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13];
var user = [];
var cpu = [];
var rand = 0;
//Shuffles and deals the deck
var shuffled = [];
for (var i=0;i<52;i++) {
rand=Math.floor(Math.random()*full.length);
shuffled.push(full[rand]);
full.splice(rand,1);
}
for (var j=0;j<52;j++) {
if (j%2===0) {
user[user.length]=shuffled.pop();
} else {
cpu[cpu.length]=shuffled.pop();
}
}
//Creates a bunch of variables and functions that will be needed in the game
var cpu_card=0;
var cpu_warcard=0;
var cpu_war1=0;
var cpu_war2=0;
var cpu_war3=0;
var cpu_disp=0;
var user_card=0;
var user_warcard=0;
var user_war1=0;
var user_war2=0;
var user_war3=0;
var user_disp=0;
var statement=0;
var card_name = function(cpuc,userc) {
switch (cpuc) {
case 13:
cpu_disp="K";
break;
case 12:
cpu_disp="Q";
break;
case 11:
cpu_disp="J";
break;
case 1:
cpu_disp="A";
break;
default:
cpu_disp=cpuc;
break;
}
switch (userc) {
case 13:
user_disp="K";
break;
case 12:
user_disp="Q";
break;
case 11:
user_disp="J";
break;
case 1:
user_disp="A";
break;
default:
user_disp=userc;
break;
}
};
//Lets play the game!
//-->
</script>
</head>
<body>
<form>
<input type="Button" value="Click to Take Your Turn" onClick="playWar()"></input>
</form>
<p>
<h1>This Is War Lets Play!!!!</h1>
<br>
<div id="play"></div>
<script language="JavaScript">
<!--
function playWar(){
if(user.length<52 && user.length>1) {
//Picks out the cards that are used
cpu_card=cpu.shift();
user_card=user.shift();
card_name(cpu_card,user_card);
//Figures out if you win, lose, or go to war
if (user_card<cpu_card) {
statement="You lost!";
cpu[cpu.length]=cpu_card;
cpu[cpu.length]=user_card;
} else {
if (user_card>cpu_card) {
statement="You won!";
user[user.length]=user_card;
user[user.length]=cpu_card;
} else {
if(cpu.length<3 || user.length<3){
user[user.length]=user_card;
cpu[cpu.length]=cpu_card;
}
else{
statement="You tied! TO WAR!";
}
}
}
disp();
//This is what happens when you go to war
if (statement==="You tied! TO WAR!") {
cpu_war1=cpu.shift();
cpu_war2=cpu.shift();
cpu_war3=cpu.shift();
cpu_warcard=cpu.shift();
user_war1=user.shift();
user_war2=user.shift();
user_war3=user.shift();
user_warcard=user.shift();
card_name(cpu_warcard,user_warcard);
if (user_warcard<cpu_warcard) {
statement="You lost the war to your opponent!";
cpu[cpu.length]=cpu_war1;
cpu[cpu.length]=cpu_war2;
cpu[cpu.length]=cpu_war3;
cpu[cpu.length]=cpu_warcard;
cpu[cpu.length]=cpu_card;
cpu[cpu.length]=user_war1;
cpu[cpu.length]=user_war2;
cpu[cpu.length]=user_war3;
cpu[cpu.length]=user_warcard;
cpu[cpu.length]=cpu_card;
} else {
if(user_warcard>cpu_warcard) {
statement="You crushed your opponent in war!";
user[user.length]=user_war1;
user[user.length]=user_war2;
user[user.length]=user_war3;
user[user.length]=user_warcard;
user[user.length]=user_card;
user[user.length]=cpu_war1;
user[user.length]=cpu_war2;
user[user.length]=cpu_war3;
user[user.length]=cpu_warcard;
user[user.length]=cpu_card;
} else {
statement="The war resulted in a stalemate!";
user[user.length]=user_war1;
user[user.length]=user_war2;
user[user.length]=user_war3;
user[user.length]=user_warcard;
user[user.length]=user_card;
cpu[cpu.length]=cpu_war1;
cpu[cpu.length]=cpu_war2;
cpu[cpu.length]=cpu_war3;
cpu[cpu.length]=cpu_warcard;
cpu[cpu.length]=cpu_card;
}
}
war();
}
}
//When you are done, here it finds if you win or lose this game
else if (user.length===52) {
document.getElementByID("play").innerHTML="You have crushed your opponent. Feel free to steal all of his belongings!";
} else {
document.getElementByID("play").innerHTML="Unfortunatly, you have fallen victim to your opponent's wrath and have been conquered.;
}
}
//-->
</script>
</body>
You have a few problems here to start with.
you have your javascript declared in two different places and in both cases you are polluting the global namespace. That should be cleaned up and may help identify some problems.
you have an unterminated string literal at the end of this line:
you have fallen victim to your opponent's wrath and have been conquered. <===
getElementByID NEEDS to be getElementById
Your disp() function is incorrect. As it is written, each successive line is replacing the previous text.
var disp = function() {
document.getElementByID("play").innerHTML="You drew a "+user_disp+".";
document.getElementByID("play").innerHTML="Your opponent drew a "+cpu_disp+".";
document.getElementByID("play").innerHTML=statement;
};
This can be fixed by concatenating the strings together prior to setting innerHtml, or, to have more control over the output you can use separate elements. Pseudo code:
else.innerHTML = string1 + string2 + string3;
I'd recommend making some heavy use of the developer tools for whichever browser you are using for development. It will help you catch many of these problems either by watching the console output or by stepping through the code.
I've put your code in a jsFiddle as well.
That should get you started. Good luck!

Simple image rotation with pure javascript, no jQuery

trying to come up with very simple image rotation using pure javascript without jQuery.
Something that I could call like that and it could place the image in same spot rotating it one by one.
rotator('<img src="image1.gif"/ >','<img src="image1.gif"/ >');
maybe someone could suggest a way of doing it? thank you.
UPDATE: By Rotation I meant, one disappears, another appears. Not angle rotation.
This sort of steps beyond the call of duty and probably isn't the best solution but nonetheless. A full Javascript function (handles by tag not by image)
<html>
<head>
<script>
/*rotate
desc: Rotate a set of first level child objects based on tag name
params:
id = Rotate elements container id
tag = Tag (nodeName - see textNode issue) of DOM objects to be cycled
*/
function rotate(id, tag)
{
/*Normalise string for later comparison*/
tag = tag.toLowerCase();
/*Get container DOM Object*/
var el = document.getElementById(id),
visibleIdentified = false;
hasBeenSet = false,
firstMatchingChild = false;;
/*Iterate over children*/
for(i = 0; i < el.childNodes.length; i++){
/*Set child to var for ease of access*/
var child = el.childNodes[i];
/*If element has the correct nodeName and is a top level chlid*/
if(child.parentNode == el && child.nodeName.toLowerCase() == tag){
/*Set first matching child in case the rotation is already on the last image*/
if(!firstMatchingChild)
firstMatchingChild = child;
/*If child is visible */
if(child.style.display == "block"){
/*Take note that the visible element has been identified*/
visibleIdentified = true;
/*Toggle its visibility (display attribute)*/
child.style.display = "none";
/*Once the visibile item has been identified*/
}else if(visibleIdentified){
/*If the next item to become visible has been set*/
if(hasBeenSet){
/*Toggle visibility (display attribute)*/
child.style.display = "none"
}
/*Catch the next item to become visible*/
else{
/*Toggle visibility (display attribute)*/
child.style.display = "block";
/*Take note that the next item has been made visible*/
hasBeenSet = true;
}
}
}
}
/*If the hasBeenSet is false then the first item is to be made visible
- Only do so if the firstMatchingChild was identified, more or less redundant
exception handling*/
if(!hasBeenSet && firstMatchingChild)
firstMatchingChild.style.display = "block";
}
/*Declare cycle*/
setInterval("rotate('test','div')",1000);
</script>
</head>
<body>
<!-- Example container -->
<div id="test">
<div style="display:block">fire</div>
<div style="display:none">water</div>
<div style="display:none">shoe</div>
<div style="display:none">bucket</div>
</div>
</body>
</html>
Your specific question I haven't seen before, but your basic premise has been asked many times. The reason why you can't find a call like
rotate('<img src="1" />', '<img src="2" />');
is because it is a bad idea according to programming practices. You are mixing content with script. Client-side web design relies on sandboxing certain features to speed development and make debugging easier. Content, Styling and Scripting are the major areas. Here you mix content (images) with scripting. You should really use one of the many existing image rotation scripts that rely on taking existing markup and rotating them.
<img src="a" />
<img src="b" />
<script>rotateImages();</script>
If you want to do it your way then you will need to parse your strings and then create element nodes based on them. Honestly I don't think its worth the time to code one up in that format unless this is for curiosity's sake.
I am going to answer my own question as I came up with solution by my own. Sorry if I did not explain well and I hope it could be useful to someone as well. I had to avoid jQuery for a special reason, sometimes its just has to be that way. Here is the code, feel free to comment and improve... a working version is here http://jsbin.com/oxujuf/3
function rotator(options) {
var a = options.delay;
var b = options.media;
var mediaArr = [];
for(var i = 0, j = b.length; i < j; i++) {
mediaArr.push(b[i].img);
}
document.write('<div id="rotatorContainer"></div>');
var container = document.getElementById('rotatorContainer');
var Start = 0;
rotatorCore();
function rotatorCore() {
Start = Start + 1;
if(Start >= mediaArr.length)
Start = 0;
container.innerHTML = mediaArr[Start];
setTimeout(rotatorCore, a);
}
}
And then later you may call it like that, with a simple API.
rotator({
delay : 3500,
media : [{
img : '<img src="http://lorempixel.com/output/abstract-h-c-149-300-7.jpg" width="149" height="300" border="0" />'
}, {
img : '<img src="http://lorempixel.com/output/abstract-h-c-149-300-2.jpg" width="149" height="300" />'
}]
});
This is covered on many older forums and blogs.
Here are a couple links:
http://www.go4expert.com/forums/showthread.php?t=1012
http://www.reachcustomersonline.com/2008/03/19/09.38.04/?doing_wp_cron=1326819656

Categories

Resources