Chrome Extension Javascript/jQuery load page and check if changed - javascript

I'm looking for a way to load a website and then check after 1 min or so whether the content has changed, if not, repeat. This is because the website I'm trying to get content from contains javascript for loading the div I need. I thought of using some kind of iFrame, but I have no idea where to start and Google isn't helping me.
Edit
This is the code I'm running with atm and scrapUrl is a defined url so don't worry about it:
var iframe = document.body.appendChild(document.createElement('iframe'));
iframe.src = scrapUrl;
$(iframe).ready(function() {
$(iframe).load(function() {
alert('loaded');
alert($(iframe).contents().find('div#description').html());
});
});
It outputs "loaded" and after that "undefined"

So you're doing a lazy load of content in a div, and you want to know when that div has loaded? Depending how you're doing it, you'd be better to set a flag and react to the AJAX "load" event associated with that lazy load.
If you must do it the way you suggest, try this:
Create an interval (setInterval) that checks the load status, or the contents of the div
if false, do nothing. If true, clearInterval.

Related

Jquery LOAD as alternative or similar to IFRAME

I have jquery to load user messages every 1 second but I would like to implement a solution to the messages load to act, similar as a: <iframe>, <object> or <embed> tags
<script>
setInterval(
function()
{
$('#chat').load('load_chat.php');
}, 1000);
</script>
The problem is as it loads every 1 second I can't just use a iframe of the page, I need to keep using jquery, somebody has a solution?
I tried with:
<script>
setInterval(
function()
{
//$('#chat').load('load_chat.php');
$("#frame").attr("src", "load_chat.php");
}, 1000);
</script>
But this is not what I need, it flash the iframe all the time.
I need to make jquery load method looks like a iframe.
but the problem with using iframe is because I need jquery to refresh the frame every 1 second. some body has an idea of how to make <div id="chat"></div> have a scroll bar as iframe ?
First off all I think this is not the correct way to do this.
Read up on streams, because this type of use case is exactly what they where made for.
Then, if you have your load-chat.php loaded in an iframe, you can use the window send message method to trigger a reloadin the page by jquery.
The downside is, that your iframe should also contain a jquery instance.
Check this -> https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
I solved with the following:
$('#chat').css("overflow-y", "scroll");
If someone has a better alternative it would be appreciated.

Show an alert when image changes on website

I have a GitHub pages site with an image on it. I am trying to have the webpage show an alert whenever I push a change to the website.
My approach so far has been to implement an auto-refresh function:
setTimeout(function(){ location.reload(); }, 60000);
This will auto-update every minute, catching all of the changes that I make. However, I need to show an alert whenever the content of the page changes. It is important to keep in mind that the content will not change upon every refresh -- maybe only every 10 minutes (when I push changes).
I think the way to do this would be to store the name of the image and then look to see if the image name changes at every refresh -- and if the name did change, then show the alert. I have been reading about something called LocalStorage, but I'm not sure how to approach storing the name of a file -- I'm sort of new to JS/HTML.
Is using LocalStorage the best approach to this problem? What are other alternatives/simple ways to implement this on a GitHub page?
Thanks in advance.
If I clearly understand what you need to implement, I'd suggest you to read about MutationObserver in JavaScript. This class tracks all the changes, that are made to binded element. Here's the code and working demo:
<html>
<body>
<p>
Some content
</p>
</body>
<script>
// select the target node
var element = document.getElementsByTagName('p')[0];
// create an observer instance
var observer = new MutationObserver(function(mutations) {
alert("Some changes were made");
});
// configuration of the observer:
var config = { childList: true}; // ,subtree: true, characterData: true
// pass in the target node, as well as the observer options
observer.observe(element, config);
setInterval(function () { // here you can make your changes programatically
element.innerHTML += "New content";
}, 2000)
</script>
</html>
You can also use cookies, i.e. store in a cookie the last "version" of whatever - where "version" can be a string, a number etc.
This has the advantage that it also gets sent to the server, so you may generate the alert layout/code directly on the server.
Check https://github.com/js-cookie/js-cookie for a script simplifying this.
Another alternative is to implement on the server a script that responds whether the content changed. Something like http://foo.bar/changed?lastVer=XXXX which can return a JSON like {changed:true,message:'We have changed the change'}. You would retrieve this via ie. jQuery.getJSON() or vanilla XMLHttpRequest, and if it's the case show the message to the user and then reload the page. But this would require making a runnable server script somewhere.
A third option would be to load the page into, say, a hidden IFRAME, check if the image or content changed and if so transplant only the image - or a certain piece of content - to the main page without refreshing it. Or maybe refresh it. The idea is to load the page in an IFRAME and detect there if something has changed.

What to do if $(window).load(function(){}); is too early

