So i've been looking around for a while for a possible solution to make a javascript, jquery which searches in the iFrame for a certain class or id element. Then takes out the html inside of it. (example. <a id="link">Here's a link</a> ). then makes it a string out of it and also replay this function every 5 second or so. Is there anyone who know a good solution to this or a tutorial?
I've tried the function var inf = $('#iframeid').contents().find('#theid').html();but it didn't gave any success.
Try this:
function GetFrameData() {
var $MyFrame = $("#iframeid");
// You need to wait for the iFrame content to load first
// So, that the click events work properly
$MyFrame.load(function () {
var frameBody = $MyFrame.contents().find('body');
var inf = frameBody.find('#theid').html();
});
}
// Call the function every 5 seconds
setInterval(GetFrameData, 5000);
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'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)
I am trying to fire a script when the contents of a div are altered, specifically when a div receives the next set of results from a js loaded paginator.
I have this:
<script script type="text/javascript" language="javascript">
document.addEventListener("DOMCharacterDataModified", ssdOnloadEvents, false);
function ssdOnloadEvents (evt) {
var jsInitChecktimer = setInterval (checkForJS_Finish, 111);
function checkForJS_Finish () {
if ( document.querySelector ("#tester")
) {
clearInterval (jsInitChecktimer);
//do the actual work
var reqs = document.getElementById('requests');
var reqVal = reqs.get('value');
var buttons = $$('.clicker');
Array.each(buttons, function(va, index){
alert(va.get('value'));
});
}
}
}
</script>
This works well when the doc loads (as the results take a few seconds to arrive) but I need to narrow this down to the actual div contents, so other changes on the page do not fire the events.
I have tried:
var textNode = document.getElementById("sitepage_content_content");
textNode.addEventListener("DOMCharacterDataModified", function(evt) {
alert("Text changed");
}, false);
But the above does not return anything.
Can what I am trying to do be done in this way? If yes where am I going wrong?
Using Social Engine (Zend) framework with MooTools.
I did this in the end with a little cheat :-(
There is a google map loading on the page that sets markers to match the location of the results. So I added my events to the end this code namely: function setMarker() {}.
I will not mark this as the correct answer as it is not really an answer to my question, but rather a solution to my problem, which is localised to the Social engine framework.
I will add a Social engine tag to my original question in the hope it may help someone else in the future.
Thanks guys.
I have an issue with a 'Latest News' module. Please have a look at http://www.proudfootsupermarkets.com/ to see an example of the module (it's the div close to the top of the page which has a large image in it).
At the moment I have it set up so that when a user clicks on a tab the main article shows. The jQuery for this is:
jQuery(document).ready(function() {
$(".moduletable.latestnews article:first-child").addClass("atfront")
$(".moduletable.latestnews article").click(function(){
$(".moduletable.latestnews article").css("zIndex",1).addClass("atback").removeClass("atfront");
$(this).css("zIndex",100).addClass("atfront").removeClass("atback");
});
});
This is all quite simple and straight forward. The problem that I am having is that I want the articles to change automatically after a few seconds. This would then go in an infinite loop starting with article 1 and then after a couple of seconds showing article 2 etc etc...
I am sure that this is fairly simple but I have just about exhausted my knowledge of JavaScript. Thank you for any help that you are able to give :)
I have created a jsfiddle http://jsfiddle.net/Bempv/
You can use setTimeout to change the article in front. If you select the article with the class ".atfront" and then use the .next() selector you should get the functionality you are looking for
$(function(){
var articleToggler = function articleToggler(){
var front = "atfront",
back = "atback";
return function(){
var selection = $(".moduletable.latestnews")
.find("article.atfront")
.addClass(back)
.removeClass(front);
next = selection.next("article");
next = next.length ? next : $(".moduletable.latestnews")
.find("article").first();
next.addClass(front)
.removeClass(back);
console.log(selection.length,next[0])
setTimeout(articleToggler(),1000); //changes every second
};
};
//start the rotation
(articleToggler())();
});
The setTimeout will call the function passed as the first argument once the timeout expires. The timeout argument is in miliseconds so the above code wait for 1 second before calling the function. Since the above function adds it self as the callback this will repeat indefinately
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;
});