jQuery Slimbox is not requesting files correctly - javascript

I am using jQuery slimbox with it's API.
Here is my JavaScript that gets image paths via JSON, and then launches the slimbox via it's API.
$('#main-container').append('<span id="check-our-adverts">Check our Adverts</span>');
var advertImages = [];
$.getJSON( config.basePath + 'get-adverts/', function(images) {
advertImages = images;
});
$('#check-our-adverts').click(function() {
console.log(advertImages);
$.slimbox(advertImages, 0);
});
The JSON is returning ["\/~wwwlime\/assets\/images\/adverts\/advert.jpg","\/~wwwlime\/assets\/images\/adverts\/advert2.jpg"].
The actual page is here. Click top red box next to the frog. If you have a console, check it for the JSON returned.
When I view the request using Live HTTP Headers, it seems slimbox is requesting vanquish.websitewelcome.com/ and nothing else.
This is resulting in the slimbox being launched, and it's throbber spinning forever.
What could be causing this problem? Thanks
Update
I added this inside the JSON callback
$.each(images, function(i, image) {
$('body').append('link');
});
And clicking those links takes me directly to the image... what gives?

I am not 100% familiar with slimbox but the api says that the method takes and array of arrays, so your return from JSON should, i believe, look more like
[["\/~wwwlime\/assets\/images\/adverts\/advert.jpg"],["\/~wwwlime\/assets\/images\/adverts\/advert2.jpg"]]
making you call to slimbox
$.slimbox( [["\/~wwwlime\/assets\/images\/adverts\/advert.jpg"],["\/~wwwlime\/assets\/images\/adverts\/advert2.jpg"]],0);
let me know if that helps?

Related

How can I get the front page size of website using phantomjs

I want to check the front page size of any website using PhantomJS. Antone help me how?
Assuming your page is opening without issues, you can set Page.prototype.onResourceReceived callback (which has a bodySize property in the response corresponding to the Content-Length response header):
page.onResourceReceived = function (resp) {
console.log(JSON.stringify(resp));//check resp.bodySize
};

Changing a link dynamically in PhantomJS and clicking it to scrape the page

