i have a div that slides out of the screen, loads the new content and slides back.
I use jquery pjax and that part works great:
$('#menu a').on('click', function(event){
event.preventDefault();
var target = $(this).attr('href');
$('li.current').removeClass("current");
$(this).parent().addClass("current");
$(content).transition({left:$(document).width()}, 900, 'out', function() {
$.pjax({
url: target,
container: '#content',
fragment: '#content',
success: function(){
$(content).transition({ left:'0px'}, 900, 'out');
var contentHeight = $('#content').outerHeight(true)+258+$("#footer").outerHeight(true);
if(contentHeight<parseInt($("body").css("min-height"))){
contentHeight = "100%";
}
$(page).stop(true).animate({height:contentHeight}, 1000, "easeOutCubic");
}
});
});
});
But i don't get it do work if the browsers back/forward buttons are used.
I tried different things.
Here i found a nice article but i don't get it: http://artfindertech.wordpress.com/tag/historyapi/
The thing is that the content of the div changes in the moment you click the browser back button.
Then it slides out but not back.
Also the url changes to the previous page for a second but the jumps to the main url of the site.
Here is my trial for popState:
$(window).on('pjax:popstate', function() {
$(content).transition({left:$(document).width()}, 900, 'out', function() {
$.pjax({
container: '#content',
fragment: '#content',
success: function(){
$(content).transition({ left:'0px'}, 900, 'out');
var contentHeight = $('#content').outerHeight(true)+258+$("#footer").outerHeight(true);
if(contentHeight<parseInt($("body").css("min-height"))){
contentHeight = "100%";
}
$(page).stop(true).animate({height:contentHeight}, 2000, "easeOutCubic");
}
});
});
});
I'm trying to do the same thing right now i.e. to get animation functionality onpopstate. The way I see it right now is to:
on menu click call a function which will animate content and fill with the new content the container -
function animation(PageTitle,PageLink,check) {
//check if it is a call from menu and if it is than
//on animation and ajax complete call
if (check) {
setHistory(PageTitle,PageLink); // separate function to call it indimpendently
}
}
as set above, after animation finished call a function regarding window.history.pushState if is a call from menu links -
function setHistory(PageTitle,PageLink) {
window.history.pushState({'ptitle':PageTitle,'plink':PageLink}, PageTitle, PageLink);
}
after that set an onpopstatee function to call the function to the reverse animation and ajax -
window.onpopstate = function(event) {
animation(event.state.ptitle,event.state.plink,false);
}
I have not test it yet but I'm implementing it right now. If it will work I will update this...
UPDATE:
Just to update this and to tell that it works like a charm, as I presumed. An one more thing, for whom it may concern... I figured out that you must call a history.replacestate on original page load in order to have the possibility to go back to the original page with the relative variables and animation.
Related
So I have a html page which has a paragraph and button. When the button is clicked, the paragraph hides. I'm trying to automate this in Casperjs. So far, I load the page, take a screenshot, then click the button and take another screenshot. However, the screenshots are the same
var casper = require('casper').create();
casper.start('http://localhost:3000/example.html', function() {
this.echo("Loaded successfully.");
casper.capture("screenshot1.png");
});
casper.then(function() {
this.evaluate(function() {
this.click('//*[#id="hide"]')
});
});
casper.then(function(){
casper.capture("screenshot2.png");
});
casper.run();
Any ideas?
You can't use this.click() in evaluate() because the code in evaluate() will execute the code as if you were using the browser console.You can use javascript to get the element and use its click() event or you can just use this.click() directly.Anyway,don't use this.click() in evaluate().
This Could be the code if your button id='hide' as you describe your question:
var casper = require('casper').create();
casper.start('http://localhost:3000/example.html', function() {
this.echo("Loaded successfully.");
casper.capture("screenshot1.png");
casper.click('#hide'); // Clicking button with Id='hide'
casper.capture("screenshot2.png"); // capture after clicking button
});
// Execute the whole process
casper.run();
May this will helpful to you! Tx
I've got a problem where I can't seem to set the viewport for PhantomJS from within Node.js, using Phantom-Proxy as the module I'm using to bridge the two.
I've successfully got it all taking screengrabs of Web pages but like I've said above, I just can't set the viewport size.
In the Phantom-Proxy docs it says I should set the viewport property like:
//set viewport size for browser window
proxy.page.set('viewportSize',
{ width:320, height:480 }, function (result) {
console.log(result.toString().cyan);
worldCallback.call(self);
});
So in my code, I've tried setting the viewport above the lines that actually take the screengrab:
module.exports = function (app, phantom) {
app.get('/url/:url/:width?/:height?', function (req, res) {
phantom.create({"debug": true}, function (proxy) {
var page = proxy.page;
page.set('viewportSize', { width: 320, height: 480 }, function (result) {
console.log(result);
});
page.open(req.params.url, function () {
page.waitForSelector('body', function () {
page.renderBase64('PNG', function (img) {
res.set('Content-Type', 'image/png');
res.end(new Buffer(img, 'base64'), 'binary');
});
});
});
});
});
};
Though I didn't think this would work, so I tried putting the page.open inside page.set's callback and it got ignored, and also tried putting page.set inside page.open's callback and then page.waitForSelectorinside that.
The viewport still seems to be ignored though!
Any help would be greatly appreciated with this! Thank you all
Turns out it was working all along.
Basically, although the viewport was set correctly, that does not mean the Web page will necessarily be the width and height of the viewport (unless for example; the body had a width of 100%).
The Web page would scroll within the viewport, so the whole page is still rendered.
I'm writing a chrome extension that consists of a background process and a popup. The background process continually makes ajax requests to get new data, and the popup displays the info.
In an extremely simplified way, the background.js process looks like this:
var Background = {
data: {},
poll: function() {
$.ajax({
url: 'some_url',
success: function(data) {
this.data = data;
chrome.extension.sendMessage('update');
}.bind(this)
});
},
startPolling: function() {
setInterval(this.poll.bind(this), 10000);
}
};
$(Background.startPolling.bind(Background));
This shoots of an ajax request every 10 seconds, gets some data back, and sets it to Background.data. Again, this is very simplified. You can see the sendMessage call in the success callback.
My popup.js looks something like this, also extremely simplified:
var Background = chrome.extension.getBackgroundPage().Background;
angular.module('App', [])
.controller('PopupCtrl', function PopupCtrl($scope) {
$scope.data = Background.data;
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
if (request == 'update') {
console.log('update');
$scope.$apply();
}
});
});
And of course, popup.html looks something like:
<html ng-app="App" ng-csp>
<body ng-controller="PopupCtrl">
<p>{{data.title}}</p>
<p>{{data.body}}</p>
<p>{{data.date}}</p>
</body>
</html>
The message is definitely received, because I can see "update" print to the console every 10 second interval. I also know that the data is being updated properly because if I close and reopen the popup, the new data is displayed correctly. So $scope.$apply() is simply not doing anything.
How can I fix this?
I have a popup, call 'welcome.html', the thing I would like to do is when the user select a text, and click my plugin, it will use some of the page information, and print back to the welcome.html. For example, the web site title, and the text which the user selected and the url. But how can I pass value to that welcome.html? Thank you.
I do a lot of this in my extension as it mines a lot of data enabling the user to easily copy it to their clipboard.
Since you're looking for a lot less data it's even simpler. When your popup is being loaded you can call the following function to retrieve the information you require;
function getData(callback) {
chrome.tabs.getSelected(null, function (tab) {
var data = {
selection: '',
title: tab.title,
url: tab.url
};
/*
* We can't call content scripts on some pages and the process will get
* stuck if we try.
*/
if (tab.url.indexOf('chrome') === 0 ||
tab.url.indexOf('https://chrome.google.com/webstore') === 0) {
callback(data);
} else {
chrome.tabs.sendRequest(tab.id, {}, function (response) {
data.selection = response.selection;
callback(data);
});
}
});
}
Ensure you pass in a callback function which will be called once all the data has been extracted;
getData(function (data) {
console.log('Title: ' + data.title);
console.log('URL: ' + data.url);
console.log('Selected Text: ' + data.selection);
// Display the data instead
});
As you may have noticed the getData function sends a request to the selected tab. A content script will need to be injected in to the page in order for this to work so be sure you've configured your manifest correctly or injected it programmatically prior to calling getData or it won't work. The script that will need to be injected should resemble the following;
(function () {
chrome.extension.onRequest.addListener(function (request, sender,
sendResponse) {
sendResponse({
selection: window.getSelection().toString()
});
});
})();
This simply returns the currently selected text. One concern is that this data look-up could potentially cause a slight pause while the popup is rendered but you should test this yourself and experiment with it but there are solutions.
This should cover all you need to know so good luck and let me know if you need any further help as I'm aware this could be slightly overwhelming if you're new to Chrome extensions.
I'm not good at JS and I'm having some -I hope- stupid problem I'm not seeing on my code... if you guys could help me out, I'd really appreciate it.
My extension does some stuff with the current tab's URL. It worked ok using the onUpdate event on my background page, setting the tab's URL on a variable and then I used it on a pop-up.
The thing is that if the user starts, selecting different tabs, without updating the URLs my event won't be triggered again... so I'm now also listening to the onSelectionChanged event.
The thing is that there's no "tab" object within the onSelectionChanged event's parameters, so I cannot ask for the tab.url property.
I tried to use the chrome.tabs.getCurrent() method, but obviously I'm doing something wrong... and I reached the limit of my -very little- knowledge.
Here's the code, if you guys could take a look and point me in the right direction, I'll really appreciate it.
<script>
var tabURL = '';
var defaultURLRecognition = [ "test" ];
// Called when the url of a tab changes.
function checkForValidUrl(tabId, changeInfo, tab) {
//THIS IS WHAT'S NOT WORKING, I SUPPOSE
if (tab==undefined) {
chrome.tabs.getCurrent(function(tabAux) {
test = tabAux;
});
}
//
// If there's no URLRecognition value, I set the default one
if (localStorage["URLRecognition"]==undefined) {
localStorage["URLRecognition"] = defaultURLRecognition;
};
// Look for URLRecognition value within the tab's URL
if (tab.url.indexOf(localStorage["URLRecognition"]) > -1) {
// ... show the page action.
chrome.pageAction.show(tabId);
tabURL = tab.url;
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);
// Listen for tab selection changes
chrome.tabs.onSelectionChanged.addListener(checkForValidUrl);
</script>
I would do something like this:
function checkForValidUrl(tab) {
//...
}
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status == "loading") {
checkForValidUrl(tab);
}
});
chrome.tabs.onSelectionChanged.addListener(function(tabId, selectInfo){
chrome.tabs.getSelected(null, function(tab){
checkForValidUrl(tab);
});
});