Dynamic web page with no reloading - javascript

I've just recently discovered slack.com and I fell in love with the way they handle their interface. If you've never used it before it's quite easy:
There is a side navbar and an main container on the right. Everytime you click an item in the side navbar it's content is loaded in the container. The focused item changes, the container's content changes, but the page doesn't reload.
If the data changes in the meantime it is magically updated.
What would it take to achieve something like that?
URL changing, page not reloading
Content always up to date
I've been looking at meteorjs in the past few days but the url part is never mentionned.

Yes. Slack is awesome. We (My team) use it everyday. I use it so regularly, at some point I don't check email but I check slack.
So, up to your question.
URL changing, page not reloading
It can be easily done by javascript [ Tl;dr ]
Code:
window.history.pushState("object or string", "Title", "/new-url");
Content always up to date
Well this can be done in two way,
i. via Ajax and Javascript
ii. via socket
i. via Ajax and Javascript:
in javascript you can make setTimeout function to fire ajax request in some duration. via Ajax it will get newest message from backend and it will be shown.
ii. via socket:
in socket, in your case if you use node.js there is a very popular library named socket.io which will get and update message in real time.
Good luck!

You need Ajax. You can use it in conjunction with a script, probably PHP that checks the state of the databse over a timer interval (a "heartbeat") and if anything has changed you load in the new data. I'd recommend having a specific column for a datetimestamp to compare with to make the smallest possible load on your database from this as a lot of users being on the page at the same time will make a lot of requests.

For the "url changing feature but no reload", I think #Kavan Pancholi answered your question. Another way to achieve that is by using the yield templates feature of iron-router.
You are using meteor, it means that you can do it without too much trouble (forget about Ajax & Sockets).
I don't know Slack (but I'll definitely have a look at it) but from what I understand, all data is preloaded/lazy loaded and they only change the displayed elements. In other terms, you keep ready and loaded all your client subscriptions or you bring them up when your yield template is loaded.
I will have a look at Slack and edit this if I realize I did not understood correctly what you are aiming for.
Edit Ok I tried it. You need to use yield templates with iron-router and they also added some transitions effect you can achieve with _uihooks + a loading template

On top of that, if you use a framework like angular, you'll notice urls like this:
http://localhost:3000/#/chat/room
You've probably seen similar with wikipedia in having urls like this:
https://en.wikipedia.org/wiki/Cat#Cats_and_humans
That little # won't reload the page on the url, so you can use that to make a url routing action without changing the page. You can access it with window.location.hash. So on the wikipedia article, you'd get
> window.location.hash
#Cats_and_humans
Combine that with ajax and event listeners and you can do something similar.
// using jquery
// set a callback when the hash changes
$(window).on('hashchange', function (e) {
e.preventDefault();
var hash = window.location.hash;
// get your container where you want to add data and clear it out
var $container = $('#container');
$container.html('<ul></ul>');
if (hash === '#/movies') {
// request json from an endpoint, and with the data, append it to the dom
$.getJSON('/api/movies', function (data) {
data.each(function (el) {
$container.append('<li>' + el.name + '</li>');
});
});
}
});

Related

Page Load alternative in a Pure HTML AJAX Website