I've been trying to figure this out for a couple days now but haven't been able to achieve it.
There's this web page were I need to scrap all records available on it, I've noticed that if I modify the pagination link with firebug or the browser's inspector I can get all the records I need, for example, this is the original link:
<a href="javascript:gReport.navigate.paginate('paginator_min_row=16max_rows=15rows_fetched=15')">
If I modify that link like this
<a href="javascript:gReport.navigate.paginate('paginator_min_row=1max_rows=5000rows_fetched=5000')">
And then click on the pagination button on the browser (the very same that contains the link I've just changed) I'm able to get all records I need from that site (most of the time "rows" doesn't get any bigger than 4000, I use 5000 just in case)
Since I have to process that file by hand every single day I thought that maybe I could automatize the process with PhantomJS and get the whole page on a single run without looking for that link then changing it, so in order to modify the pagination link and getting all records I'm using the following code:
var page = require('webpage').create();
var fs = require('fs');
page.open('http://testingsite1.local', function () {
page.evaluate(function(){
$('a[href="javascript:gReport.navigate.paginate(\'paginator_min_row=16max_rows=15rows_fetched=15\')"]').first().attr('href', 'javascript:gReport.navigate.paginate(\'paginator_min_row=1max_rows=5000rows_fetched=5000\')').attr('id','clickit');
$('#clickit')[0].click();
});
page.render('test.png');
fs.write('test.html', page.content, 'w');
phantom.exit();
});
Notice that there are TWO pagination links on that website, because of that I'm using jquery's ".first()" to choose only the first one.
Also since the required link doesn't have any identificator I select it using its own link then change it to what I need, and lastly I add the "clickit" ID to it for later calling.
Now, this are my questions:
I'm, not exactly sure why it isn't working, if I run the code it fetches the first page only, after examining the requested page source code I do see the href link has been changed to what I want but it just doesn't get called, I have two different theories on what might be wrong
The modified href isn't getting "clicked" so the page isn't getting updated
The href does get clicked, but since the page takes a few seconds to load all results dynamically I only get to dump the first page Phantomjs gets to see
What do you guys think about it?
[UPDATE NOV 6 2015]
Ok, so the answers provided by #Artjomb and #pguardiario pointed me in a new direction:
I needed more debugging info on what was going on
I needed to call gReport.navigate.paginate function directly
Sadly I simply lack the the experience to properly use PhantomJS, several other samples indicated that I could achieve what I wanted with CasperJS, so I tried it, this is what I produced after a couple of hours
var utils = require('utils');
var fs = require('fs');
var url = 'http://testingsite1.local';
var casper = require('casper').create({
verbose: true,
logLevel: 'debug'
});
casper.on('error', function(msg, backtrace) {
this.echo("=========================");
this.echo("ERROR:");
this.echo(msg);
this.echo(backtrace);
this.echo("=========================");
});
casper.on("page.error", function(msg, backtrace) {
this.echo("=========================");
this.echo("PAGE.ERROR:");
this.echo(msg);
this.echo(backtrace);
this.echo("=========================");
});
casper.start(url, function() {
var url = this.evaluate(function() {
$('a[href="javascript:gReport.navigate.paginate(\'paginator_min_row=16max_rows=15rows_fetched=15\')"]').attr('href', 'javascript:gReport.navigate.paginate(\'paginator_min_row=1max_rows=5000rows_fetched=5000\')').attr('id', 'clicklink');
return gReport.navigate.paginate('paginator_min_row=1max_rows=5000rows_fetched=5000');
});
});
casper.then(function() {
this.waitForSelector('.nonexistant', function() {
// Nothing here
}, function() {
//page load failed after 5 seconds
this.capture('screen.png');
var html = this.getPageContent();
var f = fs.open('test.html', 'w');
f.write(html);
f.close();
}, 50000);
});
casper.run(function() {
this.exit();
});
Please be gentle as I know this code sucks, I'm no Javascript expert and in fact I know very little of it, I know I should have waited an element to appear but it simply didn't work on my tests as I was still getting the page without update from the AJAX request.
In the end I waited a long time (50 seconds) for the AJAX request to show on page and then dump the HTML
Oh! and calling the function directly did work great!
The href does get clicked, but since the page takes a few seconds to load all results dynamically I only get to dump the first page Phantomjs gets to see
It's easy to check whether it's that by wrapping the render, write and exit calls in setTimeout and trying different timeouts:
page.open('http://testingsite1.local', function () {
page.evaluate(function(){
$('a[href="javascript:gReport.navigate.paginate(\'paginator_min_row=16max_rows=15rows_fetched=15\')"]').first().attr('href', 'javascript:gReport.navigate.paginate(\'paginator_min_row=1max_rows=5000rows_fetched=5000\')').attr('id','clickit');
$('#clickit')[0].click();
});
setTimeout(function(){
page.render('test.png');
fs.write('test.html', page.content, 'w');
phantom.exit();
}, 5000);
});
If it's really just a timeout issue, then you should use the waitFor() function to wait for a specific condition like "all elements loaded" or "x elements of that type are loaded".
The modified href isn't getting "clicked" so the page isn't getting updated
This is a little trickier. You can listen to the onConsoleMessage, onError, onResourceError, onResourceTimeout events (Example) and see if there are errors on the page. Some of those errors are fixable by the stuff you can do in PhantomJS: Function.prototype.bind not available or HTTPS site/resources cannot be loaded.
There are other ways to click something that are more reliable such as this one.

Latest tweet not always showing

With the follow code, the latest tweet is only occasionally showing in Chrome but always in Firefox. Typically only shows in Chrome with /? on the url but vanishes when I refresh.
jQuery(document).ready( function(){
console.log("getting twitter data..");
jQuery.getJSON("http://twitter.com/statuses/user_timeline/*hidden*.json?callback=?", function(data) {
console.log("got it..", data);
jQuery("#tweet").html(data[0].text);
jQuery("#ttime").html(data[0].created_at);
} );
});
You are trying to get the direct JSON from the twitter API. This is not possible due the same origin policy. You are only allowed to get JSON from your own domain.
A workaround exists and it's called JSONP (JSON with padding) and that's what twitter is using. You need to append the name of a function to the callback parameter in the URL. This function then gets executed when the twitter API loads.
For example you could do it like this:
JavaScript
function render(data) {
// data is the object that contains your twitter data. It's an usual JavaScript object.
}
HTML
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/username?
callback=render"></script>
Make sure that render is already loaded when the twitter API loads.

prototype ajax fetching images from other domain

i have two paths like:
a) localhost/firstapplication/
b) localhost/secondapplication/images
in firstapplication i do a ajax-request to secondapplication/html/index.html. e.g. i fetch the whole responsetext.
in secondapplication there are some img-tags:
<img src="../images/testpicture.png" alt="test" />
my problem: if i append the whole responsetext my browser is looking for the images.. the link is relative, wich means in: firstapplication/images.
But i want the images of the secondapplication.
Is there any way to get them really easy? Or do i have to change all values of the src-attributes in each img tag from "../images" to a fix path like "localhost/secondapplication/images/"?
thanks for support.
im working with prototype js 1.7 and i'd prefere a solution with this framework. thanks!
If firstapplication and secondapplication are on different domains the AJAX will not work due to Same Origin Policy. As such, I have not given a response to your image problem because once deployed on live your code will not work.
I see a few possibilities
Use an iframe instead of AJAX.
Have the second domain serve absolute URLs.
Manipulate the URLs when the AJAX completes.
new Ajax.Updater('secondapplication/html/index.html', 'ELEMENT_ID', {
onSuccess: function(response){
var receiver = $(this.container.success);
var otherDomain = 'http://localhost/secondapplication/';
var selector = '[src]:not([src^=/]):not([src^=http])';
receiver.select(selector).each(function(element) {
element.src = otherDomain+element.readAttribute('src');
});
selector = '[href]:not([href^=/]):not([href^=http]):not([href^=#])';
receiver.select(selector).each(function(element) {
element.href = otherDomain+element.readAttribute('href');
});
}
});
// otherDomain must end in a solidus, /
// not tested

