Jquery loop while class does not exist - javascript

I am trying to use jquery to go though each page of the website and scrape data from each page. When a user clicks to new page button and once the page is loaded the value of current page number is set to "". So I am trying to use that as an indicator of when the page has finished loading
So I tried doing something like this, so that each loop waits until the page is fully loaded .
let totalNumberOfPages = -1;
$(".pagination .pg").each(function(data) {
totalNumberOfPages++;
});
for (let i = 1; i <= totalNumberOfPages; i++) {
$(".goto-page-input").val(i);
$(".gotosubmit").click();
// Wait until page loads
while ($(".goto-page-input").val() != "") {
// Loading
}
console.log(`Getting data of page ` + i);
}
The outer loop is to go though each page number buttons. However, this code does not work because it creates an infinite while loop. The while loop never ends because I beleive that it blocks the code and the code that is supposed to set the value of the page number to "" never fires. I am not sure how to solve this issue.

What you're looking for is an event handler for the change event see example below. Do note the change event will be fired on loss of focus.
(async () =>
{
document.querySelector(".goto-page-input")
.addEventListener("change", evt =>
{
console.log(evt.target.value);
if (evt.target.value === "")
{
// LOGIC GOES HERE
console.log('Logic is happening');
}
}, true);
})();
<input type="number" placeholder="Page" value="" class="goto-page-input" />

You could use
$(window).load(() => {
console.log(“Getting data of page “ + i);
});
This will execute the callback function as soon as the window loads.
See docs: https://api.jquery.com/load/

Related

How to Delay execution until an element has loaded on a modal to then alter the element?

I have a form with a modal on it. In my javascript after the modal is opened I need to look for a particular div and hide it and then show it again if a certain value is changed.
The problem is when the function that loads the modal runs the content hasn't rendered yet. I was trying to call monitorForVaultCardGroup() to look for the field ever 100ms, then return when it was found. Then, with the reference valid call hide().
function monitorForVaultCardGroup() {
setTimeout(() => {
const vaultCardGroup = $("[data-group=VaultCardGroup]");
if (vaultCardGroup.length > 0) {
return;
}
monitorForVaultCardGroup();
}, 100);
}
monitorForVaultCardGroup();
vaultCardGroup.hide();
Why does the reference not seem to resolve when .hide() is called?

Replace element after amount of page refreshes

Today, I was thinking if a javascript is possible to replace an element after refreshing the page 10 times specifically. I would really need this to replace an element after amount of page refreshes to make it static. I was trying to code it but all, I coded so far is to replace it after clicking on the element 3 times. And localStorage logs it and creates a key so the webserver remembers the change. All, I want is the element to replace its code with urls code after 10 refreshes on the page.
var count = parseInt(localStorage.getItem("count"), 10) || 0;
function loadMyPage() {
if (count >= 3)
$("#id-2").load("yoinkexecutor2.html");
}
}
$(document).ready( function () {
loadMyPage();
$("#id-2").on("click", function() {
localStorage.setItem("count", count += 1);
loadMyPage();
});
});
Ok, I updated the fiddle to work when the fiddle is reloaded. Don't worry too much about my mockHtmlReq function as it's just to mock a request for HTML content, similar to .load().
The only thing I changed was inside the $(document).ready()
$(document).ready( function () {
loadMyPage();
localStorage.setItem("count", count += 1);
});
Basically what happens is everytime the page reloads we are just incrementing up our count value stored in localStorage.

How do update a page element while inside a long running event?