I am working on a pure HTML website, all pages are HTML with no relation to any server side code.
Basically every request to the server is made using AJAX, I send data from forms, I process this data in Handlers, then I return a JSON string that will be processed back on the client side.
Let's say the page is loaded with parameters in the URL, something like question.html?id=1. Earlier, I used to read this query string on Page Load method, then read data from the database and so on...
Now, since its pure HTML pages, I'm trying to think of an approach that will allow me to do the same, I have an idea but its 99% a bad idea.
The idea is to read URL parameters using JS (after the page has loaded), and then make an AJAX request, and then fetch the data and show them on the page. I know that instead of having 1 request to the server (Web Forms), we are now having 2 Requests, the first request to get the page, and the second request is the AJAX request. And of course this has lots of delays, since the page will be loaded at the beginning without the actual data that I need inside it.
Is my goal impossible or there's a mature approach out there?
Is my goal impossible or there's a mature approach out there?
Lately there are a good handful of JavaScript frameworks designed around this very concept ("single page app") of having a page load up without any data pre-loaded in it, and accessing all of the data over AJAX. Some examples of such frameworks are AngularJS, Backbone.js, Ember.js, and Knockout. So no, this is not at all impossible. I recommend learning about these frameworks and others to find one that seems right for the site you are making.
The idea is to read URL parameters using JS (after the page has loaded), and then make an AJAX request, and then fetch the data and show them on the page.
This sounds like a fine idea.
Here is an example of how you can use JavaScript to extract the query parameters from the current page's URL.
I know that instead of having 1 request to the server (Web Forms), we are now having 2 Requests, the first request to get the page, and the second request is the AJAX request. And of course this has lots of delays, since the page will be loaded at the beginning without the actual data that I need inside it.
Here is why you should not worry about this:
A user's browser will generally cache the HTML file and associated JavaScript files, so the second time they visit your site, the browser will send requests to check whether the files have been modified. If not, the server will send back a short message simply saying that they have not been modified and the files will not need to be transmitted again.
The AJAX response will only contain the data that the page needs and none of the markup. So retrieving a page generated on the server would involve more data transfer than an approach that combines a cacheable .html file and an AJAX request.
So the total load time should be less even if you make two requests instead of one. If you are concerned that the user will see a page with no content while the AJAX data is loading, you can (a) have the page be completely blank while the data is loading (as long as it's not too slow, this should not be a problem), or (b) Throw up a splash screen to tell the user that the page is loading. Again, users should generally not have a problem with a small amount of load time at the beginning if the page is speedy after that.
I think you are overthinking it. I'd bet that the combined two calls that you are worried about are going to run in roughly the same amount of time as the single webforms page_load would if you coded otherwise - only difference now being that the initial page load is going to be really fast (because you are only loading a lightweight, html/css/images page with no slowdown for running any server code.
Common solution would be to then have a 'spinner' or some sort (an animated GIF) that gives the user an visual indication that the page isn't done loading while your ajax calls wait to complete.
Watch a typical page load done from almost any major website in any language, you are going to see many, many requests that make up a single page being loaded, wether it be pulling css/images from a CDN, js from a CDN, loading google analytics, advertisements from ad networks etc. Trying to get 100% of your page to load in a single call is not really a goal you should be worried about.
I don't think the 2-requests is a "bad idea" at all. In fact there is no other solution if you want to use only static HTML + AJAX (that is the moderm approach to web development since this allow to reuse AJAX request for other non-HTML clients like Android or iOS native apps). Also performance is very relative. If your client can cache the first static HTML it will be much faster compared to server-generated approach even if two requests are needed. Just use a network profiler to convince yourself.
What you can do if you don't want the user to notice any lag in the GUI is to use a generic script that shows a popup hiding/blocking all the full window (maybe with a "please wait") until the second request with the AJAX is received and a "data-received" (or similar) event is triggered in the AJAX callback.
EDIT:
I think that probably what you need is to convert your website into a webapp using a manifest to list "cacheable" static content. Then query your server only for dynamic (AJAX) data:
http://diveintohtml5.info/offline.html
(IE 10+ also support Webapp manifests)
Moderm browsers will read the manifest to know whether they need to reload static content or not. Using a webapp manifest will also allow to integrate your web site within the OS. For example, on Android it will be listed in the recent-task list (otherwise only your browser, not your app is shown) and the user can add a shorcut to the desktop.
So, you have static HTMLs and user server side code only in handlers? Why you can't have one ASP .Net page (generated on server side) to load initial data and all other data will be processed using AJAX requests?
if its possible to use any backed logic to determine what to load on server side, that will be easy to get the data.
say for example if you to load json a int he page cc.php by calling the page cc.php?json=a, you can determine from the PHP code to put a json into the page it self and use as object in your HTML page
if you are using query string to read and determine, what to load you have to make two calls.
The primary thing you appear to want is what is known as a router.
Since you seem to want to keep things fairly bare metal, the traditional answer would be Backbone.js. If you want even faster and leaner then the optimised Backbone fork ExoSkeleton might be just the ticket but it doesn't have the following that Backbone proper has. Certainly better than cooking your own thing.
There are some fine frameworks around, like Ember and Angular which have large user bases. I've been using Ember recently for a fairly complex application as it has a very sophisticated router, but based on my experiences I'm more aligned with the architecture available today in React/Flux (not just React but the architectural pattern of Flux).
React/Flux with one of the add-on router components will take you very far (Facebook/Instrgram) and in my view offers a superior architecture for web applications than traditional MVC; it is currently the fastest framework for updating the DOM and also allows isomorphic applications (run on both client and server). This represents the so called "holy grail" of web apps as it sends the initial rendered page from the server and avoids any delays due to framework loading, subsequent interactions then use ajax.
Above all, checkout some of the frameworks and find what works best for you. You may find some value comparing framework implementations over at TodoMVC but in my view the Todo app is far too simple and contrived to really show how the different frameworks shine.
My own evolution has been jQuery -> Backbone -> Backbone + Marionette -> Ember -> React/Flux so don't expect to get a good handle on what matters most to you until you have used a few frameworks in anger.
The main issue is from a UX / UI point of view.
Once you get your data from the server (in Ajax) after the page has been loaded - you'll get a "flickering" behavior, once the data is injected into the page.
You can solve this by presenting the page only after the data has arrived, OR use a pre-loader of some kind - to let the user know that the page is still getting its data, but then you'll have a performance issue as you already mentioned.
The ideal solution in this case is to get the "basic" data that the page needs (on the first request to the server), and manipulate it via the client - thus ease-in the "flickering" behavior.
It's the consideration between performance and "flickering" / pre-loading indication.
The most popular library for this SPA (Single Page Application) page - is angularJS
If I understand your inquiry correctly. You might want to look more about:
1) window.location.hash
Instead of using the "?", you can make use of the "#" to manipulate your page based on query string.
Reference: How to change the querystring on the same page without postback
2) hashchange event
This event fires whenever there's a changed in the fragment/hash("#") of the url. Also, you might want to track the hash to compare between the previous hash value and the current hash value.
e.g.
$(window).on('hashchange', function () {
//your manipulation for query string goes here...
prevHash = location.hash;
});
var prevHash = location.hash; //For tracking the previous hash.
Reference: On - window.location.hash - Change?
3) For client-side entry-point or similar to server-side PageLoad, you may make use of this,
e.g.
/* Appends a method - to be called after the page(from server) has been loaded. */
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function () {
if (oldonload) {
oldonload();
}
func();
}
}
}
function YourPage_PageLoad()
{
//your code goes here...
}
//Client entry-point
addLoadEvent(YourPage_PageLoad);
Since you're doing pure ajax, the benefit of this technique is you would be able to easily handle the previous/next button click events from the browser and present the proper data/page to the user.
I would prefer AngularJS. This will be a good technology and you can do pagination with one HTML. So i think this will be good framework for you as your using static content.
In AngularJS MVC concept is there please read the AngularJS Tutorial. So this framework will be worth for your new project. Happy coding

