This question already has answers here:
How to make JavaScript execute after page load?
(25 answers)
Closed 4 years ago.
How do I make the following code load once the page is loaded?
I tried making it an entire new function but it didn't work, can someone help me
document.getElementById("ano").addEventListener("change", function(a) {
const tbody = document.getElementById('tbody_calendario_jogos')
while (tbody.firstChild) {
console.log(tbody.firstChild)
tbody.removeChild(tbody.firstChild)
}
for (key in jogos) {
const anoSelect = new RegExp(`${a.target.value}`)
const data = anoSelect.exec(jogos[key].Data)
if (data != null) {
const obj = jogos[key]
const tr = document.createElement('tr')
const tdTemporada = document.createElement('td')
tdTemporada.textContent = obj.Temporada
const tdLocal = document.createElement('td')
tdLocal.textContent = obj.Local
const tdMais = document.createElement('td')
tdMais.textContent = obj.Mais
tr.appendChild(tdTemporada)
tr.appendChild(tdLocal)
tr.appendChild(tdMais)
tbody.appendChild(tr)
}
}
})
You can use a simple init statement to execute the code after the page loads:
function init() {
//your code here
}
window.onload = init;
Just move your function outside the event listener and change it to a name function so you can reference the function name and load the function on page load as well as when the change listener is invoked by your #ano element like this:
function someFunc(a) {
const tbody = document.getElementById('tbody_calendario_jogos')
while (tbody.firstChild) {
console.log(tbody.firstChild)
tbody.removeChild(tbody.firstChild)
}
for (key in jogos) {
const anoSelect = new RegExp(`${a.target.value}`)
const data = anoSelect.exec(jogos[key].Data)
if (data != null) {
const obj = jogos[key]
const tr = document.createElement('tr')
const tdTemporada = document.createElement('td')
tdTemporada.textContent = obj.Temporada
const tdLocal = document.createElement('td')
tdLocal.textContent = obj.Local
const tdMais = document.createElement('td')
tdMais.textContent = obj.Mais
tr.appendChild(tdTemporada)
tr.appendChild(tdLocal)
tr.appendChild(tdMais)
tbody.appendChild(tr)
}
}
}
someFunc(); // will load on page load
document.getElementById("ano").addEventListener("change", someFunc); // will load when `ano` element invokes the change listener
Check and run the following Code Snippet for a practical example of the above approach:
function someFunc() {
alert("function loaded!!")
}
someFunc(); // will load on page load
document.getElementById("ano").addEventListener("click", someFunc); // will load when `ano` element invokes the change listener
<button id="ano">Click Me</button>
Try putting it in self-revoking function instead of change function. Whatever you define inside of the change function will NEVER be called when the page loads. Depending on where and when you want the code to be called, placing it in the appropriate location of the page such as inside of the <head></head> tag, right after opening <body> tag, or at the end of the closing </body> tag.
(function () { // Your code })();
Related
I'm trying to replace the HTML in an element on my main page.
This is the JS function I am calling:
var insertHtml = function(selector,html) {
var targetElem = document.querySelector(selector);
console.log(html);
targetElem.innerHtml = html;
};
The new HTML is displaying on the console, however, no changes are reflected on the browser.
If it helps, these are the calling functions:
dc.loadMenuCategories = function () {
showloading("#main-content");
$ajaxUtils.sendGetRequest(categoriesURL, buildAndShowCategoriesHTML);
};
function buildAndShowCategoriesHTML (categories) {
$ajaxUtils.sendGetRequest(
categoriesTitleHTML,
function (categoriesTitleHTML){
$ajaxUtils.sendGetRequest(
categoryHTML,
function (categoryHTML) {
var categoriesViewHTML =
buildCategoriesViewHtml(categories,
categoriesTitleHTML,
categoryHTML);
insertHtml("#main-content", categoriesViewHTML);
},
false);
},
false);
}
Does anyone know why these changes are not loading on the browser?
When I run my rails application and enter likeButton into the console it gives me Uncaught ReferenceError: likeButton is not defined
at :1:1
(anonymous) # VM1591:1
I tried moving the script in html to head and body. I am currently trying to use DOMContentLoaded but it seems I'm missing something. My overall goal is to change the color of the button once pressed and also keep the color after page refresh. I am using sessionStorage for this process. I just want to make sure that likeButton variable is declared after html is loaded. If its possible to done in javascript only.
//first js file
const BASE_URL = "http://localhost:3000"
const GPUS_URL = `${BASE_URL}/gpus`
const USERS_URL = `${BASE_URL}/users`
const gpuCollection = document.querySelector('#gpu-collection')
let wish = sessionStorage.getItem('wish');
class Gpu {
constructor(gpuAttributes) {
this.title = gpuAttributes.title;
this.price = gpuAttributes.price;
this.features = gpuAttributes.features;
this.link = gpuAttributes.link;
this.image = gpuAttributes.image;
this.id = gpuAttributes.id;
}
render() {
let div = document.createElement('div');
div.classList.add('card');
let h = document.createElement('h2');
let t = document.createTextNode(`${this.title} ($${this.price})`);
h.appendChild(t);
div.appendChild(h);
let h1 = document.createElement('h1');
h1.classList.add('gpu-cat');
h1.innerHTML = `${this.features}`;
div.appendChild(h1);
let button = document.createElement('button');
button.classList.add('list_btn');
button.innerHTML = '♡';
div.appendChild(button);
let a = document.createElement('a');
let img = document.createElement('img');
a.href = `${this.link}`;
a.target = '_blank';
img.src = `${this.image}`;
img.classList.add('gpu-image');
a.appendChild(img);
div.appendChild(a);
gpuCollection.appendChild(div);
}
}
//second js file
document.addEventListener("DOMContentLoaded", function (){
let likeButton;
SignUp();
logInUser();
logOutUser();
function putGpusOnDom(gpuArray){
gpuArray.forEach(gpu => {
let newGpu = new Gpu(gpu)
newGpu.render()
});
likeButton = document.querySelector("button");
}
function fetchGpus(){
fetch(GPUS_URL)
.then(res => res.json())
.then(gpus => putGpusOnDom(gpus))
}
const enableWish = () => {
console.log(likeButton)
sessionStorage.setItem('wish', 'red')
}
gpuCollection.addEventListener('click', function (){
wish = sessionStorage.getItem('wish');
if(wish !== 'red'){
enableWish();
}else{
disableWish();
}
});
})
//html file
...
<body>
<div id = "gpu-collection"></div>
<script type="text/javascript" src="src/Gpu.js"></script>
<script type="text/javascript" src="src/index.js" ></script>
</body>
</html>
As I mentioned in a comment the like button is not available on DOMContentLoaded if it is added dynamically. You need to wait until the button has been placed in the DOM
Use something like the following, I'm making some guesses here as there are some gaps in your code
document.addEventListener("DOMContentLoaded", function (){
//document.querySelector("button"); not yet available
//NOTE: The likeButton variable will ONLY be in scope INSIDE the event listener function
// You will not be able to access directly in the console.
let likeButton;
SignUp();
logInUser();
logOutUser();
function putGpusOnDom(gpuArray){
gpuArray.forEach(gpu => {
let newGpu = new Gpu(gpu)
newGpu.render()
});
//Now you have rendered the button it is available
//CAUTION: querySelector("button") will grab the first button on the page
// and ONLY the first button
likeButton = document.querySelector("button");
//Log like button to console while it is still in scope.
console.log(likeButton);
}
function fetchGpus(){
fetch(GPUS_URL)
.then(res => res.json())
.then(gpus => putGpusOnDom(gpus))
}
const enableWish = () => {
console.log(likeButton)
sessionStorage.setItem('wish', 'red')
}
})
I have a following trouble in APIFY. I would like to write a function that saves HTML body of a current page and then click to the next page, saves HTML body etc.
I tried this:
var result = [];
var scrapeAndClick = function() {
$("div.ui-paginator.ui-paginator-top.ui-widget-header.ui-corner-top").each(function() {
result.push(
$(this).html()
);
//klikej na dalsi stranky
var nextButton = $('a.ui-paginator-next.ui-state-default.ui-corner-all');
console.log('Click next button');
nextButton.click().delay(4000)
});
};
scrapeAndClick();
In Google Chrome console it returns me only the HTML body of the first page. APIFY does not return anything.
Can someone see, where is the problem?
If is someone interested in the whole Page function:
async function pageFunction(context) {
const { log } = context;
const searchSelector = 'div.ui-panel-content.ui-widget-content > button';
//vyber "Gemeenschappelijk Landbouw Beleid" z Kies subsidie:
const subsidySelector = $("span.column2 > select.jsTruncate").val("10000");
log.info('Select CAP ')
subsidySelector
//klikni na Zoek
log.info('Click search.')
$(searchSelector).eq(0).click()
//loopujeme dalsi stranky a ukladame html body
var result = [];
var scrapeAndClick = function() {
$("div.ui-paginator.ui-paginator-top.ui-widget-header.ui-corner-top").each(function() {
result.push(
$(this).html()
);
//klikej na dalsi stranky
var nextButton = $('a.ui-paginator-next.ui-state-default.ui-corner-all');
console.log('Click next button');
nextButton.click().delay(4000)
});
};
scrapeAndClick();
return result;
}
StartURL is this: https://mijn.rvo.nl/europese-subsidies-2017
I found an old question on APIFY forum (https://forum.apify.com/t/clickable-link-that-doesnt-change-the-url/361/3), however it seems that it was done on old version of APIFY crawler.
Thanks a lot for any help!
Firstly sorry for my english, i have code that doesnt work when I execute it on
<script language="javascript" src="/thecode.js"></script>
I put thecode.js on footer
var msg=document.body.innerHTML;
for(var i=0;i<msg.length;i++){
var tx=document.body[i].innerHTML;
tx=tx.replace(/dog/ig,'animal');
tx=tx.replace(/apple/ig,'fruit');
tx=tx.replace(/\[VIdEo\]/ig,'Video');
tx=tx.replace(/http\:\/\/example\.com/ig,'http://thelink.com');
document.body.innerHTML=tx;}
I think i dont make any fault, but when i execute it, its doesnt work.
thank for your attention... :)
no need to iterate body element
try this:
want to change to with that js? i have used to make it
function addTitleToSurveyUrls() {
var elements = document.getElementsByTagName('a');
for(var el in elements) {
var element = elements[el];
var href = element.getAttribute("href");
if(href.indexOf('survey_')>-1) {
element.setAttribute('title', 'Some TITLE HERE');
}
}
}
function replaceBodyElements() {
var tx=document.body.innerHTML;
tx = tx.replace(/dog/ig,'animal');
tx = tx.replace(/apple/ig,'fruit');
tx = tx.replace(/\[VIdEo\]/ig,'Video');
tx = tx.replace(/http\:\/\/example\.com/ig,'http://thelink.com');
document.body.innerHTML=tx;
}
window.onload = function(){
replaceBodyElements();
addTitleToSurveyUrls();
// ... some another operations
};
also
document.onreadystatechange = function () {
var state = document.readyState;
if(state == 'complete') {
replaceBodyElements();
addTitleToSurveyUrls();
}
}
I've used onload event because maybe document has dynamic elements and etc. so better wait while all elements get loaded and change it.
or You can replace window.onload with window.document.onload
I'm writing a Firefox extension. The extension replaces certain words on the page with other words. Here's the basic code I'm using:
function startup() {
gBrowser.addEventListener("load", pageLoad, true);
}
function pageLoad(event) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
}
The problem is that this code is causing an endless loop. When I set the innerHTML property of the body, it sends another load event, which causes the endless loop.
How can I modify the page when it loads without causing the page load event to fire again?
You could use the following code to check if it has already been run before.
var loaded = false;
function pageLoad(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
Alternatively, if you wanted to keep the loaded variable out of global scope, you could use a closure:
var pageLoad = (function () {
var loaded = false;
return function(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
}();
The outer function gets executed immediately and returns the inner function which will have visibility of the loaded variable due to closure.
Would having a div or span tag immediately inside of your body tag be an option? Then you could just update the innerHTML of that element, and not the entire body...