I've got a long running method -- and I want to indicate to the user that an operation is underway. This is NOT and ajax call, so I can't use the common pattern I've used in the past to display, say a spinner, before the ajax event, then hiding it on success for example.
In my case -- I'm not making an ajax call, I'm instead doing some very heavy DOM manipulation.
I had a test example on jsFiddle.net -- would love to learn how to capture the event. At the moment, my "wait-message" div updates at the same exact time when my operation completes which is much too late :(
Complete sample code is here: http://jsfiddle.net/rsturim/97hrs/6/
Javascript (jQuery)
$(document).ready(function() {
$("#link-action").click(function(e) {
$("#wait-message").text("starting ...");
var count = longRunningMethod(1000000000);
$("#result").text(count);
$("#wait-message").text("completed.");
});
var longRunningMethod = function(countUpTo) {
var i = 0;
while (i <= countUpTo) {
i++;
}
return i;
};
});
HTML:
<div id="wait-message">
push button please
</div>
<hr />
<button id="link-action">Run Operation</button>
<hr />
<h1>Results:</h1>
<div id="result"> </div>
Here is a solution. I'm not sure if it works in all browsers, you may want to test it out in several, but I think it does:
$(document).ready(function() {
$("#link-action").click(function(e) {
$("#wait-message").text("starting ...");
// Stuff to do after a render
setTimeout(function(){
var count = longRunningMethod(1000000000);
$("#result").text(count);
$("#wait-message").text("completed.");
}, 0);
});
var longRunningMethod = function(countUpTo) {
var i = 0;
while (i <= countUpTo) {
i++;
}
return i;
};
});
Basically, the browser won't render any changes until a script finishes executing. That allows you to do things like:
Hide all divs with a certain class
Show one of those divs
In a row and the browser will never render the div that is being shown as hidden, so you won't get weird flickers or things moving around on the page.
Using setTimeout like I did, the anonymous click handler will finish executing, the browser will re-render, the the anonymous function in the setTimeout will run (immediately after the render since there is no actual delay).
Use setTimeout or setInterval instead of your while loop; a sub-second delay like 15ms should be enough to prevent your window freezing / UI locking.

Call a function only once

I've 3 divs (#Mask #Intro #Container) so if you click on Mask, Intro gets hidden and Container appears.
The problem is that I just want to load this only one time, not every time I refresh the page or anytime I click on the menu or a link, etc.
How can I do this?
This is the script I'm using for now:
$(document).ready(function(){
$("div#mask").click(function() {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
});
});
Thank you!
You can try using a simple counter.
// count how many times click event is triggered
var eventsFired = 0;
$(document).ready(function(){
$("div#mask").click(function() {
if (eventsFired == 0) {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
eventsFired++; // <-- now equals 1, won't fire again until reload
}
});
});
To persist this you will need to set a cookie. (e.g. $.cookie() if you use that plugin).
// example using $.cookie plugin
var eventsFired = ($.cookie('eventsFired') != null)
? $.cookie('eventsFired')
: 0;
$(document).ready(function(){
$("div#mask").click(function() {
if (eventsFired == 0) {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
eventsFired++; // <-- now equals 1, won't fire again until reload
$.cookie('eventsFired', eventsFired);
}
});
});
To delete the cookie later on:
$.cookie('eventsFired', null);
Just point to an empty function once it has been called.
var myFunc = function(){
myFunc = function(){}; // kill it
console.log('Done once!'); // your stuff here
};
Web pages are stateless in that they don't hold states between page refreshes. When you reload the page it has no clue what has happened in the past.
Cookies to the rescue! You can use Javascript (and jQuery has some nice plugins to make it easier) to store variables on the client's browser. Store a cookie when the mask is clicked, so that when the page is next loaded it never shows.
this code with will work perfect for you and it is the standard way provided by jquery to bind events that you want to execute only once
$(document).ready(function(){
$("div#mask").one('click', function() {
$("div#intro").fadeToggle('slow');
$("div#container").fadeToggle('slow');
$("div#mask").css("z-index", "-99");
});
});

Load Html Content if not exist JQuery AJAX

I have a page with 3 buttons. >Logos >Banners >Footer
When any of these 3 buttons clicked it does jquery post to a page which returns HTML content in response and I set innerhtml of a div from that returned content . I want to do this so that If I clicked Logo and than went to Banner and come back on Logo it should not request for content again as its already loaded when clicked 1st time.
Thanks .
Sounds like to be the perfect candidate for .one()
$(".someItem").one("click", function(){
//do your post and load the html
});
Using one will allow for the event handler to trigger once per element.
In the logic of the click handler, look for the content having been loaded. One way would be to see if you can find a particular element that comes in with the content.
Another would be to set a data- attribute on the elements with the click handler and look for the value of that attribute.
For example:
$(".myElements").click(function() {
if ($(this).attr("data-loaded") == false {
// TODO: Do ajax load
// Flag the elements so we don't load again
$(".myElements").attr("data-loaded", true);
}
});
The benefit of storing the state in the data- attribute is that you don't have to use global variables and the data is stored within the DOM, rather than only in javascript. You can also use this to control script behavior with the HTML output by the server if you have a dynamic page.
try this:
HTML:
logos<br />
banner<br />
footer<br />
<div id="container"></div>
JS:
$(".menu").bind("click", function(event) {
event.stopPropagation();
var
data = $(this).attr("data");
type = $(this).attr("type");
if ($("#container").find(".logos").length > 0 && data == "logos") {
$("#container").find(".logos").show();
return false;
}
var htmlappend = $("<div></div>")
.addClass(type)
.addClass(data);
$("#container").find(".remover-class").remove();
$("#container").find(".hidde-class").hide();
$("#container").append(htmlappend);
$("#container").find("." + data).load("file_" + data + "_.html");
return false;
});
I would unbind the click event when clicked to prevent further load requests
$('#button').click(function(e) {
e.preventDefault();
$('#button').unbind('click');
$('#result').load('ajax/test.html ' + 'someid', function() {
//load callback
});
});
or use one.click which is a better answer than this :)
You could dump the returned html into a variable and then check if the variable is null before doing another ajax call
var logos = null;
var banners = null;
var footer = null;
$(".logos").click(function(){
if (logos == null) // do ajax and save to logos variable
else $("div").html(logos)
});
Mark nailed it .one() will save extra line of codes and many checks hassle. I used it in a similar case. An optimized way to call that if they are wrapped in a parent container which I highly suggest will be:
$('#id_of_parent_container').find('button').one("click", function () {
//get the id of the button that was clicked and do the ajax load accordingly
});

Categories

Resources