Try stuffing this code into files index.html, style.css and app.js, it doesn't open. The browser says that "The webpage was reloaded because a problem occurred" and keeps on loading.I am using an MacBook Air with macOS Big Sur with an M1, if that's of any help. I removed the full HTML code and rewrote it again, and found out it is the javascript that is causing the issue. But I have no idea why, because 1) I think my code is correct and 2) I can't open the console to check for errors because the file doesn't open. Could anybody help me?
My HTML file is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="./app.js" defer></script>
<title>Document</title>
</head>
<body>
<div class="type" contenteditable="true">In .type</div>
<div class="words">In .words</div>
</body>
</html>
My JavaScript file is:
const type = document.querySelector(".type");
const words = document.querySelector(".words");
console.log(type.innerHTML.split(""));
for (let i=0; i < type.innerHTML.split("").length; i++) {
type.innerHTML += `<span>${i}</span>`
}
And my css file is:
#import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #333;
}
.type, .words {
font-family: 'JetBrains Mono', monospace;
color: #fff;
border: 2px solid #007bff;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 80%;
height: 200px;
border-radius: 20px;
display: flex;
align-items: center;
padding: 50px;
font-size: 100px;
outline: none;
}
.type {
background-color: transparent;
z-index: 2;
}
.words {
background-color: #333;
z-index: 1;
}
You are running a loop on element type and updating it in loop.
You have created an endless loop my friend.
Try changing this-
for (let i=0; i < type.innerHTML.split("").length; i++) {
type.innerHTML += `<span>${i}</span>`
}
to this-
let typesplit = type.innerHTML.split("")
for (let i=0; i < typesplit.length ; i++) {
type.innerHTML += `<span>${i}</span>`
}
This way it won't update the value of .type every time.
Also try not to use type as variable name as it is a reserved word in Typescript which resembles JavaScript.
Related
I have made a simple API based project wherein whenever the user enter some number in the input, the div below it with the output becomes visible and when the input field is empty the div gets hidden again as it was in the initial state. The problem is whenever I clear the input field gradually the setup works as expected but if I clear it quickly the div doesn't hide the div at all. Below given is the reference code for the same
let input = document.querySelector("#number-input");
let fact = document.querySelector(".fact-content");
input.addEventListener("input", getFact);
function getFact() {
let number = input.value;
if (number != "") {
let xhr = new XMLHttpRequest();
xhr.open("GET", "http://numbersapi.com/" + number);
xhr.onload = function () {
if (this.status == 200) {
fact.innerText = this.responseText;
fact.style.display = "block";
}
};
xhr.send();
}
else{
fact.innerText = "";
fact.style.display = "none";
}
}
#import url('https://fonts.googleapis.com/css2?family=Varela+Round&display=swap');
*{
margin: 0;
padding: 0;
font-family: 'Varela Round', sans-serif;
box-sizing: border-box;
}
body{
background-color: #9AD0EC;
}
main{
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container{
width: 40%;
margin: auto;
line-height: 1.6;
background-color: #1572A1;
color: #eee;
padding: 2rem;
min-width: 500px;
border-radius: 5px;
}
.container h1{
font-size: 1.5em;
}
.container h4{
font-size: 1.2rem;
}
input{
padding: 0.5rem;
border-radius: 5px;
border: none;
margin: 10px 0;
width: 50%;
}
.fact-content{
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Number Fact</title>
</head>
<body>
<main>
<div class="container">
<h1>Get random fact based on numbers</h1>
<h4>Enter a number and get a random fact</h4>
<input
type="number"
id="number-input"
placeholder="Enter a number..."
/>
<p class="fact-content"></p>
</div>
</main>
</body>
</html>
Consider the case when you have two characters in your input. You delete one character, and initiate an AJAX request for the remaining character. Before that AJAX request completes, you delete the remaining character.
When you delete the final character, the event handler clears and hides the element. But then the previous AJAX request completes, and displays the outdated response in the element.
There are two things you can do here:
When the AJAX request completes, check that the input value is still the same as the number variable. If it's not, discard the response to the AJAX request.
Switch to using the fetch API, and use an AbortController instance to abort the in-flight request when the input value changes.
let input = document.querySelector("#number-input");
let fact = document.querySelector(".fact-content");
let abortToken = null;
input.addEventListener("input", getFact);
async function getFact() {
if (abortToken) {
abortToken.abort("Input changed");
abortToken = null;
}
let number = input.value;
if (!number) {
fact.innerText = "";
fact.style.display = "none";
return;
}
const url = `http://numbersapi.com/${number}`;
abortToken = new AbortController();
const { signal } = abortToken;
try {
const response = await fetch(url, { signal });
if (input.value !== number) {
// The input has been modified.
return;
}
if (!response.ok){
const errorMessage = await response.text();
console.error(response.status, response.statusText, errorMessage);
fact.innerText = "# ERROR #";
fact.style.display = "block";
return;
}
const text = await response.text();
fact.innerText = text;
fact.style.display = "block";
} catch {
}
}
#import url('https://fonts.googleapis.com/css2?family=Varela+Round&display=swap');
*{
margin: 0;
padding: 0;
font-family: 'Varela Round', sans-serif;
box-sizing: border-box;
}
body{
background-color: #9AD0EC;
}
main{
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container{
width: 40%;
margin: auto;
line-height: 1.6;
background-color: #1572A1;
color: #eee;
padding: 2rem;
min-width: 500px;
border-radius: 5px;
}
.container h1{
font-size: 1.5em;
}
.container h4{
font-size: 1.2rem;
}
input{
padding: 0.5rem;
border-radius: 5px;
border: none;
margin: 10px 0;
width: 50%;
}
.fact-content{
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Number Fact</title>
</head>
<body>
<main>
<div class="container">
<h1>Get random fact based on numbers</h1>
<h4>Enter a number and get a random fact</h4>
<input
type="number"
id="number-input"
placeholder="Enter a number..."
/>
<p class="fact-content"></p>
</div>
</main>
</body>
</html>
My slideshow script uses the onclick event window.location.reload() to advance to the next mini-slideshow, causing the page to flicker when the “NEXT Plant” button is clicked.
Ideally, the onclick event should trigger a function to advance the slideshow, eliminating the need to reload the page.
Creating such a function, unfortunately, is easier said than done.
Intuitively, my first thought was to forego the onclick event window.location.reload() method and instead have the onclick event call the onLoad function runShow(), thinking that re-invoking this script would advance the slideshow. It didn’t.
Re-invoking other functions also failed to advance the slideshow, and now I’m out of ideas what to try next.
Please advise. Thanks.
body {
display: flex;
justify-content: center;
text-align: center;
background-color: black;
}
img {
display: block;
position: relative;
top: 20px;
max-width:100%;
max-height:calc(100vh - 160px - ((.4em + .6vmin) + (.4em + .6vmax)));
object-fit: contain;
}
.caption {
position: absolute;
bottom: 120px;
font-size: calc((.4em + .6vmin) + (.4em + .6vmax));
color: white;
left: 0;
right: 0;
width: 100%;
text-align: center;
}
p {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
width: 100%;
text-align: center;
}
.button {
border-radius: 8px;
background-color: green;
border: none;
color: black;
padding: 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<title>Plant Slideshow</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
</head>
<body onLoad="runShow()">
<img id="slide" onmouseover="stopShow()" onmouseout="runShow()" src="" alt="">
<script>
var genusSpecies={"Adam's Needle (Yucca filamentosa)":["Adam's Needle (Yucca filamentosa)1.jpg"],"Virginia Wild Rye (Elymus virginicus)":["Virginia Wild Rye (Elymus virginicus)1.jpg","Virginia Wild Rye (Elymus virginicus)2.jpg"]};
if (window.innerHeight > 1000) {
var specificResolution="./plants1220/"; // Higher-resolution photos for desktops
} else {
var specificResolution="./plants500/"; // Lower-resolution photos for smartphones
}
var curimg=0;
var keys=Object.keys(genusSpecies); // Creates array of keys
var plantNumber=Object.keys(genusSpecies).length;
x=Math.floor(Math.random() * (plantNumber)); // Selects random index number for “keys” array, the element’s value providing a named key for “genusSpecies”
var plant=genusSpecies[keys[x]]; // Value of named key (image file names of specific mini-slideshow)
function swapImage()
{
document.getElementById("slide").setAttribute("src",specificResolution+plant[curimg])
curimg=(curimg<plant.length-1)? curimg+1 : 0; timer = setTimeout("swapImage()",4000);
}
function stopShow()
{
clearTimeout(timer);
}
function runShow()
{
swapImage();
}
</script>
<div class="caption">
<script>
document.write(keys[x]); // Displays caption
</script>
</div>
<p><button class="button" onclick="window.location.reload()">NEXT Plant<br>(hover over slideshow to pause)</button></p>
<!-- Reloads page, advancing the slideshow, but is inefficient & causes flickering -->
</body>
</html>
Took a bit of doing to learn how it works.. and because of that I just made a function nextSlide that resets JUST the important stuff(you might wanna do something else other than random though) because your other functions do the rest :D
Pure random next slide makes there be several occurrences of the same slide being loaded.. If you want it not like that(eg: sequentially looping through array) just tell me in the comments, but as for now, your code runs without reloading
EDIT: IT WORKS PERFECTLY, WHAT IS GOING WRONG?
https://repl.it/talk/share/Testing/121825 has code forked from your repl(and I applied my below answer to it) and https://slideshow-code-needs-improving--paultaylor2.repl.co/ would let you see the full tab example(it works, and changes the images).. so I ask, what problems are you experiencing?
I did see one thing, that the value specificResolution are 2 different things from when you gave your snippet in your question and the snippet you have in your repl.. so just ensure that specificResolution checks EXISTING FOLDERS
//place this in a script tag SOMEWHERE AT THE BOTTOM LIKE BELOW BODY
var genusSpecies={"Adam's Needle (Yucca filamentosa)":["Adam's Needle (Yucca filamentosa)1.jpg"],"Virginia Wild Rye (Elymus virginicus)":["Virginia Wild Rye (Elymus virginicus)1.jpg","Virginia Wild Rye (Elymus virginicus)2.jpg"]};
/*HELLO, PLEASE MAKE SURE THIS VARIABLE HAS A VALID BEGINNING, since your example in the repl for this variable is DIFFERENT to the example I'm replicating from your question*/
/////////////////////////////////////////////////
if (window.innerHeight > 1000) {
window.specificResolution="./plants1220/"; // Higher-resolution photos for desktops
} else {
window.specificResolution="./plants500/"; // Lower-resolution photos for smartphones
}
/////////////////////////////////////////////////
var curimg=0;
var keys=Object.keys(genusSpecies); // Creates array of keys
var plantNumber=Object.keys(genusSpecies).length;
var rand=()=>Math.floor(Math.random() * (plantNumber));
var x=rand(); // Selects random index number for “keys” array, the element’s value providing a named key for “genusSpecies”
var plant=genusSpecies[keys[x]]; // Value of named key (image file names of specific mini-slideshow)
function swapImage()
{
document.getElementById("slide").setAttribute("src",specificResolution+plant[curimg])
curimg=(curimg<plant.length-1)? curimg+1 : 0; window.timer = setTimeout(swapImage,4000);
}
function stopShow()
{
clearTimeout(timer);
}
function runShow()
{
swapImage();
}
function nextSlide(){ //your other functions do the rest of work :D
x=rand(); curimg=0;
stopShow(); runShow();
plant=genusSpecies[keys[x]];
document.getElementsByClassName('caption')[0].innerText=(keys[x]);
}
document.getElementsByClassName('caption')[0].innerText=(keys[x]); // Displays caption
body {
display: flex;
justify-content: center;
text-align: center;
background-color: black;
}
img {
display: block;
position: relative;
top: 20px;
max-width:100%;
max-height:calc(100vh - 160px - ((.4em + .6vmin) + (.4em + .6vmax)));
object-fit: contain;
}
.caption {
position: absolute;
bottom: 120px;
font-size: calc((.4em + .6vmin) + (.4em + .6vmax));
color: white;
left: 0;
right: 0;
width: 100%;
text-align: center;
}
p {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
width: 100%;
text-align: center;
}
.button {
border-radius: 8px;
background-color: green;
border: none;
color: black;
padding: 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<title>Plant Slideshow</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
</head>
<body onLoad="runShow()">
<img id="slide" onmouseover="stopShow()" onmouseout="runShow()" src="" alt="">
<div class="caption"></div>
<p><button class="button" onclick="nextSlide()">NEXT Plant<br>(hover over slideshow to pause)</button></p>
<!-- Reloads page, advancing the slideshow, but is inefficient & causes flickering -->
</body>
</html>
the svg id = "map"
the normal path class = "T"
Selected class ="Tactive"
Tcurrent is a active shave by Default
var oMap= document.getElementById("map");
var oRng= document.getElementsByClassName("T");
var Tcurrent
for (var j = 0; j < oRng.length; j++) {
oRng[j].addEventListener("click", function () {
Tcurrent = document.getElementsByClassName("T Tactive");
Tcurrent[0].classList ="T"
this.classList = "T Tactive";
});
}
Hopefully this may help...
$('.svg').click(function() {
$('.svg').removeClass('selected'); // removes initial selected classes.
this.classList.add('selected'); // adds selected class for clicked svg.
});
.svg {
margin: 15px;
padding: 8px;
height: 100px;
width: 100px;
display: inline-block;
background: #eee;
border-radius: 4px;
}
.svg:hover {
cursor: pointer;
}
.selected {
border: 2px solid #333;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Selected</title>
</head>
<body>
<main>
<div class="svg">a.</div>
<div class="svg">b.</div>
</main>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>
I try to load an array from an external JS file into my HTML and have problems with that.
My js.js:
var temp_max = [4,9,2,5,8,4,2,10];
My HTML:
Note: Please download this file DateJS and insert it into "DATE-JS"!!
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--CSS for layout-->
<link rel="stylesheet" type="text/css" href="mystyle.css">
<!--Date library for german date layout-->
<script src="DATE-JS"></script>
<script src="js.js"></script>
</head>
<body>
<br>
<br>
<div style="width:80%" position="absolute">
<div class="header">
<script>
for(var i = 0 ; i <8 ; i++)
{
var weekday=Date.today().addDays(i).toString('dddd');
document.write("<div id='div_weekday'>" + weekday + "</div>");
}
for(var i = 0 ; i <8 ; i++)
{
var day = Date.today().addDays(i).toString('dd');
document.write("<div id='div_date'>" + day + "</div>")
}
</script>
</div>
</div>
</body>
</html>
My CSS:
* {
box-sizing: border-box;
}
body {
background-color: rgb(86,86,85);
}
h1:after {
content: " ";
width: 70.5%;
height: 2px;
background-color: rgb(228,203,153);
position:absolute;
top: 50%;
margin-left: 15px
}
.header {
width: 100%;
}
.header > div {
color: rgb(228,203,153);
width: 12.5%;
float: left;
border: solid rgb(228,203,153);
border-width: 1px 1px 1px 0;
text-align: left;
word-break: break-all;
}
.header > div:first-child {
border-width: 1px;
}
#div_date {
border: none;
width: 12.5%;
font-size: 60px;
text-align: right;
border-bottom: solid rgba(228,203,153,0.3);
border-width: 0.5px;
padding-right: 1%
}
#div_weekday {
border: none;
width: 12.5%;
font-size: 20px;
text-align: left;
padding-left: 1%
}
Here is a screenshot without importing the JS array.
So I want that my temp_max array values are displayed exactly above the German weekdays!
So above the first information: 'Donnerstag' the script should display the value 4 from the array and so on.
Please note that I want to export this array from an external JS-file, I am not able to write this variable into my HTML file!
I already tried to use
document.getElementById
but this does not work for me.
If the problem just in looping over the created divs, I think you can do this.
All what you need to change is just adding a different ids to your divs.
Just use i index in your ids.
Something like this:
Creation:
for(var i = 0 ; i <8 ; i++) {
var weekday=Date.today().addDays(i).toString('dddd');
document.write("<div id='div_weekday_" + i + "'>" + weekday + "</div>");
}
Updating data:
for (var i = 0; i < 8; i++) {
document.getElementById('div_weekday_' + i).innerHTML = temp_max[i].weekday;
}
First and foremost, this is my code.
var size = 400
function createGrid(size) {
$("#create").click(function() {
for (i = 0; i <= size; i++) {
$("#container").append('<div class="grid"> </div>');
}
});
}
$(document).ready(createGrid);
#container {
top: 10px;
position: relative;
width: 960px;
height: 960px;
border-color: black;
margin: auto;
outline: 2px solid black;
}
.grid {
display: inline-block;
border: 1px solid white;
background-color: black;
float: left;
width: 10px;
height: 10px;
}
<!DOCTYPE html>
<html>
<title>
Sam's Etcha Sketch
</title>
<head>
<link type="text/css" rel="stylesheet" href="stylesheet.css">
</head>
<body>
<div>
<button id="create">Create!</button>
</div>
<div id="container"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
My goal is to create square divs inside #container after clicking on the button #create. I don't mind how ugly it looks right now, I just want to be able to click on the button to add squares(which isn't the result as of now). I checked JS Bin and my browser console for any bugs or errors but I can't seem to find any. Not sure what I'm doing wrong as I tried a simple FadeOut function on the button and it didn't seem to work, so maybe it's the way I placed the into the HTML? (I tried placing it inside as well.)
TL;DR
What is wrong with my code that is causing my click() function to not append any square divs inside a container?
You're never passing size to createGrid
Here's your code.
// the outer "size" variable
var size = 400
// this creates a new "size" variable which shadows the outer one
function createGrid(size) {
$("#create").click(function() {
for (i = 0; i <= size; i++) {
$("#container").append('<div class="grid"> </div>');
}
});
}
// this passes "createGrid" to the event handler, which calls it without any argument
$(document).ready(createGrid);
Here's how to do it:
// this generates an event handler with a custom "size" in its scope
function getGridCreator(container, size) {
return function () {
$("#create").click(function() {
for (i = 0; i <= size; i++) {
$(container).append('<div class="grid"> </div>');
}
});
};
}
// this passes the grid creator to the event handler, which again calls
// it without any argument, but this time "size" is in scope
$(document).ready(getGridCreator("#container", 400));
As a general tip: Avoid global variables, use function parameters and closures instead.
Try this i made a few changes in your script
$(document).ready(function(){
var size = 400
function createGrid(size) {
$("#create").click(function() {
for (i = 0; i <= size; i++) {
$("#container").append($('<div class="grid"/>'));
}
});
}
createGrid(size)
});
#container {
top: 10px;
position: relative;
width: 960px;
height: 960px;
border-color: black;
margin: auto;
outline: 2px solid black;
}
.grid {
display: inline-block;
border: 1px solid white;
background-color: black;
float: left;
width: 10px;
height: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<title>
Sam's Etcha Sketch
</title>
<head>
<link type="text/css" rel="stylesheet" href="stylesheet.css">
</head>
<body>
<div>
<button id="create">Create!</button>
</div>
<div id="container"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>