Changing image SRC using javascript - unknown error - javascript

I'm using javascript for the first time and am having difficulty getting certain features to work. Crucially I can't seem to get the following line of code to execute.
document.getElementByID("reportImage").src=filepath;
The full code is given below.
Notice that I've created a test function to try and narrow down the cause of the malfunction. The first two functions are there to demonstrate intent but are not currently being called by the .
The behavior of the test function suggests that the error is within this specific line. Notably the alert will fire if it is placed first in the function but will not trigger if placed second (suggesting that this specific line is problematic in some way).
It may be a simple syntax error but I've checked many times and can't see what it might be. Please help!
<!DOCTYPE html>
<html>
<script>
/* declare and set script variables */
var numberOfImages, imageArray, timing, containingFolder, i;
i = -1;
timing = 3;
containingFolder = "H:\\Images";
imageArray = [
"FoxKey.jpg",
"TeamKPI2.tif"
]; //imageArray should contain names of image files that sit within the specified folder
numberOfImages = imageArray.length;
function activateImageTimer() {
/* function iterates through selected images */
if (numberOfImages === timingArray.length) {
setInterval(nextImage(), timing*10);
}
else { alert("Please check contents of imageArray and timingArray. The
number of images should correspond to the number of timings."); }
}
function nextImage() {
i = (i+1) % numberOfImages; //use modulus function to loop through array
var filepath = containingFolder + "\\" + imageArray[i]; //build filepath
document.getElementByID("reportImage").src=filepath;
}
function testFunction() {
document.getElementByID("reportImage").src="H:\\Images\\FoxKey.jpg";
alert("Function is functioning");
}
</script>
<body onload="testFunction()">
<img id="reportImage" src="H:\Images\TeamKPI2.tif">
</body>
</html>

JavaScript is Case Sensitive.
Try with this:
Change: document.getElementByID to document.getElementById
And, <script></script> it has to be put inside the body or head, not of html.

Related

Javascript: how to execute a function within a function without delay?

I'm trying to make an automated image gallery using javascript to paste img-statements (+ some extras for css) into html.
All the images are in the same folder and are named image (1), image (2), ... Apparently client side can't know the name of the files in the folder nor the amount of files.
The append-process works fine, but I can't find a way to stop without giving the amount of pictures myself.
I'm trying to stop the append-process using ".onerror" when the browser can't find the next image, but it is always skipped until the end (resulting in an infinite loop (I'm using a "i<=6" for testing)).
Thanks! Here is my code:
function showgallery() {
let flag = true;
let i = 1;
while (i <= 6 && flag) {
$("#fotos").append(`<div class="cssbox">
<a id="image${i}" href="#image${i}"><img id="picture${i}" class="cssbox_thumb" src="../photogallery/image (${i}).jpg">
<span class="cssbox_full"><img src="../photogallery/image (${i}).jpg" /></span>
</a>
<a class="cssbox_close" href="#void"></a>
<a class="cssbox_prev" href="#image${i-1}"><</a>
<a class="cssbox_next" href="#image${i+1}">></a>
</div>`);
document.getElementById(`picture${i}`).onerror = () => {
flag = false;
}
i++;
}
}
window.onload = showgallery;
The reason why it's skipping some is because it takes time to load each image and for onerror to be called, yet you are doing this all in a loop which executes all the code without waiting for the error, so even if there is an error the flag variable won't be changed until the error event is fired, which happens after the current loop cycle
The way to do this instead is use recursion, if a certain condition is not met yet. Also I would recommend using Image for testing then appending it to the document
Also you don't even need error you can just only append it if it loads successfully
So you can use recursion here like
var cur = 0
function getImg() {
var img= new Image ()
img.src = "image (" + (cur++) + ").jpg"
img.onload = () => {
fotos.appendChild(img)//or other span elements etc that have img as a child
getImg()
}
//if you want to know when it ended then you can use .onerror
img.onerror = () => console.log("done")
}
getImg()

Javascript Object changing from typed element to arraybuffer

Client Side Javascript scenario: Choosing multiple files in a single window to upload. Storing selected files in:
var SelectedFile={};
using the element name as a key. I am pushing elements into the object using:
SelectedFile[event.srcElement.name]=event.target.files[0];
which is inside a function call. Variable scope of SelectedFile is global to the function.
Inside of this function, all elements of SelectedFile are visible as "File" objects.
When I access SelectedFile from another function, the elements are now "ArrayBuffer" and I have lost all keys and sub-objects within the File instances.
How to I ensure that the elements of "SelectedFile" stay as "File" objects at all times?
"use strict";
window.addEventListener("load", Ready);
var SelectedFile={};
function Ready() {
if(window.File && window.FileReader) {
document.getElementById('UploadButton').addEventListener('click', StartUpload);
$(".upreel").each(function(idx,obj) {
obj.addEventListener('change', function(event) {
console.log(event.target.files[0]);
SelectedFile[event.srcElement.name]=event.target.files[0]; console.log(SelectedFile[event.srcElement.name]);
console.log(SelectedFile);
});
});
} else {
document.getElementById('UploadArea').innerHTML="Your Browser Doesn't Support The File API. Please Upade Your Browser";
}
}
var socket=io.connect('http://localhost:3000');
var FReader;
var Name;
function StartUpload() {
$(".upreel").each(function (index) {
console.log(index);
});
console.log(SelectedFile);
for (var a in SelectedFile) {
console.log(SelectedFile[a]);
};
socket.emit('StartMultiple',{SelectedFiles:SelectedFile});
}
Don't seem able to replicate the behaviour here either. Using Chrome 53.0.2785.143 m (64-bit) under Windows 7.
This code appears to duplicate yours, albeit without the use of jQuery.
Also, I notice that while the console output appears to indicate SelectedFile to be an object that contains 2 ArrayBuffer members, this is not backed-up by the output of console.log(SelectedFile[a]); - I'm not so sure I'd be inclined to think the console output to be correct. If you can still use the objects as expected, I'd be looking for a reason to trust the console over my own observations.
The output I see is identical with the exception of the output of console.log(SelectedFile);, which gives the output of [reelfile1: File, reelfile2: File] as shown below.
The code required follows. Ironically enough, when run as a stack-snippet, the output is also incorrect, though is fine when using the native console, rather than the emulated one provided by StackOverflow. For this reason, I'll not post it as a snippet you can run on this page, just save as a new file instead.
<!doctype html>
<html>
<head>
<script>
"use strict";
function byId(id){return document.getElementById(id)}
function allByClass(clss,parent){return (parent==undefined?document:parent).getElementsByClassName(clss)}
// useful for HtmlCollection, NodeList, String types (array-like types)
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);
let SelectedFile = [];
function onDocLoaded(evt)
{
byId('uploadButton').addEventListener('click', onUploadBtnClicked);
var fileInputs = allByClass('upreel');
forEach(fileInputs, attachFileInputListener);
function attachFileInputListener(fileInputElem, index)
{
fileInputElem.addEventListener('change', onFileInputChanged, false);
}
}
function onFileInputChanged(evt)
{
console.log(this.files[0]);
SelectedFile[this.name] = this.files[0];
console.log(SelectedFile);
}
function onUploadBtnClicked(evt)
{
var fileInputs = allByClass('upreel');
forEach(fileInputs, showIndex);
console.log(SelectedFile);
for (var a in SelectedFile)
{
console.log(SelectedFile[a]);
console.log(SelectedFile[a].name);
}
function showIndex(elem, index, array)
{
console.log(index);
}
}
</script>
<style>
</style>
</head>
<body>
<input type='file' class='upreel' name='reelfile1'/><br>
<input type='file' class='upreel' name='reelfile2'/><br>
<hr>
<div id='UploadArea'></div>
<hr>
<button id='uploadButton'>Upload</button>
</body>
</html>
TLDR; - There doesn't actually seem to be a problem here, other than the display in the console.

Calling javascript function in html second time

Below is my code for a simple text based game that i am trying to make but i cannot understand why the first time i call my function with a hyperlink 'link1', it works but when i add another link to my html document using javascript, and try to call another function onclick upon that link, it doesn't work. can somebody explain?
var getupvar = document.getElementById("attack");
getupvar.onclick = attack;
function attack() {
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
}
var link2event = document.getElementById("defend");
link2event.onclick = defend;
function defend() {
alert("working now");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="console">
<p id="startGameMessage"></p>
<div id="gameArea">
<p id="gameMessage">Some Text</p>
link1
<div id="placeHolder"></div>
</div>
</div>
When you link up your attack onclick, the element exists. But because #defend does not exist on the dom when you run var link2event = document.getElementById("defend");, your onclick never gets set.
Instead try:
var getupvar = document.getElementById("attack");
getupvar.onclick = attack;
function attack(){
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
var link2event = document.getElementById("defend");
link2event.onclick= defend;
}
function defend(){
alert("working now");
}
jsfiddle https://jsfiddle.net/fv9mpbm6/
This will get your code working how you wish. If you don't do so, your code cannot work because the two lines added to the attack() function will be executed when you call the .js file in your html document as a script and not as a function. This means that the method getElementById("defend") will not find anything, because when you initialize the page, you cannot find any element with this id, you create it when you click on the link.
But do note that if you click attack more than once, your code will break because there will be more than one defend element.
When creating dynamic content, never use ids for handlers! Use classes instead
function attack() {
$('link2').insertBefore("#placeHolder");
}
Also, to ensure proper handling for elements that may not exist yet, leverage jquery's on functionality
$('body').on('click', '.defend', function() {
alert("working now")
})
it is simple, just put the two lines of code
var link2event = document.getElementById("defend");
link2event.onclick= defend;
inside the attack() function, at the end,and it works. This is the new attack() function:
function attack(){
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
var link2event = document.getElementById("defend");
link2event.onclick= defend;}
If you don't do so this code cannot works because these two lines will be executed when you call the .js file in your html document as a script and not as a function. This means that the method getElementById("defend") will not find nothing, because when you initialize the page, you cannot find any element with this id, you create it when you click on the link.
I hope that this helps!
Cheers!
Try this, I am not sure is this what you expect
var getupvar = document.getElementById("attack"), i=0;
getupvar.onclick = attack;
function attack() {
$('<p> Some text </p>').insertBefore("#placeHolder");
$('link2').insertBefore("#placeHolder");
var link2event = document.getElementById("defend"+i);
link2event.onclick = defend;
i++;
}
function defend() {
alert("working now");
}

JavaScript, How to change the background of a div tag every x seconds

I'm trying to make some JavaScript code to change the background of two div tags every X seconds. Here is my code:
HTML
<div id="bg_left"></div>
<div id="bg_right"></div>
CSS
body{
height:100%;
}
#bg_left{
height:100%;
width:50%;
left:0;
position:fixed;
background-position:left;
}
#bg_right{
height:100%;
width:50%;
right:0;
position:fixed;
background-image:url(http://presotto.daterrawebdev.com/d/img/pp_hey_you_bg.png);
background-position:right;
}
JAVA SCRIPT
function carousel_bg(id) {
var bgimgs = [ 'pp_hey_you_bg.png', 'burningman_bg.png' ];
var img1 = bgimgs[id];
var img2 = bgimgs[id+1];
var cnt = 2;
$('#bg_left').css("background-image", "url(http://presotto.daterrawebdev.com/d/img/"+img1+")");
$('#bg_right').css("background-image", "url(http://presotto.daterrawebdev.com/d/img/"+img2+")");
id = id + 1;
if (id==cnt) id = 0;
setTimeout("carousel_bg("+id+")", 10000);
}
$(document).ready(function() {
carousel_bg(0);
});
​
The background-images should be changing randomly, but they don't even change at all.
OK, I see the issue in your jsFiddle. Because you're passing a string to setTimeout() that string will be evaluated only at the top level scope. But, the function name you were passing is not at the top level scope (it's in an onload handler for the jsFiddle). So, I changed the way your JS is positioned in the jsFiddle so it is now at the top level scope. I also fixed up the logic for selecting an image and it now works here: http://jsfiddle.net/jfriend00/awVYP/
And, here's a cleaned up version that does not pass a string to setTimeout() (a much better way to write javascript) that passes a local function and uses a closure to keep track of the current index: http://jsfiddle.net/jfriend00/LVGNN/
function carousel_bg(id) {
var bgimgs = [ 'pp_hey_you_bg.png', 'burningman_bg.png' ]; // add images here..
function next() {
if (id >= bgimgs.length) {
id = 0;
}
var img1 = bgimgs[id];
id++;
if (id >= bgimgs.length){
id = 0;
}
var img2 = bgimgs[id];
$('#bg_left').css("background-image", "url(http://presotto.daterrawebdev.com/d/img/"+img1+")");
$('#bg_right').css("background-image", "url(http://presotto.daterrawebdev.com/d/img/"+img2+")");
setTimeout(next, 1000);
}
next();
}
$(document).ready(function() {
carousel_bg(0);
});
Previous comments on earlier version so of the OP's code:
$('#body')
should be:
$('body')
or even faster:
$(document.body)
Also, your jsFiddle shows a bit of an odd issue. Your CSS has a background image on the HTML tag, but your javascript sets a semi-transparent background image on the body tag. Is that really what you want?
For testing I added another image to the array so that we got some distinction in the sorting.
function carousel_bg(id) {
var bgimgs = [ 'http://presotto.daterrawebdev.com/d/img/pp_hey_you_bg.png', 'http://presotto.daterrawebdev.com/d/img/burningman_bg.png', 'http://gallery.orobouros.net/var/albums/2012/NewYorkComicCon2012/Legend-of-Korra/nycc_20121013_164625_0041.jpg?m=1354760251' ]; // add images here..
var img1 = bgimgs[id+1];
var img2 = bgimgs[id];
var cnt = bgimgs.length; // change this number when adding images..
$('#bg_left').css("background-image", "url("+img1+")");
$('#bg_right').css("background-image", "url("+img2+")");
id = id + 1;
if (id== (cnt - 1) ) id = 0;
setTimeout("carousel_bg("+id+")", 10000);
}
Two changes here:
For your total image count, I am retrieving the total count of images in the array dynamically instead of by hand (bgimgs.length)
In your conditional to reset the id value, subtract the total count by 1. Since JS has zero-based indexes, not doing this will get you an undefined error (a 3 item array will spit out a value of 4 in your original code on the last iteration).
While this code does loop through your array, it's not random. That's another topic.
For those not using JQuery, simply do the following:
document.body.style.backgroundImage="url(images/mybackgroundimage.jpg)";

JavaScript Timed Image Swap Need Help

So in my script I have...
<script type="text/javascript">
var images = new Array();
var numImages = 3;
var index = 0;
function setupSwapper() {
for (i = 0; i < numImages; i++) {
images[i] = new Image(266, 217);
images[i].src = "images/image" + i + ".png";
}
setTimeout("swapImage()", 5000);
}
function swapImage() {
if (index >= numImages) {
index = 0;
}
document.getElementById('myImage').src = images[index].src
index++;
setTimeout("swapImage()", 5000);
}
</script>
And then I have <body onload="setupSwapper()"> to setup the body.
and <img width=266 height=217 id="myImage" name="myImage" src="images/image0.png"></img> elsewhere in my document.
Only the initial image (image0.png) is showing up. I'm probably blind from having looked at this so long. The images are not swapping.
Use FireBug or a similar tool for debugging what's going on:
Does the img DOM element in fact gets its src changed ?
Do you see any network activity trying to load the images ? does it succeed ?
Set up breakpoints in your code and see what happens in the debugger
BTW - You can use setInterval instead of setTimeout - it sets a repeating timer
You're missing the () in the definition of "setupSwapper".
Also it's setTimeout, not setTimeOut.
Finally, get rid of the "type" attribute on your <script> tag.
You might want to start "index" at 1 instead of 0.
The way to go:
setTimeout(swapImage, 5000);
[FORGET] the type attribute has nothing to do with it
[FORGET] the index has nothing to do with it
[OPTIONAL] remove "name" attribute from the image (useless)
[OPTIONAL] close image tags like <img />
Note: 2-5 is about correctness. Only the first one is important to get it work.
Get Firebug, use it's debugger to put breakpoints inside swapImage to see if it is hit after the timeout. Another way is to use the console.* apis to see what's happening(e.g. console.log).

Categories