How to capture user interaction with a website?

How can I capture user interaction on a website? How many links a user has clicked. From where user has come. I want to create my own logic. I don't want to use any statistics tool. How can I accomplish this?
Thanks in advance
Place where user come from you can get by referer (document.referrer).
And if you have some kind of session or mark user(by cookies), than you can check what links are clicked by capturing onclick event. But do not put onclick on every link, just use event capturing technique. In jQuery this will be:
$('a')
.livequery('click', function(event) {
alert('clicked');
return false;
});
If you want to capture what link was clicked when goes away - you should place onunload event which will send data about clicked link to your server.
There are 2 ways that I know of:
make a service, and call it using a GET method on each event you want to track.
this is something like this:
service.php?event=pageview&time=127862936&userId=70&registered=true
this way your service can work with the data.
second way that I know of, which I myself use, is calling to some dummy Image on my server, chaining GET query to it, and then analyze the request to the image at the server side. each request is anylized and logged, then I build reports.
again, you need to know what events you want to grab, they are pre-defined, and need to catch and send them as they happen. you client can put a 1-script js file, but this script need to add events listeners. lets say you want to know when the use has quit the page. add an event listener to the onbeforeunload event, like this:
window.onbeforeunload = function(){
sendStats({event:'onbeforeunload'});
}
then sendStats function breaks down the JSON and builds a query to be sent to server like this:
function sendStats(statsJSON){
var url = [];
for (var key in statsJSON) {
// make sure that the key is an actual property of an object, and doesn't come from the prototype
if( statsJSON.hasOwnProperty(key) ){
var sign = (!url[0]) ? '?' : '&';
url.push(sign);
url.push(key + '=');
url.push( encodeURI(statsJSON[key]) );
}
}
var time = new Date().getTime();
url.push('&time=');
url.push(time);
var stat = new Image();
stat.src = clientHost + 'stats.gif' + url.join('');
}
Start with web server log files, dig into it's format, try some simple stats. Then you may want to read through the code of statistic tools like awstats to enhance your vision on that.
I am a asp .net developer. But i think this technique will work all the time. If you want to find out from where user has come to your site, you can user some sort of tracking querystring variable www.mysite.com?IMFrom=something. So you when you post your link on some third party website for e.g. say Google. Post link as www.mysite.com?google=traficfromgoogle. You might have trafic comming from different otherwebsite. Have different querystring variable for each. You can also use some kind of unique id for all website which is sending trafic to you. Now create the tracking function which will track this querystring variable. Use this function where it will get called during each request.
And you can now put some customized logic for each request having such querystring.
I don't think you'll need to capture this, as it is most likely already captured in web server logs by the web server itself. You just need to find the software that can analyze the logs and give you some nice metrics. There's lots of packages out there for that.
I know its not creating your own logic but if you decide you don't want to parse your server logs you could try a new service that is trying to one up google analytics: http://mixpanel.com/. It's real time analysis and they have a free limited account so you can try it before you upgrade.
I haven't tried their api to get stuff out yet but I imagine that you could let them collect the data from your site and do some fun stuff with it after you get it back out.
Use Google analytics and hook up site elements using their API.
record and replay the web https://www.rrweb.io/
This can be useful for:
- recording user interaction/events in the browser
- sending recordings to your backend only when an error

