How to access 2 different HTML files from 1 JS file? - javascript

I have two HTML pages and one JS file, which does the logic for both of them. When I try to change an image dynamically in one of my HTML files using var mainImage = document.getElementById("lastImageID"); this works, but when I try to do the same thing for the other HTML file, it doesn't (I receive null as a result).
I have "included" <script type="text/javascript" src="controller.js"></script> the JS file in both HTML files.I also tried to find information here, in Stack Overflow, how to access an element in an HTML file other than using the document notation, but seems this is the only right way.
I also checked and there are no identical IDs in both files.
First HTML file (relevant code):
<div class="thumbnail">
<img id="mainImageId" src="img/decision.jpg"
alt="Decision">
</div>
<div class="textMessage">
<div id="messageToUserID" class="infoText">
<h5>some text</h5>
</div>
</div>
Second HTML file (relevant code):
<div class="thumbnail">
<img id="lastImageID"
src="img/congratulations.jpg"
alt="Decision">
</div>
<div class="textMessage">
<div id="lastMessageToUserID" class="infoText">
<h5>some text</h5>
</div>
JavaScript Code:
// A function, which receives an new image, and updates the main image of the simulation by it.
function updateImageInLastScreen(newImage){
var mainImage = document.getElementById("mainImageId");
mainImage.src = newImage;
var lastImage = document.getElementById("lastImageID");
lastImage.src = newImage;
}
// A function, which receives an new message, and updates the main message of the simulation by it.
function updateMessageInLastScreen(newMessageToUser){
var mainMessageToUser = document.getElementById("messageToUserID");
messageToUserID.innerHTML = newMessageToUser;
var lastMessageToUser = document.getElementById("lastMessageToUserID");
lastMessageToUser.innerHTML = newMessageToUser;
}
The access to the elements in the first file work, but to those in the second one do not...
Here are 4 small files I am working with

Try adding if checks before manipulating the content:
// A function, which receives an new image, and updates the main image of the simulation by it.
function updateImageInLastScreen(newImage){
var mainImage = document.getElementById("mainImageId");
if (mainImage) {
mainImage.src = newImage;
}
var lastImage = document.getElementById("lastImageID");
if (lastImage) {
lastImage.src = newImage;
}
}
// A function, which receives an new message, and updates the main message of the simulation by it.
function updateMessageInLastScreen(newMessageToUser){
var mainMessageToUser = document.getElementById("messageToUserID");
if (mainMessageToUser) {
messageToUserID.innerHTML = newMessageToUser;
}
var lastMessageToUser = document.getElementById("lastMessageToUserID");
if (lastMessageToUser) {
lastMessageToUser.innerHTML = newMessageToUser;
}
}

So...I dont understand very well. Tell me if my explanation is equal your problem.
I have created page1.html
<h1>Image 1</h1>
<img src="" alt="image one" style="width:304px;height:228px;" id="image1">
<script src="myfile.js" type="text/javascript"></script>
Then, I have created page2.html
<h1>Image 2</h1>
<img src="" alt="image two" style="width:304px;height:228px;" id="image2">
<script src="myfile.js" type="text/javascript"></script>
In myfile.js I put the one piece image
var image1 = document.getElementById('image1');
var image2 = document.getElementById('image2');
if( image1) image1.src = 'image.jpg';
if( image2 ) image2.src = 'image.jpg';
This way is your problem ? Here, this way works both images.

when you call the same function updateImageInLastScreen() for the second html this line var mainImage = document.getElementById("mainImageId"); gets the value as null (since 'mainImageId' is not there in second html) and the second statement after it mainImage.src = newImage; throws an exception saying
TypeError: Cannot set property 'src' of null
at updateImageInLastScreen
and stops the further execution. You can verify the same in F12 console.
But when you call it from the first html then also it throws an exception for lastImage.src = newImage; but since it comes after the mainImage it's getting updated.
As per your code it's obvious that either of the element will be null since it's being called from a single html file. And you are blindly looking for the availability of the second element.
You can overcome this by putting your code inside a try..catch block as
function updateImageInLastScreen(newImage){
try{
var mainImage = document.getElementById("mainImageId");
mainImage.src = newImage;
}
catch(e){
console.log(e);
}
try{
var lastImage = document.getElementById("lastImageID");
lastImage.src = newImage;
}
catch(e){
console.log(e);
}
}
you can find it working here https://jsfiddle.net/hk30k20t/1/

Related

Loading an img object with a src in javascript

