I'm trying to play a sound every time a user gets a new notification. The way I am loading the notifications on my page is simple:
(function($)
{
$(document).ready(function()
{
var $container = $("#noti");
$container.load("notify.php");
var refreshId = setInterval(function()
{
$container.load('notify.php');
}, 1000);
});
})(jQuery);
This works by updating a div container with whatever number the PHP code sends out. it retries every second (probably not the most efficient way, but it works).
I have another piece of code that checks when the div content changes, then creates an alert box (which I will change to playing a sound when the script is done):
var myElement = document.getElementById('noti');
if(window.addEventListener) {
// Normal browsers
myElement.addEventListener('DOMSubtreeModified', contentChanged, false);
} else
if(window.attachEvent) {
// IE
myElement.attachEvent('DOMSubtreeModified', contentChanged);
}
function contentChanged() {
// this function will run each time the content of the DIV changes
alert("js is working");
}
This script works, however it also creates an alert or the first loading of the notifications. This is because it starts of as an empty div, then it loads the data, which sets off this alert script. The only way I could think about going round this is delaying the script from loading for a couple of seconds whilst the AJAX script does its business.
Does anyone know a way I could delay this second script from doing anything for the first few seconds after page load, or perhaps a better way about going round this?
Instead of doing that, use a custom event which you trigger when load finishes:
var refreshId = setInterval(reloadContainer, 1000)
function reloadContainer() {
$container.load('notify.php', function success() {
$container.trigger('loaded')
})
}
$(myElement).on('loaded', contentChanged)
Related
I have spend a lot of time think about this and tried different things now. I want to scrape a webpage with multiple pages but the page does not reload on page change. Instead, some container data is changed on each changed page. The most difficult thing to do is know when to click the next page button.
Someone might think that this is pretty easy and I thought the same and started off by doing:
$('.pagn a').each(function() {
console.log(`Loop counter`)
$(this).click()
//Code to scrape the new page
})
Now, the loop runs 13 times but only one page is changed. This is because the pagination itself is inside the container that reloads so all other button presses are basically ignored.
To tackle this I needed some kind of a check that makes sure that the new content has loaded before proceeding but if I try to do something like:
$('.pagn a').each(function() {
console.log(`Loop counter`)
while (someConditionToCheckIfPageLoaded) {
}
$(this).click()
//Code to scrape the new page
})
This would be an infinite loop because JavaScript is single threaded and the code to change the condition never fires.
I also tried this which I now know is incorrect.
The indicator for page being loaded is if the button URL matches the page URL.
$('.pagn a').each(function() {
let visitedURL = [];
if ($(this).attr('data-url')) {
let button = $(this)
buttonURL = "https://www.ebay.com/myb/PurchaseHistory#" + $(this).attr('data-url');
(function wait() {
button.click()
if (buttonURL == location.href && !visitedURL.includes(button.html())) {
console.log(button.html())
button.click()
visitedURL.push(button.html())
console.log(buttonURL);
console.log(location.href);
//Scrape page
} else {
setInterval(wait, 5000);
}
})();
}
})
This also only changes one page.
If someone has been able to scrape webpages with multiple pages with JavaScript please let me know how.
Edit1:
Also, I am not sure why this creates an infinite loop as well:
let glbElements = []
$('.pagn a').each(function() {
glbElements.push($(this))
})
for(let i = 0 ; i<glbElements.length; i++){
console.log(`Loop Counter`)
setTimeout(function(){
console.log(`Inside SetTimeout`)
glbElements[i].click()
glbElements.splice(i,1)
},2000)
}
Lopp Counter *5
Inside SetInterval -- Keeps printing
You can use the setTimeout() function to wait after a user clicks a button.
Like this:
<a href='newpage.html'><button id='click'>Click!</button</a>
$('#click').click(function() {
setTimeout(function() {
// code you want executed after page is loaded
}, 100);
});
I have a situation where I must wait for a Specific image to load, and then either swap out its src, or locate the next image and hide/show it.
What I need to happen is show a placeholder image (silhouette) until its main image is ready, and then hide the silhouette and show the main image. Very common stuff.
Problem is this jquery function does not fire on a new tab, or window... but if I hit f5 it works perfectly... but then again I open a new tab, and it wont fire until I hit f5.
CSS:
.staffImage1, .staffImage2, .staffImage3, .staffImage4, .staffImage5 { display: none; }
Jquery:
$('.staffImage1, .staffImage2,.staffImage3,.staffImage4, .staffImage5')
.load(function () {
$(this).next('.sillhouette').hide();
$(this).show();
console.log("function fired")
})
I get the log message only after refresh.
Something to be aware of is I am using the "First 14k" method to increase page speed, so maybe jquery just is not ready when the images are initially loaded the first time, but are cached and work after f5?
Each image must wait until its fully loaded, they are in a slider, so I need to show the first slides image as soon as its ready,I cannot wait until all 5 images are ready, as that would slow down the first slides image.
Any advice is appreciated, thank you
This structure:
$('.staffImage1, .staffImage2,.staffImage3,.staffImage4, .staffImage5').load(...)
does not work to notify you when all the images have been loaded. .load() only works on a single image at a time. And, if the images are cached, they may already have finished loading before your jQuery even runs so you would miss the load event entirely.
The simplest work-around is to use the window load event when all page resources have finished loading:
$(window).load(function() {
// all images are loaded here
});
It is also possible to monitor just those 5 images, but that is more work. I've written code to do this before so I'll see if I can find that prior code.
Here's a jQuery plug-in function that monitors just specific images. It will call its callback when all the images in the jQuery object are loaded:
// call the callback when all images have been loaded
// if all images are already loaded or there were no images in the jQuery
// object, then the callback will be called immediately
jQuery.fn.imgsLoaded = function(fn) {
var cntRemaining = 0;
function checkDone() {
if (cntRemaining === 0) {
fn();
}
}
function imgDone() {
--cntRemaining;
checkDone();
// remove event handlers to kill closure when done
$(this).off("load error abort", imgDone);
}
this.each(function() {
if (!this.tagName.toLowerCase() === "img" && !this.complete && this.src) {
++cntRemaining;
$(this).on("load error abort", imgDone);
}
});
checkDone();
return this;
}
You could use it like this:
$('.staffImage1, .staffImage2,.staffImage3,.staffImage4, .staffImage5').imgsLoaded(function () {
$(this).next('.sillhouette').hide();
$(this).show();
console.log("function fired")
});
Working demo: http://jsfiddle.net/jfriend00/zaoweyoo/
Write jquery code
'$(document).ready(function(){
//your code
});'
I have a question about a Javascript-file I've made. It makes sure hyperlinks open in a div and not in a new tab. However, I've also made a very simple text-inclusion to show while the page is loading.
$(document).ready(function () {
$('a').on('click', function(e){
e.preventDefault();
var page_url = $(this).prop('href');
var loading =
$('#content')
.html('<h2>The page is loading. A second please.</h2>')
.load(page_url);
});
});
However, some pages are considerably loading faster than others. In other words, in some pages it's very useful to have this script, but when a page is loading immediately, it's just simply very annoying.
Is it possible to measure the time that the 'load' takes, and accordingly, display html or not? (I was thinking about something like: "If time-loading>1000 .html('blabla') / Else").
You can do something like that:
var timer = setTimeout(function() {
$('#content').html('<h2>The page is loading. A second please.</h2>');
timer = null;
}, 1000);
$('#content').load(page_url, function() {
if (timer) {
clearTimeout(timer);
}
});
For fellow googlers, I combined the comments and the answer above to provide a solution. What I did was the following: instead of not displaying the loading message if the page was loading within a second, I made sure it was at least displaying at least a second:
$(document).ready(function () {
$('a').on('click', function(e){
e.preventDefault();
$('#content').html("<div id='status' class='status'></div>");
$('#status').html('<h2>The page is loading. A second please.</h2>');
var page_url = $(this).prop('href');
var loadingMsg = setTimeout(function(){
$('#content').load(page_url, function (){
clearTimeout(loadingMsg);
$('#status').html();
});
},1000);
});
});
The reasons why I did this, is because I couldn't get the timeout-function consistent. Sometimes it worked perfectly, but sometimes the screen just froze and nothing was displayed until the page loaded. Now, it is displayed at least a second, and if the loading takes more, it will be displayed until the page loads.
Thanks for your answers and I hope this helps for people with a similar problem!
I've been having trouble finding any delays right after a function is executed. The problem is that the href loads a little slow and the function takes in effect before the _target page is loaded. You can see the change coming into effect immediately. I'd like to have a little timer to wait a few seconds before the function takes affect.
I've tried setInterval inside a var, but it doesn't seem to be working. setInterval by itself keeps running once the page is clicked and I don't want that. I want the timer to be started once the image is clicked and the link loaded.
<script type='text/javascript'>
function change() {
var image = document.getElementById('doge');
image.src = 'img/doge.png';
document.getElementById("text").innerHTML="<b>such wow</b> much amaze <b><i>very effort</b></i>"
}
</script>
<img src='Logo_256.png' alt='doge' id='doge' onclick='change();'>
<small id='text'>This page was last modified on Wednesday, November 20, 2013 8:43:13 PM</small>
I assure you everything works, so don't mind if the .jpg or .png match up (just edited right now).
Add a timeout to the things that the function does, so the delay occurs when the function runs what you want to happen in your change() function after a setTimeout():
var change = function(){
setTimeout(function() {
var image = document.getElementById('doge');
image.src = 'img/doge.png';
document.getElementById("text").innerHTML="<b>such wow</b> much amaze <b><i>very effort</b></i>"
}, 5000);
};
My website works in a way so that any links clicked do not load a new page but however trigger a .load() event into a div named "content".
Everything has been nice and dandy but now I have run into a small problem.
On one of the content pages, I have the following code:
$('.count').each(function () {
$this = $(this);
countdown = setInterval(function(){
countnow = parseInt($('.remain', $this).html());
$('.remain', $this).html(countnow-1);
}, 1000);
return false;
});
The code works... it works very well. But when I load that same page again, it seems like the code is running twice because the seconds are going down by 2 at a time. Then when I load it again, it's going down by 3 seconds at a time. Another load, and it goes down by 4 seconds at a time. I load it a couple more times and it goes down faster then I can read.
I tried giving the .count divs their own unique id's (the .remain div is nested inside the .count div), even when pages are subsequently loaded the id is still entirely different and this did not fix my problem. I also tried putting clearInterval(countdown) right before the function but that just made it stop working entirely. Any suggestions?
And yes I know the countdown doesn't currently stop when it reaches 0.
Try this:
var countdown;
$('.count').each(function () {
$this = $(this);
if (!countdown)
countdown = setInterval(function(){
countnow = parseInt($('.remain', $this).html());
$('.remain', $this).html(countnow-1);
}, 1000);
return false;
});