Could a page display diferrent content if the URL hash changes?

How could a page display different content based on the URL hash?
I'm not talking about the browser scrolling down to display the anchored section, but something like JavaScript reacting to that hash and loading different content via AJAX.
Is this common or even probable?
Oh yes - it's becoming a common pattern to handle page-state-to-URL persistence when content is AJAX driven.
Javascript can access this value via window.location.hash. Once that's done, you can perform any actions based on the value of that hash
Show/hide nodes
Makes other AJAX calls
Change page titles or colors
Swap images
etc
Really, any DHTML effect.
This is occasionally done. Youtube uses hashes to link to specific timestamps within a video.
EDIT: I had assumed that you might have an issue where if the user goes up and manually edits the hash in the address bar, the page doesn't reload and even javascript will not know that it changed. I was wrong. I tried it on Youtube it works.
I just built a system to do this a few weeks ago
depeding on the browser you need to detect the hash, heres how to do that
// test all possible places hash could be on different browsers
if(window.location.hash){
hash = window.location.hash;
} else if (document.location.hash){
hash = document.location.hash;
} else if (location.hash){
hash = location.hash;
}
// some browsers start the hash with #, remove it for consistency
if(hash.substring(0,1) == '#'){
hash = hash.substring(1,hash.length);
}
Then handle the value of the hash variable to trigger page changes as you please.
for example:
http://www.example.com#pageA
if(hash = 'pageA'){
document.getElementById('mainContentDiv').innerHTML = '<p> content for the page displayed when the hash sais pageA</p>';
}
Sammy is a javascript library that does just this.
As JavaScript has access to the URL-string it could of course act differently on the contents of the url.
I've occassionally seen something like this but I don't think that this is a good way to react unless in very specific uses.
One of the uses I remember was TiddlyWiki using the after-portion of the hash to set preferences for the page rendering and such.
It is fairly common among AJAX-heavy applications (think Gmail) to be able to have all the AJAXy stuff while still making it possible for you to bookmark a particular page or link someone to a particular page. If they didn't do this, it would be considered bad for usability. It is fairly easy to get the URL hash by doing window.location.hash - so you can then have a switch-like statement on page load to execute a particular set of Javascript functions if a hash is present.
Some jQuery plugins that achieve this functionality: history/remote, history.
The answer for this question will be more or less the same as my answers for these questions:
How to show Ajax requests in URL?
How does Gmail handle back/forward in rich JavaScript?
In summary, two projects that you'll probably want to look at which explain the whole hashchange process and using it with ajax are:
jQuery History (using hashes to manage your pages state and bind to changes to update your page).
jQuery Ajaxy (ajax extension for jQuery History, to allow for complete ajax websites while being completely unobtrusive and gracefully degradable).

