Javascript callback called twice - javascript

I'm pretty new with coding, and this is really stumping me...
Here is my index.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css">
<link rel="stylesheet" href="owlcarousel/owl.carousel.css">
<link rel="stylesheet" href="owlcarousel/owl.theme.default.css">
</head>
<body>
<div class="owl-carousel owl-theme">
</div>
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous" type="text/javascript" language="JavaScript"></script>
<script src="jquery.min.js"></script>
<script src="owlcarousel/owl.carousel.js"></script>
<script src="app.js"></script>
<script>
fetch('https://www.paulschlatter.com/slideshow/slideshows.txt')
.then((response) => response.text().then(yourCallback));
let cache = {}
function yourCallback(retrievedText, callback) {
if (cache[retrievedText]) {
console.log('oops')
} else {
let array = []
console.log(callback)
array = retrievedText.split(/\n|\r/g)
let httpsArray = []
let keysArray = []
let mappedArray = array.map(item => {
if (item.substring(0, 5) === 'https') {
httpsArray.push(item)
} else if (item.substring(0, 3) === '202') {
keysArray.push(item)
}
})
const object = { ...keysArray
}
for (const prop in object) {
window['value' + prop] = []
httpsArray.filter(item => item.includes(object[prop])).map(item => {
window['value' + prop].push(item)
})
}
const owlImages = document.querySelector('.owl-carousel'),
owlDiv = document.createElement('img');
owlDiv.setAttribute('src', window.value0.pop())
owlDiv.setAttribute('alt', '')
owlImages.appendChild(owlDiv)
}
}
</script>
</body>
</html>
I am not using npm or anything, just straight JavaScript, and HTML.
The function yourCallback is firing twice, so even when I only console.log hello world it returns hello world twice to my browser.
Obviously this is not ideal, and I believe that the problem lies in the
fetch('https://www.paulschlatter.com/slideshow/slideshows.txt')
.then((response) => response.text().ten(yourCallback));

This was a silly mistake, in my app.js file I had the same fetch and yourCallback function, so it was firing twice cause I called it twice :)

Related

Need to put JS modules in correct order

I got a task to render a word using pure JavaScript and modules, but always got mistakes like params of renderDOM function is undefined and so on. I'm able to choose the order of scripts, use IIFE
here is html:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class="root"></div>
<script src="invert.js"></script>
<script>
window.render.renderDOM('.root', reverse('sseccus'));
</script>
<script src="dom.js"></script>
</body>
</html>
and 3 files with functions:
dom.js
const TAG = 'div';
function createElement(tag = TAG, content) {
const element = document.createElement(tag);
element.textContent = content;
return element;
}
render.js
const TAG = 'p';
function renderDOM(selector, content) {
const root = document.querySelector(selector);
if (!root) {
return;
}
const element = createElement(TAG, content); // createElement из файла dom.js
root.appendChild(element);
}
reverse.js
(function () {
function reverse(str) {
return str.split('').reverse().join('');
}
})();
I've tried to add type='module', added export or export default to the functions. As a result there must be "success" rendered.
index.html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class="root"></div>
<script src="invert.js"></script>
<script src="dom.js"></script>
<script src="render.js"></script>
<script src="reverse.js"></script>
<script>
window.render.renderDOM('.root', reverse('sseccus'));
</script>
</body>
</html>
render.js
const TAG = 'p';
function renderDOM(selector, content) {
const root = document.querySelector(selector);
if (!root) {
return;
}
const element = createElement(TAG, content);
root.appendChild(element);
}
window.render = {renderDOM};
dom.js
const createElement = (() => {
const TAG = 'div';
return function createElement(tag = TAG, content) {
const element = document.createElement(tag);
element.textContent = content;
return element;
}
})();

How can I gradually change the element from my page?

I'm trying to display all elements of an array, by iterating through the arrray, but after I chose the file (from the input), the element in page changes to : "unidentified". Why?
function getElement() {
console.log('sfgsdf')
document.getElementById('files').onchange = function() {
console.log('sfgsdf')
let file = this.files[0];
let reader = new FileReader();
reader.readAsText(file);
reader.onload = function() {
variableIs = this.result
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
function display(asd) {
const usingSplit = asd.split(' ')
lengthOf = usingSplit.length
for (var i = 0;i < lengthOf;i++) {
sleep(1000).then(() => {
document.getElementById('test').innerHTML = usingSplit[i];
});
}
}
display(variableIs);
}
}
}
getElement()
The HTML code is just this simple one :
<!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">
<title>Document</title>
</head>
<body>
<h1 id="test">TEST</h1>
<script src="test4.js"></script>
</body>
</html>
The problem is the var inside the for loop.
You should use let instead due to the way both work.
Read this post to understand their difference:
What is the difference between "let" and "var"?
The way you're using the sleep function is not gonna work since they will execute at the same time.
You can solve this by using async await.
function delay(ms = 0) {
return new Promise(resolve => setTimeout(resolve, ms))
}
const inputFile = document.getElementById('files')
const test = document.getElementById('test')
function init() {
inputFile.onchange = async function() {
const file = this.files[0];
const content = await file.text()
const splitText = content.split(' ')
for (let i = 0; i < splitText.length; i++) {
test.innerHTML = splitText[i]
// Here we are actually waiting in the for loop since this is an async function
await delay(1000)
}
}
}
init()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 id="test">TEST</h1>
<input id="files" type="file">
</body>
</html>

