How to use phantomjs to take screen shot with dynamic data visualization - javascript

When I follow this tutorial (http://phantomjs.org/screen-capture.html) to do a screen capturing, I got some problem about dynamic data visualization.
In that tutorial, it uses some code like:
var page = require('webpage').create();
page.open('http://localhost:8080/index.html', function() {
page.render('screenshot.png');
phantom.exit();
});
But this seems work only with static page. I wonder if I have some some user interaction and make that page changed(like mouse click change color etc.), how can I make that capturing which show current screen?
If phantomjs can not work in this way, could anyone suggest some other solutions?

Sure, just add the functionality you want after page.open() and before page.render().
page.open('http://localhost:8080/index.html', function() {
/**
* Add your events and actions here...
* or call JS functions of the page itself...
*/
page.evaluate(function() {
/**
* Inject a <style text/css> tag in the head,
* which set the bgcolor
*/
var style = document.createElement('style'),
text = document.createTextNode('body { background: red }');
style.setAttribute('type', 'text/css');
style.appendChild(text);
document.head.insertBefore(style, document.head.firstChild);
});
page.render('screenshot.png');
phantom.exit();
});
Keep in mind that you are working with Javascript here and that you can inject arbitrary helper scripts, like CasperJS or jQuery, and use their functionality on the loaded page.
For inspiration:
PhantomJS; click an element
How to retrieve the ajax data whose loading requires a mouse click with PhantomJS or other tools
see especially this answer for clicking, screenshot-after-click and ajax stuff: https://stackoverflow.com/a/18274644/1163786
Browse a bit, then screenshot: https://stackoverflow.com/a/17506213/1163786

Related

How to inject userscripts into embedded web page content?

I have a userscript I'd like to inject after clicking a link to open an embedded web page. Specifically, I'd like to know how I should go about injecting this script:
Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)).forEach(i => i.style.display = 'none');
Array.from(document.querySelectorAll('div')).filter(i => /moreComments-/.test(i.id)).forEach(i => i.querySelector('p').click());
setTimeout(function() {
Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)).forEach(i => i.style.display = 'none');
},7000)
Into all embeddable Reddit subpages, i.e. all linked threads loaded from a subreddit's main page:
An image illustrating an embedded Reddit subpage in contrast to a standard fully-loaded page
I assume this requires an event listener or MutationObserver, but I don't know how to go about specifying the solution. Reading the Reddit source is deeply confusing and I'm not a coder. This is just something I think would be useful to know for myself and other everyday web users.
What are the right steps to follow in problem-solving a case like this? What kind of code should I consider?
You need to process the userscript on a selected group of page nodes. Because your code is only executed once per page load event, the nodes that load dynamically later on remain unaffected.
There are several ways to achieve your goal. One of the simplest approaches involves the use of the setInterval function. This calls your function periodically (by using a reasonable time span, say 500ms). With this function, you have to select the nodes you want and process only new arrival nodes. You can mark your node's DOM objects with something like the _is_processed property. And finally this can be wrapped into another function, say doForEachOnce. For example:
function doForEachOnce(list,theFunc) {
list.forEach(i => {
if (!i._is_processed) { i._is_processed = true; return theFunc(i); } else { return null; }
});
}
doForEachOnce(Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)), i => i.style.display = 'none');
doForEachOnce(Array.from(document.querySelectorAll('div')).filter(i => /moreComments-/.test(i.id)), i => i.querySelector('p').click());
setInterval(function() {
doForEachOnce(Array.from(document.querySelectorAll('span')).filter(i => /(\d+)\spoint/.test(i.innerHTML)), i => i.style.display = 'none');
},500);
I tested this userscript successfully with Tampermonkey. It expands all comments, hides the karma on page load, and then hides the karma again for each new arrival. Hope this is what you need.
Your question is too general, but I assume you asking something basic. If targeting some specific platform, please clarify your question.
I assume you want just inject javascript code into the web HTML page or part of HTML page.
Usually this done via script tag
<script>
/* Your code is here */
Array.from(document.querySelectorAll.......
</script>
To force a link to call your code, you have to wrap your code inside function and format href attribute of a tag as javascript:func_name()
<script>
function my_func()
{
/* Your code is here */
Array.from(document.querySelectorAll.......
}
</script>
click me

Adding Facebook Pixel event to Squarespace button click

I'm trying to add a Facebook pixel event -- "ViewContent" -- to my Squarespace site. I have one page with one button, and I want to fire the event on the button click. It feels like it should be simple, but I'm consistently getting an error in Facebook Pixel Helper with my current setup.
I'm referencing this post: Add FB pixel event code into button - Squarespace
And as recommended in the answer, I'm using a per-page code injection in the header on this page: https://www.wearpapercrane.com/survey
This is what I have --
<script>
(function() {
var btns = document.getElementsByClassName("sqs-block-button-element");
var i, I;
for (i=0, I=btns.length; i<I; i++) {
btns[i].addEventListener("click", function() {
fbq("track", "ViewContent");
});
}
})();
</script>
But here's what I get on the other end when I use Facebook Pixel Helper to validate --
(This is after the click, by the way ... the button opens the link in a separate tab, so this is going back to the page after the click and looking at Pixel Helper).
Is there something I'm missing that is resulting in this error?
I have the pixel installed and I have a "lead" event working properly on another page (using Squarespace's Form Embed feature), so I'm pretty sure it's a problem with this specific code injection.
Would love any and all recommendations. Thank you!!
The event is not firing because the answer you referenced (which I wrote) did not account for the fact that, when injecting the code via header injection (site-level or page-level), one must wait for the DOM to be loaded before attaching events to the elements.
The answer you have referenced has been updated, notably the following section:
<script>
window.Squarespace.onInitialize(Y, function() {
var btns = document.getElementsByClassName("sqs-block-button-element");
var i;
for (i=btns.length-1; i>=0; i--) {
btns[i].addEventListener("click", function() {
fbq("track", "AddToCart");
});
}
});
</script>

Infinite Scroll + Swipe.js

Background:
I'm making a portfolio site utilising both Swipe.js and Infinite Ajax Scroll (JQ).
Problem:
When the content from extra pages is loaded into the current page, it is not processed by the already-loaded Swipe.js script. This means that the new content doesn't have it's mark-up changed (needed for the swipe functionality to work).
I think I need to get the Swipe.js script to fire after each page re-load. Would that fix it? Please explain this to me like I'm an 8yr old. JS is not a strong suit...
Demo:
http://hatchcreative.co.nz/tomo
You can see that as the page loads new content, the buttons on either side of the sliders no longer work.
Yes you're right, after the images are loaded you have to create a new Swipe instance on these new elements (as they weren't there at the beginning, when the page was loaded).
Based on the docs of infinite scroll you can use onRenderComplete.
So you had your jQuery.ias constructor like this:
jQuery.ias({
// ... your settings...
onRenderComplete: function(items) {
$(items).each(function(index, element) {
new Swipe(element);
});
}
});
This should work this way somehow, but I am not exactly sure; I haven't worked with these libraries yet.
Edit:
After some more inspection of your code, I saw you had some inline click handler like: onclick='two.prev();return false;'.
You need to remove this and add your onclick handle in the same onRenderComplete function.
onRenderComplete: function(items) {
var swipe;
$(items).each(function(index, element) {
swipe = new Swipe(element);
});
// find tags with the class 'forward' inside the current element and add the handler
$(element).find('.forward').on('click', function() {
swipe.next();
});
// ... also for previous
}
By the way: Usually you should provide a jsFiddle with your important code parts, so it's easier for us to get the problem, and the question is not getting obsolote when the linked page changes.

load a part of the page without refreshing it

I am pretty new to web design. I just finished my first static website.
What i dont like about it is that the page often reload (each time you change section)
My question is "how to make this kind of nav : http://www.doblin.com/work/#innovation-strategy"
As you see the page doesnt reload when you click on "Set Innovation Strategy / Design, Build + Launch Innovations / Become Better Innovators"
How it s done ?
Is it possible on a static website (html/css/jquery) without sql or so (it may require ajax or ...) ?
Thanks
Taking a look at the code, this page uses some jQuery functions to do this work, check it out:
$(window).hashchange( function(){
var hash = location.hash;
// if a hash has been set
if(hash !== '') {
showContent(hash, origSections);
} else {
// pass in "empty" hash
showContent('', origSections);
}
return false;
});
// call hashchange on initial page load
$(window).hashchange();
// ----------- SHOW CONTENT ----------- //
function showContent(active, all) {
if (jQuery.support.opacity) {
opacity = true;
} else {
opacity = false;
}
This can also be done using CSS3 transitions and animations. Here's a pen based on this Codrops tutorial. I particularly think this is a better approach
But if you want to get dynamic data from somewhere, i advise you to use Ajax(There are some cool jQuery stuff to handle this)
you can use Jquery on your static website. You can go through below link
Jquery
But if you wish to save data and retrieve from server then you need to use Ajax to avoid refreshing page.There are many tutorials available on how to use Ajax
Take a (hard) look at JQuery or Dojo, any of them will be your friend.
Your example uses JQuery.
It can be done on one static page without worries.
Here you have some demos: http://jqueryui.com/tabs/
You can also study jquery on http://w3schools.com/jquery/default.asp

jquery causing “white” on load

I've searched this a bit on the forum, and can't seem to figure out how to fix the common issue of white flashing when a new page loads.
I've tried Chris Coyer's example of placing this above my other javascript:
// Prevent variables from being global
(function () {
/*
1. Inject CSS which makes iframe invisible
*/
var div = document.createElement('div'),
ref = document.getElementsByTagName('base')[0] ||
document.getElementsByTagName('script')[0];
div.innerHTML = '­<style> iframe { visibility: hidden; } </style>';
ref.parentNode.insertBefore(div, ref);
/*
2. When window loads, remove that CSS,
making iframe visible again
*/
window.onload = function() {
div.parentNode.removeChild(div);
}
})();
but, still flashing. I'm a noob to javascript, so I'm not really sure what I'm doing wrong.
The page that is the worst is: http://thegoodgirlsnyc.com/test/new/index3_7.php
If you're using Jquery try wrapping your function with:
$(document).ready(function(){
/* Code goes here */
});
This will execute your code when the document is ready (fully loaded)
The problem is that you're executing tasks throughout the pageload. You're getting the flashing because code is being run in-time with page load.
You need to abstract the running of the code behind a unified point. This is where things like $(document).ready() are nice from jQuery. It happens upon DOM completion, but before window load completion. This means it happens before visual, which prevents screen flash Javascriptiong.
It seems like you're worried about the global namespace:
jQuery( function($){
$('iframe').hide();
$(document).ready( function(){
$('iframe').show();
});
});
This is an easy solution that alleviates the namespacing issue, and you won't have to refactor current code. So my answer is two parts:
Use jQuery.
Use namespacing.
If you still get screen flashing using the above, you need to set the display to none in the stylesheet for the iframe element.

Categories

Resources