How to monitor the changes in the url (Fragment identifier - the anchor portion of a URL )

I'm making a website that tend to handle all the request in one page (Ajax).
so i thought that I could trap every user's click on a link and check IF it's on my website i do something on JavaScript like an ajax request for example, ELSE it would open the link like usual!
doing a watch on window.location did not work!
and moreover I don't know if there is anyway to get the url part that is after the # sign.
Note: both GMail, and Facebook does that I guess!, they use something like this:
http://mail.google.com/mail/#inbox
http://www.facebook.com/home.php#/inbox/?ref=mb
Kindly Consider: that I love to use jQuery in my projects, so any solution using it is preferred.
Any ideas?
Here is another good read: Restoring Conventional Browser Navigation to AJAX Applications
Excerpt from the article:
Many developers have adopted AJAX as a
way to develop rich web applications
that are almost as interactive and
responsive as desktop applications.
AJAX works by dividing the web UI into
different segments. A user can perform
an operation on one segment and then
start working on other segments
without waiting for the first
operation to finish.
But AJAX has a major disadvantage; it
breaks standard browser behavior, such
as Back, Forward, and bookmarking
support. Rather than forcing users to
adapt to AJAX's shortcomings,
developers should make their AJAX
applications comply with the
traditional web interaction
style,.......
The fragment part of the URL is used to enable navigation history (back and forward buttons) on AJAX-enabled websites. If you want to "trap" clicks on links, since you're using jQuery anyway, you could just do that:
$('a').click(function()
{
var item = $(this);
var url = item.attr('href');
// your logic here
});
If you use fragments (window.location.hash) in constellation with AJAX, note that IE6 submits the fragment part of the url in AJAX requests which can lead to very hard-to-debug bugs, so be aware of that.
There's a hashchange event dispatched on the window for most recent browsers.
Simple:
if(window.location.hash) {
// Fragment exists
} else {
// Fragment doesn't exist
}
Link:
How can you check for a #hash in a URL using JavaScript?
See #Pekka 's link to How can you check for a #hash in a URL using JavaScript? to look at the hash. Just put that function in the callback to window.setInterval()

Enabling back/fwd key events for an Ajax Application

I have an application which works heavily on AJAX. However I want to have navigation functionalities in it. To spoof the url, I am changing the location.hash, to generate URL. But if I use back/fwd, only the url changes, but page wont reload. How can I override the hstory.back to reload the page.
I don't know of any other way than continuous polling to implement this behaviour. An implementation might look like this:
var lastHash = '';
function pollHash() {
if(lastHash !== location.hash) {
lastHash = location.hash;
// hash has changed, so do stuff:
alert(lastHash);
}
}
setInterval(pollHash, 100);
You can't exactly capture the back event, but most of these problems have been solved - and a good thing too, it's a hard problem.
Take a look at really simple history (aka RSH) and either implement it or work through it to see how it works.
The answer for this question will be more or less the same as my answers for these questions:
How to show Ajax requests in URL?
How does Gmail handle back/forward in rich JavaScript?
In summary, two projects that you'll probably want to look at which explain the whole hashchange process and using it with ajax are:
jQuery History (using hashes to manage your pages state and bind to changes to update your page).
jQuery Ajaxy (ajax extension for jQuery History, to allow for complete ajax websites while being completely unobtrusive and gracefully degradable).
The balupton answers are really great.
But you also have another jQuery Plugin to handle your ajax requests, it is address.

Categories

Resources