How to make script execute once the first script is loaded

I'm trying to make a web framework and one feature will be a key-value state management tool. I need the second <script> tag to only run after ./script.js loads in.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./framework.js"></script>
</head>
<body>
<p f-text="name"></p>
<script>
Framework.store('name', 'Joe');
</script>
</body>
</html>
framework.js:
document.querySelectorAll('*').forEach((element) => {
if (element.hasAttribute('f-text')) {
const textValue = element.getAttribute('f-text');
const key = window.fStore.find((x) => x.key === textValue);
element.innerHTML = key.value;
}
});
window.Framework = {
store: (key, value?) => {
if (!value) {
const foundKey = window.fStore.find((x) => x.key === key);
return foundKey.value;
}
window.fStore = [...window.fStore, { key: key, value: value }];
}
}
Error:
SyntaxError: Unexpected token ')'
at /framework.js:12:22
ReferenceError: Framework is not defined
at /:12:5
You need to wait that your script is loaded, you can use this
window.addEventListener('load', function() {
Framework.store('name', 'Joe');
})

Receiving an error running script in local browser

Receiving error "Enabler is not defined" when I try and run the page on my local browser. Is there a reason the "Enabler" variable isn't active when it's called or is there a specific way I need to run this type of doc.
Thanks so much for your help!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link type="text/css" href="styles.css"
rel="stylesheet" />
<script
src="https://s0.2mdn.net/ads/studio/Enabler.js"></script>
<script
src="https://s0.2mdn.net/ads/studio/cached_libs/tweenmax_1.19.0_643d6911392a3398cb1607993edabfa7_min.js"></script>
<script
src="https://s0.2mdn.net/ads/studio/cached_libs/scrolltoplugin_1.19.0_53288c1da14a1784cdf302f94d0116a7_min.js"></script>
<script
src="https://s0.2mdn.net/ads/studio/cached_libs/textplugin_1.19.0_ee0a9b7420a65afd44a2fd958cd72d16_min.js"></script>
<script src="mkr.min.js"></script>
<script src="isi-ss-tool.js"></script>
<script src="banner.js"></script>
<script type="text/javascript">
var clickTag1 = 'https://zilrettapro.com/request-a-rep-email-sign-up/';
var clickTag2 = 'https://zilrettalabel.com/PI.pdf';
var clickTag3 = 'https://www.fda.gov/medwatch';
function activateClickTags() {
mkr.on('#cta', 'click', linkHandler);
mkr.on('#pi', 'click', linkHandler);
mkr.on('#fda', 'click', linkHandler);
}
function linkHandler(e) {
e.preventDefault();
switch (e.target.id) {
case 'cta':
Enabler.exit('CTA Exit', clickTag1);
break;
case 'pi':
Enabler.exit('PI Exit', clickTag2);
break;
case 'fda':
Enabler.exit('FDA Exit', clickTag3);
break;
}
return false;
}
window.onload = function () {
//Polite loadind...
if (Enabler.isInitialized()) {
initHandler();
} else {
Enabler.addEventListener(studio.events.StudioEvent.INIT, initHandler);
}
};
</script>
</head>

cannot add bootstrap popover from javascript to dynamically created elements

I am using javascript to generate an array of cards in HTML dynamically and currently, I am putting in each card button when the user clicks on this button he should be able to see the popover, but before that, I fetch some data to put on the cards, but something is wrong or missing, the popover doesn't appear, and if I commented the first line of loadPhotos() it works correctly.
$(function () {
$('[data-toggle="popover"]').popover()
})
const getAllPhotos = async () => {
let res = await fetch('https://jsonplaceholder.typicode.com/photos').then(
response => { return response.json() }
)
return res;
}
const displayPhotos = (photos) => {
const view = document.getElementById('photosGrid');
photos.forEach(element => {
view.append(element)
});
}
const createCard = (data) => {
const card = document.createElement('div');
card.classList.add('card', 'col-lg-2', 'm-2', 'p-0')
const optionsButton = document.createElement('button')
optionsButton.innerText = "test"
optionsButton.title = "title of me"
optionsButton.setAttribute('data-toggle', 'popover')
optionsButton.setAttribute('data-content', 'content of me')
card.appendChild(optionsButton)
return card;
}
const createCardsArray = async (data) => {
const res = await data.map(d => {
return createCard(d);
})
return res;
}
const loadPhotos = async () => {
const photos = await getAllPhotos();
const cards = await createCardsArray([1, 2]);
displayPhotos(cards);
}
loadPhotos();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Pinterest Homepage</title>
</head>
<body>
<div class="container-fluid">
<div class="row" id="photosGrid">
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
Initialize the popover after creating the elements, if more elements are added later, you can reinitialize the popover.
JQuery is adding the popover to the elements during initialization, thus elements created after initialization are not assigned their popups by JQuery

Categories

Resources