I need to trigger a piece of code after every single bits are done downloading. The script works if injected after everything is loaded, but how do I trigger that automaticly?
My script is:
var divId = "jwplayer-0_wrapper";
if ($('#' + divId).length == 1) {
myReg = /https?:\/\/www\.youtube\.com\/watch\?v=[^"]+/;
var plainText = $('#' + divId).parent().children('script').text();
var url = plainText.match(myReg);
if (url !== null) {
window.location = url;
};
};
It is used to skip certain site that decide to use the JW player witch I find horribly buggy. So it looks for a div with the indication of the JW player and if there's one, it finds the link to the original youtube video and directly goes there.
Its triggered By Google Chrome Add-on named Javascript Injector and I apply the script on every page I visit. The plug in work perfectly well on sites like www.ayoye.co and www.veuxturire.com. But on other sites, that uses the same pathern, it seems that the script is triggerd too early. For example there www.mondedestars.com and www.lesautos.ca triggers it too early.
If I use the "inject now" fonction of the Add on after the page is really done loading, then it redirects me to the youtube page as expected. I am lost on the why it works some where and not were else.
I'm not trying to understand every single website here, I'd prefer make it dynamicly triggered after the page has done loading everything from its php, ajax, script, flash, html and CSS.
I've tryed to look to the JWplayer API, but since its terribly unclear to me, over the fact that its partialy in flash, it woudl be simpler if there was a way to trigger it after, or maybe just triggering it after i hover over the body, since every sites has a body. It cant be specific to one page.
Use something like this
var timer;
function injectYouTube() {
// DO YOUR STUFF HERE
// ONCE DONE CALL clearInterval(timer);
clearInterval(timer);
}
timer = setInterval(injectYouTube, 2000);
I am not saying this will be called after everything is loaded but instead you can make sure your code is executed when you want it to.
The JWPlayer API are not that difficult. You can retrive the informations you need even not knowing the container id.
This is an example:
var player = jwplayer(0); // get the first jwplayer element of the page
var video = player.getPlaylistItem(); // get the player video
var url = video.file // retrieve the video url
I think the setTimeout or setInterval are unreliable.
Setting up a listener on jwplayer onReady event would be better.
The pessimistic answer to this is that you can't wait until a page has finished all AJAX operations etc. because web pages can continue loading new content indefinitely if they wish.
What you might consider is running your code every time a new HTML element is added to the page. This way, you can be certain to catch JWPlayer the moment it is inserted into the page.
document.addEventListener("DOMNodeInserted", yourRemovalFunction);

Nivoslider (within dynamic ajax content) doesn't load images on first load

I am developing a website (jQuery + Ajax) and I stumbled on a problem. When a page loads dynamically (for the first time, images aren't cached yet), it doesn't display the images. When I recall the ajax load function, suddenly my pictures are there.
$("#overlayInner").load(source+" #loader",function() {
$('#workImgs').nivoSlider();
});
I call nivoSlider on my dynamic page outside my loader div, so people who arrive directly on this page, can see the images as well.
<script type="text/javascript">
$(function(){
$('#workImgs').nivoSlider();
});
</script>
When you try to load the page without Ajax, the images load like they should.
Any ideas?
It is hard to make experiments in your website :) but you can try to add to each loading page (4d.html, dokerpoot.html and vuylsteke.html) the code for image preloading (in the start of the body tag). I used example images from vuylsteke.html:
<script type="text/javascript">
var images = [
'images/work/kapsalon2.jpg',
'images/work/kapsalon3.jpg',
'images/work/kapsalon4.jpg'
];
$(images).each(function() {
$('<img/>')[0].src = this;
});
</script>
Since the fragment load function after get parses the returned document to find the element with an ID of container, the idea is to let it first to load these images into memory, and then start to parse the document, and finally initialize Nivoslider. Possibly it will help.
I had this issue with content being loaded from a database. It turns out it was being caused by the Images not having a width or height set. This means that the plugin didn't know the size of the images and didn't show them but the browser calc'd these properties after the re-load so it showed the second time around.
Setting a width and height resolved this.

Intercepting HTTP event using JQuery

I have this JQuery code working however I need to know whether how to actually get the URL executed from the tags selected.
$("link, script, style, a, img").each(function () {
$(this).load(function () {
// get the URL and log it
console.log("Intercepted HTTP Event");
});
});
First thing I need to do it to get the actual URL during the load.
Next thing I may need to do is to actually catch before the load event happens, I mean before an image or link is loaded for example. Also, I need to modify the URL of the event that will be executed, for example, img tag has src="/somewhere/image.png" I mean, this will cause a GET /somewhere/image.png I may need to change it to GET/otherplace/image.png
Any ideas how to achive any of these?
$(this).load() will fire after the contents of the element have been loaded. So you may be able to grab the URL by doing $(this).attr("src") or $(this).attr("href"), but it's already too late to stop the HTTP requests from going out.
AFAIK, with modern browsers, there's no way for JavaScript to prevent assets from being loaded in the first place. At best, you may be able to change images and stylesheets after the page has been loaded, by changing the src attributes. If you do this, make sure that $(this).load() doesn't go into an infinite loop. (<a> links are less of a problem. Nothing is loaded, so just change the href attribute.)
.attr('src')
http://api.jquery.com/attr/
One way to approach this problem would be to have some dummy links/hidden controls with the source of your external resource and once the page loads you go through all such controls and then create the respective html elements, update the src attribute and then append it to the dom.
Dummy Controls:
<input type="hidden" source="/my/source/a.jpg" nodeType="img" class="specialControls"/>
<input type="hidden" source="/my/source/1.js" nodeType="script" class="specialControls" />
and the javascript
$(document).ready(function()
{
$(".specialControls").each(function(){
var elementType=$(this).attr("nodeType");
$('<'+elementType+'/>').attr('src', $(this).attr("source"))
.insertAfter($(this))
});
});
Hope this helps.

Categories

Resources