How to use javascript to get information from the content of another page (same domain)?

Let's say I have a web page (/index.html) that contains the following
<li>
<div>item1</div>
details
</li>
and I would like to have some javascript on /index.html to load that
/details/item1.html page and extract some information from that page.
The page /details/item1.html might contain things like
<div id="some_id">
picture
map
</div>
My task is to write a greasemonkey script, so changing anything serverside is not an option.
To summarize, javascript is running on /index.html and I would
like to have the javascript code to add some information on /index.html
extracted from both /index.html and /details/item1.html.
My question is how to fetch information from /details/item1.html.
I currently have written code to extract the link (e.g. /details/item1.html)
and pass this on to a method that should extract the wanted information (at first
just .innerHTML from the some_id div is ok, I can process futher later).
The following is my current attempt, but it does not work. Any suggestions?
function get_information(link)
{
var obj = document.createElement('object');
obj.data = link;
document.getElementsByTagName('body')[0].appendChild(obj)
var some_id = document.getElementById('some_id');
if (! some_id) {
alert("some_id == NULL");
return "";
}
return some_id.innerHTML;
}
First:
function get_information(link, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", link, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.responseText);
}
};
xhr.send(null);
}
then
get_information("/details/item1.html", function(text) {
var div = document.createElement("div");
div.innerHTML = text;
// Do something with the div here, like inserting it into the page
});
I have not tested any of this - off the top of my head. YMMV
As only one page exists in the client (browser) at a time and all other (virtual/possible) pages are on the server, how will you get information from another page using JavaScript as you will have to interact with the server at some point to retrieve the second page?
If you can, integrate some AJAX-request to load the second page (and parse it), but if that's not an option, I'd say you'll have to load all pages that you want to extract information from at the same time, hide the bits you don't want to show (in hidden DIVs?) and then get your index (or whoever controls the view) to retrieve the needed information from there ... even though that sounds pretty creepy ;)
You can load the page in a hidden iframe and use normal DOM manipulation to extract the results, or get the text of the page via AJAX, grab the part between <body...>...</body>ยจ and temporarily inject it into a div. (The second might fail for some exotic elements like ins.) I would expect Greasemonkey to have more powerful functions than normal Javascript for stuff like that, though - it might be worth to thumb through the documentation.

Categories