I have a program that should pick a random line from a local text file, but it seems to not be working.
Here's the code:
<html>
<head>
<script src="http://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<h1 id = "gen">Alt Info: </h1>
<script>
function readTextFile(file)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
var split = allText.split('\n')
var randomNum = Math.floor(Math.random() * split.length);
var randomLine = split[randomNum]
console.log("All Lines\n"+allText)
console.log("Line Numebr\n"+(randomNum+1))
console.log("Random Line\n"+randomLine)
}
}
}
rawFile.send(null);
}
readTextFile("alts.txt");
</script>
<button type="button" class=button onclick=document.getElementById("gen").innerHTML = randomLine;>Generate</button>
The code above should pick a random line from the 'alts.txt' text file and then when the generate button is clicked it should display that random line to the screen. Instead when I click the generate button, nothing happens.If someone could help me that would be awesome!
Your button is using an inline handler that's trying to reference a variable not in the global scope.
Inline event handlers are essentially eval inside HTML markup - they're bad practice and result in poorly factored, hard-to-manage code. Seriously consider attaching your events with JavaScript, instead, eg: https://developer.mozilla.org/en/DOM/element.addEventListener
The other problem is that #showText does not exist - just remove that line from your script.
You have a couple options here. One is to make randomLine a global variable so that it can be referenced by the button on demand - which isn't recommended:
<script>
var randomLine;
function readTextFile(file)
// ...
var randomNum = Math.floor(Math.random() * split.length);
randomLine = split[randomNum]
But in addition to that, it would be better to remove the inline handler, and add a click listener to the button properly:
document.querySelector('button').addEventListener('click', () => {
document.getElementById('gen').textContent = randomLine;
});
Or, even better, don't create a global variable at all; keep the line defined only where it's needed, which is inside the listener:
(() => {
var randomLine;
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "alts.txt", false);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4) {
if (rawFile.status === 200) {
var allText = rawFile.responseText;
var split = allText.split('\n')
var randomNum = Math.floor(Math.random() * split.length);
randomLine = split[randomNum]
console.log("All Lines\n" + allText)
console.log("Line Numebr\n" + (randomNum + 1))
console.log("Random Line\n" + randomLine)
}
}
}
rawFile.send(null);
const gen = document.getElementById('gen');
document.querySelector('button').addEventListener('click', () => {
if (randomLine) gen.textContent = randomLine;
else gen.textContent = 'Not retrieved yet';
});
})();
(or use fetch and Promises to handle the asynchronicity instead)
Related
I think my javascript in my php file is in conflict with my javascript file.
I have a script that checks of the image is smaller then 2MB and a script that shows the image you selected in a small version. But the second part does not work when the first script is active. how do I fix this?
script in HTML
<script>
window.onload = function() {
var uploadField = document.getElementById("frontImages");
uploadField.onchange = function() {
if(this.files[0].size > 2000000){
alert("File is too big!");
this.value = "";
};
};
var uploadField = document.getElementById("itemImages");
uploadField.onchange = function() {
if(this.files[0].size > 200){
alert("File is too big!");
this.value = "";
};
};
}
</script>
.js file
$("#frontImages").change(function () {
if ($('#frontImages').get(0).files.length > 0) {
$('#frontImages').css('background-color', '#5cb85c');
} else {
$('#frontImages').css('background-color', '#d9534f');
}
});
$("#itemImages").change(function () {
if ($('#itemImages').get(0).files.length > 0) {
$('#itemImages').css('background-color', '#5cb85c');
} else {
$('#itemImages').css('background-color', '#d9534f');
}
});
document.getElementById("frontImages").onchange = function () {
var x = document.getElementById('previewFrontImage');
x.style.display = 'block';
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById("previewFrontImage").src = e.target.result;
};
reader.readAsDataURL(this.files[0]);
};
function previewImages() {
var $preview = $('#previewItemImages').empty();
if (this.files) $.each(this.files, readAndPreview);
function readAndPreview(i, file) {
var reader = new FileReader();
$(reader).on("load", function () {
$preview.append($("<img/>", {src: this.result, height: 100}));
});
reader.readAsDataURL(file);
}
}
$('#itemImages').on("change", previewImages);
I'm guessing that the conflict is between the html script and this
document.getElementById("frontImages").onchange = function ()
I also have a question how I can fix that there will be no small image when the image is too big
Your guess is correct, onchange is simply member variable of various elements, and thus
var uploadField = document.getElementById("frontImages");
uploadField.onchange = function() {
and
document.getElementById("frontImages").onchange = function ()
are setting this single variable (of frontImages), which will store one callback function at a time.
You could use addEventListener() instead, which maintains a list of event listeners, so there can be more than one. Modifying the lines to
var uploadField = document.getElementById("frontImages");
uploadField.addEventListener("change", function() {
and
document.getElementById("frontImages").addEventListener("change", function ()
will register both event listeners on frontImages, regardless of the order they are executed.
Side remark: when you have "nice" ids, document.getElementById() can be omitted, as elements with ids become variables (of window which is the global scope), and thus you could write frontImages.addEventListener(...). You still need the getter in various cases, like when a local variable shadows the id, or when it is not usable as variable identifier (like id="my-favourite-id" or id="Hello World")
I'm trying to pass a callback function as an argument in a previous function that is triggered by a mouseup in a chrome extension. So basically I'm aiming to trigger the quickTranslate function right after the lwsGetText finishes running. But I can't figure out how to do this since the function lwsGetText is triggered by a mouseup. Here's my code:
Content Script (js)
(function () {
// Holds text being selected in browser
var lwsSelectedText = '';
// Adds pop-up to current webpage
function lwsAddContent(callback) {
// Get body tag
var body = document.getElementsByTagName('body');
// add invisible div
document.body.innerHTML += '<div id="myModal" class="modal"><div class="modal-content"><span class="close">×</span><div id="lwsSpanishDiv"><p id="lwsSpanishTitle">Spanish</p><textarea id="lwsSpanishTextArea">Hello</textarea></div><div id="lwsEnglishDiv"><p id="lwsEnglishTitle">English</p><textarea id="lwsEnglishTextArea">Hello 2</textarea></div></div></div>';
callback(lwsSetUpTextGetter);
}
// Make the pop-up visible and set up close button
function lwsActivateContent(callback) {
var modal = document.getElementById('myModal');
// Get the textarea
var txtarea = document.getElementById("myTxtArea");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function () {
modal.style.display = "none";
}
callback(quickTranslate);
}
// Initialize ability to select and grab text from browser
function lwsSetUpTextGetter(callback) {
//Set the onmouseup function to lwsGetText
document.onmouseup = lwsGetText;
//Handling clicking outside webpage?
if (!document.all) document.captureEvents(Event.MOUSEUP);
}
//Gets selected text
function lwsGetText(callback,e) {
// Get access to spanish text area
var spanishText = document.getElementById('lwsSpanishTextArea');
//Get text
lwsSelectedText = (document.all) ? document.selection.createRange().text : document.getSelection();
//if nothing is selected, do nothing
if (lwsSelectedText != '') {
// test: does browser grab text correctly?
alert(lwsSelectedText);
// Set spanish text area content to the selected text from browser
spanishText.value = lwsSelectedText;
// --Error Here--
callback();
}
}
function quickTranslate() {
alert("Quick Translate");
var url = "https://translate.yandex.net/api/v1.5/tr.json/translate",
keyAPI = "trnsl.1.1.20130922T110455Z.4a9208e68c61a760.f819c1db302ba637c2bea1befa4db9f784e9fbb8";
var englishTextArea = document.getElementById('lwsEnglishTextArea');
var spanishTextArea = document.getElementById('lwsSpanishTextArea');
englishTextArea.value = 'Working...';
var xhr = new XMLHttpRequest(),
textAPI = spanishTextArea.value,
langAPI = 'en';
data = "key=" + keyAPI + "&text=" + textAPI + "&lang=" + langAPI;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(data);
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var res = this.responseText;
var json = JSON.parse(res);
if (json.code == 200) {
englishTextArea.value = json.text[0];
}
else {
englishTextArea.value = "Error Code: " + json.code;
}
}
}
}
// When document ready
$(document).ready(function () {
lwsAddContent(lwsActivateContent);
});
})();
If someone could help me figure out how to implement the quickTranslate function as a callback function, that would be awesome! Thanks!
As you know the event handler you're assigning takes one parameter, the event. However you can create a closure around the "callback" variable by doing something like:
function lwsGetText(callback) {
return function (e) {
// Get access to spanish text area
var spanishText = document.getElementById('lwsSpanishTextArea');
//Get text
lwsSelectedText = (document.all) ? document.selection.createRange().text : document.getSelection();
//if nothing is selected, do nothing
if (lwsSelectedText != '') {
// test: does browser grab text correctly?
alert(lwsSelectedText);
// Set spanish text area content to the selected text from browser
spanishText.value = lwsSelectedText;
// --Error Here--
callback();
}
};
}
You would then pass the value quickTranslate as the "callback" parameter when you set the handler, not sure how you're doing that so here is a guess:
myElement.addEventListener("mouseup", lwsGetText(quickTranslate));
Okay i am using AJAX to recive JSON data which contains information about what should happend next... basically i use a css class hide/show which i add/remove from the images/wrapper and the loading .png image
But even tho i add/remove show/hide om the image, then add a new image src and then add add/remove css classes on the new image.
Even tho i do it in this order sometimes when the hide/show classes are added it is still the old picture for a split second before it changes to the next image src
I have tried to put a 150 milli sec delay on the end but it still
function newImage(voteValue, imgValue, checked) {
if (checked == "") {
var innerVotingWrapper = document.getElementById('innerVotingWrapper');
innerVotingWrapper.innerHTML = "Du skal vælge en kategori";
console.log(checked);
} else {
var loadingWrapper = document.getElementById('loadingWrapper');
var imgSrc = document.getElementById('imgSrc');
var globalRating = document.getElementById('globalRating');
globalRating.classList.add("hide");
globalRating.classList.remove("show");
imgSrc.classList.add("hide");
imgSrc.classList.remove("show");
loadingWrapper.classList.add("show");
loadingWrapper.classList.remove("hide");
var http = new XMLHttpRequest();
var url = "pages/newImage.php";
var params = "voteValue=" + voteValue + "&imgValue=" + imgValue + "&checked=" + checked;
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function () {
if (http.readyState === 4 && http.status === 200) {
var jsonData = JSON.parse(this.responseText);
setTimeout(func, 1000);
function func() {
console.log(this.responseText);
console.log(jsonData.checked);
loadingWrapper.classList.add("hide");
loadingWrapper.classList.remove("show");
if (jsonData.imgSrc) {
imgSrc.src = jsonData.imgSrc;
}
if (jsonData.id) {
var imgValue = document.getElementById('imgValue');
imgValue.value = jsonData.id;
}
if (jsonData.empty) {
console.log('Ikke flere billeder');
var innerVotingWrapper = document.getElementById('innerVotingWrapper');
innerVotingWrapper.innerHTML = "Du har votet alle billeder kom tilbage om 24timer";
}
function showImg() {
globalRating.classList.add("show");
globalRating.classList.remove("hide");
imgSrc.classList.add("show");
imgSrc.classList.remove("hide");
}
setTimeout(showImg, 150);
}
}
};
http.send(params);
}
}
In think the good solution it's to regenerate an img html tag.
By changing the img src do not force the navigator to upgrade it.
To generate an img tag do :
var newImg = document.createElement("img");
newImg.src = jsonData.imgSrc;
then you need to remove imgSrc and add the newImg.
var parent = imgSrc.parentNode;
parent.appendChild(newImg);
parent.removeChild(srcImg);
I need an image to change when it's clicked and to load a URL without anything visual changing on the page. I only need a total of two images and each image will be associated with one URL. I was able to replicate the example of onclick image change located at:
http://www.paulgriffiths.net/program/javascript/otherbasic1.php
For example: I want the image of the earth to change to mars and load URL #1. Then when mars is clicked on I want it to load back the picture of earth and load URL #2. I want the URL to load in the background and not change the images of earth and mars.
What do I add to the ".js" file below to accomplish this?
var newsrc = "mars.jpg";
function changeImage() {
if ( newsrc == "mars.jpg" ) {
document.images["pic"].src = "/images/program/js/forms/mars.jpg";
document.images["pic"].alt = "Mars";
newsrc = "earth.jpg";
}
else {
document.images["pic"].src = "/images/program/js/forms/earth.jpg";
document.images["pic"].alt = "Earth";
newsrc = "mars.jpg";
}
}
I used a boolean instead of testing strings but this should help you.
function loadCommand(url) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// if successfull
} else {
// if not successfull
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
var isOn = false;
var img = document.getElementById("pic");
// change handler
var loadImage = function() {
if (isOn) {
loadCommand("http://x.x.x.x/cmd/DOFF");
img.src = "/images/program/js/forms/mars.jpg";
img.alt = "Mars";
} else {
loadCommand("http://x.x.x.x/cmd/DON");
img.src = "/images/program/js/forms/earth.jpg";
img.alt = "Earth";
}
};
// set up event handler
img.onclick = function() {
// potentially send window to new location with window.location=<host>/cmd/DOFF or something similar
// or just change state
isOn = !isOn;
loadImage();
};
// load initial image
loadImage();
I have some troubles to read a number from a text file with JavaScript.
setInterval("readTextFile()", 500);
function readTextFile() {
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "zoom.txt", false);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4) {
if (rawFile.status === 200 || rawFile.status == 0) {
var allText = rawFile.responseText;
document.getElementById('boldStuff').innerHTML = allText;
writeln(allText);
}
}
}
rawFile.send(null);
}
The goal is to read a value into zoom.txt every 500ms, but this code doesn't work.
The value from the text file isn't refresh on F5 but only when I open (or refresh) zoom.txt in my browser.
I find something strange, this code works the first time I used it on Midori. Could you help me please ?
Thanks,
EDIT :
I tried that :
setInterval(readTextFile, 500);
setInterval(test, 500);
function readTextFile()
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "zoom.txt", false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
document.getElementById('boldStuff').innerHTML = allText;
}
}
}
rawFile.send(null);
}
function test(){
document.getElementById('boldStuff').innerHTML = '';
}
My value is blinking on the screen but don't change even if I modify it.
First parameter to the setInterval should be a function and not function call.
setInterval(readTextFile, 500); //No need of quotes
If it is fetching the data from the text file on page refresh means that your code is working fine.
Now, you need to change the text in your text file so that it will get new value from the text file.
To check the content every interval you need to empty the html of your div like,
function readTextFile() {
// empty the div first to get the new value from text file
document.getElementById('boldStuff').innerHTML = '';
...
Okay, I empty the cache of Firefox and avoid to use it and the code is working fine.