I want to add a thumbnail picture to a book's details, derived from the google books api, on the webpage. The code below will place the source code (api) for the appropriate book, first into the text field bookCover and then into the var copyPic, and then it should be copied into imgDisp, but it doesn’t. I can see that bookCover holds the right text, and have checked that copyPic holds the correct content.
<img id="imgDisp" src="http://books.google.com/books/content?
id=YIx0ngEACAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api" width="85" height="110"" />
$.getJSON(googleAPI, function(response) {
$("#title").html(response.items[0].volumeInfo.title);
$("#subtitle").html(response.items[0].volumeInfo.subtitle);
$("#author").html(response.items[0].volumeInfo.authors[0]);
$("#description").html(response.items[0].volumeInfo.description);
$("#version").html(response.items[0].volumeInfo.contentVersion);
$("#modeR").html(response.items[0].volumeInfo.readingModes.text);
$("#bookCover").html(response.items[0].volumeInfo.imageLinks.thumbnail);
var copyPic = document.getElementById('bookCover').innerHTML;
document.getElementById("imgDisp").src=copyPic;
Does anyone know why not? Or can I put the api details directly into imgDisp (can’t find such code syntax anywhere on the net)? Everything else is working fine. If I put a src in directly, then it works e.g.
document.getElementById("imgDisp").src = “http://.....api”
but not with a variable.
Without more info - eg, I can't see where the getJSON() function ends or what the URL's are, I can't see what the issue may be (except, perhaps, as in my last comment).
I idea seems ok, as I can replicate it (in a cut-down version of course):
function copyImageSource() {
let d = document.getElementById("bookCover").innerHTML;
document.getElementById("imgDisp").src = d;
}
<button onclick="copyImageSource();">Get image</button>
<div id="bookCover">https://duckduckgo.com/assets/icons/meta/DDG-icon_256x256.png</div>
<img id="imgDisp" src="">
I assume that this is the sort of thing you are trying to achieve?
(javascript -> jquery:
let copyPic = $("#bookCover").html();
$("#imgDisp").attr("src", copyPic);
)
Version using jquery:
function copyImageSource() {
let d = $("#bookCover");
d.html("http://books.google.com/books/content?id=YIx0ngEACAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api");
let dCopy = d.html().replace(/&/g, "&");
$("#imgDisp").attr("src", dCopy);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick="copyImageSource();">Get image</button>
<div id="bookCover"></div>
<img id="imgDisp" src="https://www.picsearch.com/images/logo.png"/>
If you have jQuery you can easily do the following:
let source = 'https://img.com/image.png';
//to get the image object that has the above just do this:
let img = $('img[src="' + source + '"]');

How to have multiple JW players on same page

JS Fiddle of what's happening
https://jsfiddle.net/n1tvx49x/1/
I don't have id attribute. Will it work without that. With id its working fine.
Here is my following HTML. It consists of outter figure tag and inside that there is div tag and inside that have another div tag with class="jw-player".
I can't change my HTML
<figure data-embed-type="jwplayer" data-embed-url="video-url1" data-embed-loaded="false">
<div itemscope="" itemtype="http://schema.org/VideoObject">
<div data-embed-url="video-url1" class="jw-player"></div>
</div>
</figure>
<figure data-embed-type="jwplayer" data-embed-url="video-url2" data-embed-loaded="true">
<div itemscope="" itemtype="http://schema.org/VideoObject">
<div data-embed-url="video-url2" class="jw-player"></div>
</div>
</figure>
I want to embed JWPlayer videos inside both of these divs. $node has the figure element whole.
var videoObject = $node.querySelector('.jw-player');
var playerInstance = window.jwplayer(videoObject);
window.player1 = playerInstance;
playerInstance.setup({
file: 'video-url1',
mediaid: 'asd34',
image: 'jpg-url1'
});
and another
var videoObject = $node.querySelector('.jw-player');
var newplayerInstance = window.jwplayer(videoObject);
window.player2 = newplayerInstance;
newplayerInstance.setup({
file: 'video-url2',
mediaid: 'asder3',
image: 'jpg-url2'
});
I am getting only one JW Player on my screen. Because the second one is also replacing the first div only. And 2nd div is not getting changed. And when I am comparing the two instances on console, I am getting result as equal.
player1 === player2
true
You could add an ID using JavaScript before creating the player.
var videoObject = document.querySelector("div[data-embed-url='video-url1']");
videoObject.id = "player-1";
var newplayerInstance = window.jwplayer(videoObject);
window.player2 = newplayerInstance;
newplayerInstance.setup({
file: 'video-url2',
mediaid: 'asder3',
image: 'jpg-url2'
});
var videoObject = document.querySelector("div[data-embed-url='video-url2']");
videoObject.id = "player-2";
var newplayerInstance = window.jwplayer(videoObject);
window.player2 = newplayerInstance;
newplayerInstance.setup({
file: 'video-url2',
mediaid: 'asder3',
image: 'jpg-url2'
});

How to access the Javascript variable value outside the script tag

I want to access the Javascript variable value outside the Javascript tag.
function getprices(input) {
return input.match(/[0-9]+/g);
}
var subtotals = get_getprices('%GLOBAL_OrderTotal%');
var Grand_total = subtotals[0];
<img height="0" width="0" border="0" src="http://testing.com?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount=I want the Grand+Total Value here">
You'd need to update the src property on that img element. Let's suppose you gave the img an id (you don't have to, there are other ways to select it, but I'm keeping it simple):
<img id="the-image" height="0" width="0" border="0" src="http://testing.com?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount=I want the Grand+Total Value here">
Then:
function getprices(input) {
return input.match(/[0-9]+/g);
}
var subtotals = getprices('%%GLOBAL_OrderTotal%%'); // <=== Changed to `getprices`, was `get_getprices`
var Grand_total=subtotals[0];
var img = document.getElementById("the-image");
img.src = "http://testing.com?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount=" + Grand_total;
It looks like Grand_total will always be a number, but for the general case where it might not be, , be sure to use encodeURIComponent (it doesn't do any harm even if it is a number):
img.src = "http://testing.com?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount=" + encodeURIComponent(Grand_total);
If you didn't use an id on the img, that's fine, you can use any CSS selector via document.querySelector. That's supported by all modern browsers, and also IE8.
Note that there are other issues with that code, though, not least that getprices looks fairly suspect.
All you need to do is to assign your value to src of img in your javascript
$("#imgNeeded").attr("src",".../"+Globalvalue)
As T.J. Crowder said. make sure you encode URI if your variable contain something other than number
You can use
document.getElementsByTagName("img")[***index of the image tag***].src = "<THE STRING>"+<THE VARIABLE>+"<THE REMAINING STRING>";
or assign an id to the <img> and use
`document.getElementById("id of the image").src = ""++"";
The problem the provided approaches share is, that how they are, your image will get loaded with the unwanted source before changed:
<html>
<head>
<script>
function getprices(input){return input.match(/[0-9]+/g)};
function changeSrc(){
var tE = document.querySelector("img[src*='saleAmount=']");
var tS = getprices('anyPrice1');
if (tE && tS) tE.src += encodeURIComponent(tS[0]);
};
</script>
</head>
<body onload = 'changeSrc()'>
<img height = '0' width = '0' border = '0' src = 'http://JUSTTOSHOWtesting.com?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount=' onerror = 'console.log(this.src)'>
</body>
Your console will log two calls:
- GET http://justtoshowtesting.com/?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount= net::ERR_NAME_NOT_RESOLVED
- GET http://justtoshowtesting.com/?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount=1 net::ERR_NAME_NOT_RESOLVED
So what you could do is placing a placeholder, until you have the source you need:
<html>
<head>
<script>
function getprices(input){return input.match(/[0-9]+/g)};
function createSrc(){
var tE = document.querySelector("ins[src*='saleAmount=']");
var tS = getprices('anyPrice1');
if (tE && tS){
var tI = document.getElementById('iPlaceholder');
if (!tI){
tI = document.createElement('img');
tI.id = 'iPlaceholder';
tI.onerror = function(){console.log(this.src)};
tE.parentNode.insertBefore(tI, tE.nextSibling);
};
tI.src = tE.getAttribute('src') + encodeURIComponent(tS[0]);
};
};
</script>
</head>
<body onload = 'createSrc()'>
<ins src = 'http://JUSTTOSHOWtesting.com?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount='></ins>
</body>
</html>
Now your console will merely log one call:
- GET http://justtoshowtesting.com/?merchantId=M1&orderNo=%%GLOBAL_OrderId%%&saleAmount=1 net::ERR_NAME_NOT_RESOLVED

Why is addEventListener only executing my function but not creating a mouseover/mouseon event for it?

I have an assignment and I can't seem to figure out this one part:
I have written a Javascript function to preload/precache two images for EACH image tag, from the "img" folder based on the ID of img-html tag. This part works fine.
However the function to change the image on mouseover and mouseout using addEventListener does not seem to work and I just can't seem to figure out why! If I debug, I can see the images are being loaded fine and there is no error. However on mouseover it just doesn't seem to work!
HTML Page:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="author" content="Nilay Panchal"/>
<meta name="description" content="Part 1 Assignment 3"/>
<title>HomePage</title>
<script src="js/breadcrumb.js"></script>
<script src="js/preloader.js"></script>
<script type="text/javascript">
function animal(name,scientificName,typeOfFood,sleepingPattern,size) {
this.name = {
realName:name,
scientificName:scientificName
};
this.typeOfFood = typeOfFood;
this.sleepingPattern = sleepingPattern;
this.size = size;
}
function makeNewAnimal(name, scientificName, typeOfFood,sleepingPattern,size) {
var animalClicked = new animal(name, scientificName, typeOfFood,sleepingPattern,size);
var finalStringObject = "{"+myOwnRecursiveToStringMethod(animalClicked,"")+"}";
document.getElementById("stringOfObject").value = finalStringObject;
var backToObject = parseStringAndConvertToObject(finalStringObject);
document.getElementById("jsonDisplay").value = backToObject;
}
function myOwnRecursiveToStringMethod(objectToParse, outputString) {
var first = 1;
for(nameOfProperty in objectToParse){
if(objectToParse[nameOfProperty] instanceof Object) {
outputString += nameOfProperty+":{";
outputString = myOwnRecursiveToStringMethod(objectToParse[nameOfProperty],outputString);
outputString += "},";
} else{
outputString = outputString + nameOfProperty +":'"+ objectToParse[nameOfProperty]+"',";
}
}
if(outputString.charAt(outputString.length-1) == ',') {
outputString = outputString.slice(0,-1);
}
return outputString;
}
function parseStringAndConvertToObject(finalString) {
eval("var backToObject = "+finalString);
return backToObject;
}
</script>
</head>
<body>
<h3>Navigation List:</h3>
<nav id="navigationBar" style="border-style: double ;border-width: 10">
<ul>
<li>Assignment 3 Root</li>
<li>All Animals
<ul>
<li>Insects.html</li>
<li>Birds-Aves
<ul>
<li>The Mighty Pelican</li>
</ul>
</li>
<li>The Tall Giraffe</li>
<li>The Hefty Rhinoceros</li>
</ul>
</li>
</ul>
</nav>
<div style="border-style:groove;padding-bottom: 10px;padding-left: 10px">
<h4><u>BREADCRUMB:</u></h4>
<div id="breadcrumb"></div>
</div>
<div style="text-align: center">
<h3><u>Please click on any of the images below and the JSON object of the animals data will be displayed in the text area below!</u></h3>
<img style="width:300px;height:300px" id='pelican' alt="Pelican"/>
<img style="width:500px;height:300px" id="rhino" alt="Rhinoceros"/>
<br>
<img style="width:500px;height:300px" id="giraffe" alt="Giraffe"/>
<img style="width:300px;height:300px" id='owl' alt="Owl"/>
</div>
<hr>
<h5>Animal Objects to String:</h5>
<textarea style="width:100%" id="stringOfObject"></textarea>
<h5>Animal Strings back to Objects</h5>
<textarea style="width:100%" id="jsonDisplay"></textarea>
</body>
<script type="text/javascript">
window.onload = precacheAndLoad();
makeBreadcrumb(location.pathname);
</script>
</html>
Javascript file:
/*
*
* Below I wrote a function to perform all the image operations and precaching too. To add a new image simply do the following:
* 1) Include, the JS file and add a new img tag on the HTML page. The ID of this img tag should be the name of the animal (eg. hippo).
* 2) Save two images named the same as the animal, with a suffix of 1 and 2 for default image and hover over image. (eg. hippo1.jpg and hippo2.jpg)
* The script will take care of the rest!
*/
var allImageVariables = new Array();
function precacheAndLoad() {
var allImages = document.getElementsByTagName("img");
for(imageCount=0; imageCount<allImages.length ; imageCount++) {
currentImageId = allImages[imageCount].id;
eval("var "+currentImageId+"1 = new Image(300,300)");
eval("var "+currentImageId+"2 = new Image(300,300)");
eval(currentImageId+"1.src = 'img/"+currentImageId+"1.jpg'");
eval(currentImageId+"2.src = 'img/"+currentImageId+"2.jpg'");
allImageVariables[imageCount] = eval(currentImageId+"1");
allImageVariables[imageCount+allImages.length] = eval(currentImageId+"2");
allImages[imageCount].src = eval(currentImageId+"1.src");
allImages[imageCount].addEventListener("mouseover", hoverImage(currentImageId,imageCount+allImages.length), false);
allImages[imageCount].addEventListener("mouseout", outImage(currentImageId,imageCount), false);
}
}
function hoverImage(currentImageId, arrayIndexOfImageVariable) {
eval("document.getElementById('"+currentImageId+"').src = allImageVariables[arrayIndexOfImageVariable].src");
}
function outImage(currentImageId, arrayIndexOfImageVariable) {
eval("document.getElementById('"+currentImageId+"').src = allImageVariables[arrayIndexOfImageVariable].src");
}
Because you're executing the function and passing the return result rather than passing a reference to the function when using addEventListener(). When you use () on the function name, it is executed immediately. To pass only a reference, you need to pass just the name of the function or if you need custom arguments like you have, then you need to create a shell function that you can pass.
Furthermore, you're trying to use for loop variables inside an event handler so you need to create a closure in order to preserve the value of those variables for the event handlers long after the for loop has completed:
Change this:
allImages[imageCount].addEventListener("mouseover", hoverImage(currentImageId,imageCount+allImages.length), false);
allImages[imageCount].addEventListener("mouseout", outImage(currentImageId,imageCount), false);
to this (line breaks added for readability):
(function(imageCount, currentImageId) {
allImages[imageCount].addEventListener("mouseover", function() {
hoverImage(currentImageId,imageCount+allImages.length);
}, false);
allImages[imageCount].addEventListener("mouseout", function() {
outImage(currentImageId,imageCount);
}, false);
})(imageCount, currentImageId);
Also, why in the world are you using eval() like you are. You can code without it and have much better code, better performing and, in some cases, safer.
For example, this:
eval("var "+currentImageId+"1 = new Image(300,300)");
eval("var "+currentImageId+"2 = new Image(300,300)");
eval(currentImageId+"1.src = 'img/"+currentImageId+"1.jpg'");
eval(currentImageId+"2.src = 'img/"+currentImageId+"2.jpg'");
Can be this:
var images = [];
images.push(new Image(300,300));
images.push(new Image(300,300));
images[0].src = 'img/'+currentImageId+'1.jpg');
images[1].src = 'img/'+currentImageId+'2.jpg');
Rather than declaring variables with eval(), you can use either an object or an array and put the dynamic variables into them and then reference them from there rather than by a straight variable name. This is a common way of creating dynamic variables.

Getting a function to actually output HTML

Have some JavaScript running that's dynamically building an array of images.
Here's the simplified version:
var imgArray = new Array(
"mainBG.jpg",
"mainBG2.jpg",
"mainBG3.jpg",
"mainBG4.jpg"
);
var img = Math.floor(Math.random()*imgArray.length);
jQuery(document).ready(function() {
$("body").ezBgResize({img : "/lib/img/bkgr/" + imgArray[img]});
});
function generateThumbs(){
var t = document.getElementById("thumbs");
var ret = '';
for(i=0;i<imgArray.length;i++){
var image = imgArray[i];
ret += '<a href="#" onclick="changeBig(\''+image+'\')" /><img src="/lib/img/bkgr/'+image+'" alt="thumbnail image" width="77" height="44" /></a>';
}
return ret;
};
function changeBig(bg){
$("body").ezBgResize({img : "/lib/img/bkgr/" + bg});
}
Then in the page, it's being written out simply with:
<div class="scrollable">
<div class="items" id="thumbs">
<script>document.write(generateThumbs());</script>
</div>
</div>
Problem is, when I view the source, it never outputs actual HTML. The source just shows that line. Is there a way to get that function to actually output HTML into the page-- partially for SEO, but also so some jQuery can interact with it
?
When you view source all you see is the code returned to the browser from the webserver without any modifcations javascript has done to the dom. To have the code in the raw source you need to generate it on the server side.
To see the generated source with the javascript modifications you can use firebug in firefox or the built in developer tools in Chrome/Safari/IE9.
This will do the trick
$(function(){
$("#thumbs").html(generateThumbs());
});
Don't call document.write in the context of an HTML page. You should be doing something like this:
<script type="text/javascript" language="javascript">
document.getElementById('thumbs').innerHTML = generateThumbs();
</script>
Try:
$('#thumbs').html(generateThumbs());

Categories