I'm working on a script which reads a text file and changes the text in an div depending on the content of the .txt file.
But that isn't my Problem. I don't want just plain text, the background color should change depending on which condition of the if/elseif/else function is fulfilled.
var client = new XMLHttpRequest();
client.open('GET', 'text.txt');
client.onreadystatechange = function checktxt() {
if(client.responseText =='not')
{
document.getElementById("response").innerHTML="Connect is working";
var boxgreen = document.querySelector("#response");
boxgreen.classList.add("green");
}
else if (client.responseText =='younger')
{
document.getElementById("response").innerHTML="Connect is working";
var boxgreen = document.querySelector("#response");
boxgreen.classList.add("green");
}
else
{
document.getElementById("response").innerHTML="Connect isn't working!";
var boxred = document.querySelector("#response");
boxred.classList.add("red");
}
}
client.send();
.green {
width: 140px;
height: 140px;
background: #68B267;
color: white;
}
.red {
width: 140px;
height: 140px;
background: #ec4f3e;
color: white;
}
<div id="response"></div>
My first try was to add a "classList.add" to the if/ else function, but even if the "if" condition is fulfilled it changes the class to "red" because it has been set at last.
I'm pretty new to javascript and have no experience with ajax or jquery but maybe that's what I'm looking for.
If the code has run already, you need to remove the classes that you have added.
client.onreadystatechange = function checktxt() {
With your code, you can just call
boxgreen.classList.remove("red"); //or green for the other case
and than it will work.
Or you can use toggle and simplify the code so you do not have the same lines over and over again.
client.onreadystatechange = function() {
var isValid = client.responseText == 'not' || client.responseText == 'younger',
text = isValid ? "Connect is working" : "Connect isn't working!",
box = document.querySelector("#response");
box.innerHTML = text;
box.classList.toggle("green", isValid);
box.classList.toggle("red", !isValid);
}
Related
I want to show and hide a picture by using one button. when it's clicked, the picture is displayed and a variable is set to 1. so that when you press the button the next time, the picture will be hidden again.
After the button is pressed, I console.log the value of set variable + if the picture is displayed or not. Console says that the Picture is "inline". But the picture is not on my screen.
I think all you need is the js function. If you need more information. just comment. thank's!
<script>
function showHideM(){
let open;
open = 0
if (open == 0){
open = 1;
document.getElementById("melmanId").style.display = "inline";
console.log(open)
console.log(document.getElementById("melmanId").style.display)
return;
}
if (open == 1){
open = 0;
document.getElementById("melmanId").style.display = "none";
}
}
</script>
You don't really need flags to maintain the state of the image's visibility. You can use classList's toggle method to toggle a class on/off or, in this case, visible/hidden, which makes things a little easier.
// Cache the elements, and add an event listener
// to the button
const img = document.querySelector('img');
const button = document.querySelector('button');
button.addEventListener('click', handleClick);
// Toggle the "hidden" class
function handleClick() {
img.classList.toggle('hidden');
}
.hidden { visibility: hidden; }
img { display: block; margin-bottom: 1em; }
button:hover { cursor: pointer; background-color: #fffff0; }
<img class="hidden" src="https://dummyimage.com/100x100/000/fff">
<button>Click</button>
Additional documentation
addEventListener
querySelector
Note: this will replace all the styles applied to 'melmanId'
<script>
let show = true;
function showHideM() {
show = !show;
if(show){
document.getElementById("melmanId").style.display = "inline";
}else{
document.getElementById("melmanId").style.display = "none";
}
}
</script>
I'm quite new to JS.
I want to have my html page stay the same when JS text will be appearing in one exact place without starting from blank page.
I trigger JS function via button on HTML, function in HTML:
function match () {
setTimeout(function () {
player_hp -= monster_dmg
monster_hp -= player_dmg
if (player_hp<=0) {
document.write("\nPlayer dies!")
menu();
return;
}
if (monster_hp<=0) {
document.write("\nPlayer wins!")
menu();
return;
}
if (fight=1) {
document.write("\nPlayer hp:" + player_hp)
document.write("\nMonster hp:" + monster_hp)
document.write("\n");
match()
}
}, interval)
}
One easy way to handle this is to simply create a <div> or a <span> element that has an ID attribute like this:
<div id="status"> </div>
Now you can access this element by using the Javascript method
document.querySelector("#status") and then use the innerHTML function of that element to change the internal content. You can even place the document.querySelector function into a convenient function which I have named send_status()
Here's the whole thing
/* default values */
var player_hp = 300;
var monster_dmg = 30;
var monster_hp = 200;
var interval = 500;
var player_dmg = 50;
match();
/* heres a function that will replace your document.write() functions */
function send_status(message) {
document.querySelector("#status").innerHTML = message;
}
function match() {
setTimeout(function() {
player_hp -= monster_dmg
monster_hp -= player_dmg
if (player_hp <= 0) {
send_status("\nPlayer dies!") // replaced document.write with send_status
menu();
return;
}
if (monster_hp <= 0) {
send_status("\nPlayer wins!")
menu();
return;
}
if (fight = 1) {
send_status("\nPlayer hp:" + player_hp)
send_status("\nMonster hp:" + monster_hp)
send_status("\n");
match()
}
}, interval)
}
function menu() {}
#game {
width: 100%;
height: 100px;
border: 2px solid black;
}
#status {
width: 100%;
height: 50px;
background-color: grey;
}
<div id="game">Game Goes Here</div>
<!-- here is your status area -->
<div id="status"></div>
You should create a results div, in which will be shown the match result.
Just add <div id="match_results"></div> in your HTML code.
And replace all yours document.write() for
document.getElementById('match_results').innerHTML += "<br>Player wins!"
This command is appending content in the element with ID match_results.
You should use <br> instead of \n because it is the proper way to break line in HTML code.
I have an HTML file, which I want to read and append as HTML. I have tried the below codes but these codes are not working.
Approach 1:
var file = "abc.html";
var str = "";
var txtFile = new File(file);
txtFile.open("r");
while (!txtFile.eof) {
// read each line of text
str += txtFile.readln() + "\n";
}
$('#myapp').html(str);
Approach 2:
var file = "abc.html";
var rawFile = new XMLHttpRequest();
alert('33333333');
rawFile.open("GET", file, false);
alert('44444');
rawFile.onreadystatechange = function () {
alert('5555555555');
if (rawFile.readyState === 4) {
alert('66666666666');
alert(rawFile.readyState);
if (rawFile.status === 200 || rawFile.status == 0) {
var allText = rawFile.responseText;
$('#myapp').html(allText);
alert(allText);
}
}
}
rawFile.send(null);
In Approach 2, it not going into the onreadystatechange method.
I thought another approach that I will use all the abc.html file content as a string variable and do similar $('#myapp').html(allText);, but this looks very bad approach because later I need to do the same for other 10-15 files. So Could you guys help me out?
Note: My application is running in offline mode means I cannot use the internet.
I have tried this solution, but its also not working.
It is not possible as JavaScript is frontend framework and it doesn't have access to local file system.
But you can do diffrent method.
-> you can serve that file in a local server and use http request with any backend framework.
I think you can adapt this pen to use as you wish:
https://codepen.io/alvaro-alves/pen/wxQwmg?editors=1111
CSS:
#drop_zone {
width: 100px;
height: 100px;
background: #000;
background-repeat: no-repeat;
background-size: 100px 100px;
opacity: 0.5;
border: 1px #000 dashed;
}
HTML:
<html>
<body>
<div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);">
</div>
</body>
</html>
JS:
//drop handler do XML
function dropHandler(ev) {
ev.preventDefault();
var file, reader, parsed, emit, x, endereco;
if (ev.dataTransfer.items) {
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
if (ev.dataTransfer.items[i].kind === 'file') {
file = ev.dataTransfer.items[i].getAsFile();
reader = new FileReader();
reader.onload = function() {
parsed = new DOMParser().parseFromString(this.result, "text/xml");
console.log(parsed);
};
reader.readAsText(file);
console.log('... file[' + i + '].name = ' + file.name);
}
}
}
removeDragData(ev)
}
function dragOverHandler(ev) {
ev.preventDefault();
}
function removeDragData(ev) {
if (ev.dataTransfer.items) {
ev.dataTransfer.items.clear();
} else {
ev.dataTransfer.clearData();
}
}
You will just to handle the result.
Essentially, I am trying to create a webpage that has 2 buttons; one will cause the screen to flash randomly, and the other will cause it to slowly change colours. I want to be able to switch between these two (if you press the first button it starts flashing and then if you press the second button it slowly changes without any kind of cancel button).
The buttons each call a function which sets the 'running' variable of the other function to false and it's own 'running' variable to true. It then calls a recursive function (recursive in that it just calls itself over and over). These recursive functions only execute their code when their 'running' variable is true.
If you run the snippet you can see that the program is very inconsistent (you may need to play with it for a bit to see the issue since it sometimes seems to work). Sometimes it refuses to change function and other times the two functions seem to both be active and they both try to execute (it almost looks as if they are fighting for control). I don't understand how this is happening since, I believe, only one of the 'running' variables can be true at any time.
var runningDisco = false;
var runningColours = false;
function startColours() {
if (runningDisco == true); //Is disco running?
{
runningDisco = false; //If yes, stop it
}
runningColours = true; //Indicate we are running
window.setTimeout(Colours, 100, 0); //Run
}
function startDisco() {
if (runningColours == true); {
runningColours = false;
}
runningDisco = true;
window.setTimeout(Disco, 100);
}
function Disco() {
if (runningDisco == true); {
hex = "#";
for (discoCount = 0; discoCount < 6; discoCount++) {
hex = hex.concat((Math.floor(Math.random() * 17)).toString(16));
}
document.body.style.background = hex;
window.setTimeout(Disco, 10);
}
}
function Colours(colourCount) {
if (runningColours == true); {
if (colourCount > 359) {
colourCount -= 359;
}
document.body.style.background = "hsl(" + colourCount + ", 50%, 50%)";
window.setTimeout(Colours, 10, colourCount + 1);
}
}
input {
font-family: 'Roboto', sans-serif;
text-align: center;
background-color: #dd1021;
border: none;
color: white;
padding: 16px 32px;
text-decoration: none;
margin: 4px 2px;
cursor: pointer;
}
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<input id="clickMe" type="button" value="Start Disco" onclick="startDisco();" />
<input id="clickMe" type="button" value="Start Colours" onclick="startColours();" />
The semicolons after your if-statements are causing a problem
For example, replace:
if (runningColours == true); {
if (runningDisco == true); {
with
if (runningColours == true) {
if (runningDisco == true) {
Here it is fixed in jsfiddle.
You have semicolons in the wrong place
If you need to run a single animation you need to use a single global variable to hold the timeout handler and clear it when starting a new one.
Like this:
var running;
function startColours() {
clearTimeout(running);
running = setTimeout(Colours, 100, 0); //Run
}
function startDisco() {
clearTimeout(running);
running = setTimeout(Disco, 100);
}
function Disco() {
var hex = "#";
for (discoCount = 0; discoCount < 6; discoCount++) {
hex = hex.concat((Math.floor(Math.random() * 17)).toString(16));
}
document.body.style.background = hex;
running = setTimeout(Disco, 10);
}
function Colours(colourCount) {
if (colourCount > 359) {
colourCount -= 359;
}
document.body.style.background = "hsl(" + colourCount + ", 50%, 50%)";
running = setTimeout(Colours, 10, colourCount + 1);
}
input {
font-family: 'Roboto', sans-serif;
text-align: center;
background-color: #dd1021;
border: none;
color: white;
padding: 16px 32px;
text-decoration: none;
margin: 4px 2px;
cursor: pointer;
}
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<input id="clickMe" type="button" value="Start Disco" onclick="startDisco();" />
<input id="clickMe" type="button" value="Start Colours" onclick="startColours();" />
The real problem is the semicolons after the if statements inside the Disco and Colours functions:
if (runningDisco == true); {
document.body.style.background = …
}
will execute as
if (runningDisco == true)
;
{
document.body.style.background = …
}
which runs the content regardless of the boolean variable. Why does it work at all sometimes? I guess when the two setTimeout callbacks run close enough to each other that only the latter is rendered at all it feels consistent. Of course that is very unstable - they are indeed fighting each other for screen time.
You made a common mistake to those new to JavaScript - including a semi-colon after you if header. This creates an if statement with no body that is followed by a block containing the single statement runningColours = false, which will not execute correctly. The below should fix this:
if (runningColours == true)
{
runningColours = false;
}
The following JSFiddle link should have a working version of your script:
https://jsfiddle.net/4qhmtnhe/
I hope it starts working, and you continue to learn JavaScript.
I'm making a function that displays a modal, and the modal has two buttons. I want this function to wait until one of the two buttons has been clicked, and return a value that corresponds to which button is clicked.
Here's a sample code that I came up with:
function myFunc()
{
var val=0;
buttonA = document.getElementById('buttonA');
buttonB = document.getElementById('buttonB');
buttonA.onclick = function(){
//do something
val = 1;
}
buttonB.onclick = function(){
//do something
val = 2;
}
while(val == 0);
return val;
}
The problem in this code is that the page becomes unresponsive because of the infinite loop, hence it isn't possible to change the value of val once initialised.
To be more precise, I want the main thread (on which myFunc is being implemented) to sleep until one of the other two threads (each of buttonA and buttonB) is clicked.
Is there some other work-around for this ? Please answer in Javascript only (no jQuery). Thanks.
Try something more like this:
function myFunc()
{
buttonA = document.getElementById('buttonA');
buttonB = document.getElementById('buttonB');
buttonA.onclick = function(){
//do something
differentFunc(1)
}
buttonB.onclick = function(){
//do something
differentFunc(2)
}
}
This is a different way to make the function more versatile (edited per your comment):
function myFunc(callback)
{
buttonA = document.getElementById('buttonA');
buttonB = document.getElementById('buttonB');
buttonA.onclick = function(){
//do something
callback(1)
}
buttonB.onclick = function(){
//do something
callback(2)
}
}
and call it like
myFunc(function(result) {
// do stuff with result
}
Javascript is naturally single-threaded. Any code that waits infinitely like that will cause a hangup and disallow input. There are ways to write async functions, namely using Promises like I did for a minute there, but it's generally easier to make your code work synchronously.
If I understand the OP's purpose is to create a modal with 2 choices like a confirm()? But for some reason confirm() isn't suitable? So a value on each button and it waits for user interaction? Unless I'm missing something fairly important, I have made a dynamically generated modal (no manual markup) that has 2 buttons. The purpose and result elude me so I left it with one event listener and a function with a simple ternary condition to which the alerts can be replaced by appropriate statements or expression at OP's discretion.
SNIPPET
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
.modal {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
background:transparent;
}
.ui {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: table-cell;
border: 3px ridge grey;
border-radius: 6px;
}
button {
font-size: 24px;
}
</style>
</head>
<body>
<script>
var frag = document.createDocumentFragment();
var modal = document.createElement('div');
var ui = document.createElement('div');
var on = document.createElement('button');
var off = document.createElement('button');
modal.className = 'modal';
ui.className = 'ui';
on.id = 'on';
on.textContent = 'On';
off.id = 'off';
off.textContent = 'Off';
frag.appendChild(modal);
modal.appendChild(ui);
ui.appendChild(on);
ui.appendChild(off);
ui.addEventListener('click', status, false);
function status(e) {
var tgt = e.target.id;
tgt === 'on' ? alert('ON!') : alert('OFF!');
}
document.body.appendChild(frag);
</script>
</body>
</html>