AJAX crawling on single page - javascript

I was really confused with this question despite on google guide.
So, I have a web-page(html and js) which is upload some information to the
<div id=""></div>
using jquery's
.load(target)
Uploading realized with js function and "onclick" event in the html document.
So, when I click on the page region js start to upload information to the block.
According to google guide I should to use hash-bang if I want that page will be crawl.
Questions:
1.How can I implement this considering I have only one page?
2.How can I give access to the "#!" pages which upload by script?
3.How can I create html snapshots?
Thank you.

regarding Your question:
lets assume you have a page named MyPage.html with 3 elements to which you attach java script, with id's: A, B, C. each one of them causes different content to load in your div.
1) the simplest way is to create links like:
<a id='A' href='#GoToA' onclick='javascript:executeYourCodeA();'>Load A</a>
<a id='B' href='#GoToB' onclick='javascript:executeYourCodeB();'>Load B</a>
<a id='C' href='#GotoC' onclick='javascript:executeYourCodeC();'>Load C</a>
what that would do is when user clicks the link, the '#GoToA'or other will be added autommatically to browsers page addres. So the page address will look like
www.yourdomain.com/MyPage.html#GotoA
this change in addres will be remebered by the browser in its history.
2) if you wan to read the url use
var mylocation = window.location
- source: http://www.w3schools.com/js/js_window_location.asp
3) if the user accesses only MyPage.html everything is ok, the page renders with its original state, but what if user wants to see content visible after clicking link A ?
You can tell the difference, on page load, reading page url ( see 2)) and automatically loading the content. it can be achieved by :
$(function (){
var myurl = window.location;
var target = myurl.split('#')[1];
switch(target){
case 'GoToA' : executeYourCodeA(); break;
case 'GotoB' : executeYourCodeB(); break;
.
.
default: /*show the original, initial page*/
break;
});
Effectively what's going on now is that loading an address MyPage.html and clicking link A is the same by means of what is displayed to accessing a page MyPage.html#GoToA
So this way you can have separate links to the same site with different dynamically loaded content.
The thing Cristian Varga told you about can be used to achieving back and forward capabilities: basically what you do is you create a normal link to a page like MySecondPage.html ( this page does not really exist ). You then on click event load the contents to your div, force stop execution of standard link behavior (by preventDefault() - this causes your event not to be processed any more - so the browser 'ignores' navigation to MySecondPage.html. You then manually tell the browser to store the history stete and tell it that you are now om MySecondPage.html
history.pushState(null, null, link.href);
so you load the content, block navigation and manually convince the browser that the page has changed and to store the state in browsers history.
but now achieving the snapshot capability - would be more tricky in my mind, as the MySecondPage.html is a perfectly valid but non existent url, loading MyPage.html instead when user types in www.mydomain.com/MySecondPage.html and displaying MySecondPage content would require server side actions.
- source http://diveintohtml5.info/history.html

Related

How to keep elements non-refreshed

The main goal is to keep non-refreshed the logotext <div class="small-7 medium-4 columns logo"> and the menu <nav class="pagedMenu" role="navigation">,without clipping on page refresh or while the content is loading from a page to another. Also, the menu state should be preserved from a page to another.
I've found here a possible solution that could solve the problem (you could use ajax to fetch the updated content and use jQuery to put the new content on the page and avoid the refresh entirely. Doing it that way, the existing data in the page would remain untouched. said #jfriend00)
So, I have tried to use an Ajax plugin (called AWS). In the AWS option page, I (suppose) that I've done the right thing pointing wrapper as Ajax container ID and also pagedMenu as Menu container class, Transition Effect Enabled, No ajax container IDs blank, no loader selected, having already a pulse loader implemented in the theme.
At this point, all I got it's a menu / side-menu (shiftnav) / pulse dot loader / content loading malfunction, generated perhaps by the wrong defined Ajax container id and/or menu container class(?) OR by a conflict with an existing JS / jQuery code, not so sure.
Also in Chrome console there is an error:
Uncaught SyntaxError: Unexpected token ;
(anonymous function) # ajaxify.js?ver=4.3.1:175
n.extend.each # jquery-2.1.4.min.js?ver=2.1.4:2
n.fn.n.each # jquery-2.1.4.min.js?ver=2.1.4:2
$.bind.$.ajax.success # ajaxify.js?ver=4.3.1:169
n.Callbacks.j # jquery-2.1.4.min.js?ver=2.1.4:2
n.Callbacks.k.fireWith # jquery-2.1.4.min.js?ver=2.1.4:2
x # jquery-2.1.4.min.js?ver=2.1.4:4
n.ajaxTransport.k.cors.a.crossDomain.send.b # jquery-2.1.4.min.js?ver=2.1.4:4
Everything is getting back to normal on page refresh but doesn't help at all, being useless.
I also have to mention that for the menu I've tried to keep the state using jQuery-Storage-API and storage=jQuery.sessionStorage; as you can see in mynewmenu.js file but that will not solve the non-refreshing elements problem.
The menu jsfiddle only, if this helps to have the whole picture, here thanks to #Diego Betto.
You can use this live link as example; there is a similar situation with the above described - Ajax implementation right(?) - and regarding the appearance, menu is kept non-refreshed from one page to another; if you browse Books, Works etc, menu sections you'll see; if there is a model that could be implemented here, I'll be glad to find it.
LE: meanwhile, I've tried another ajaxify solution made by #arvgta - special thanks - without success yet but as far as I've found from the Author, the defined elements should be div's with id's not classes. So, I'll try to find a way to modify somehow the code in order to have id instead on classes.
Also, I'll try to transform and implement in ajaxify.min.js file, the page-container element; jQuery('#page-container').ajaxify(); I'll come back with news.
LE2: I've tried to implement the solution using id's instead of classes but still, the pages are not loading correctly.
At this point we have ajax.min.js file updated with these lines:
(function($){
jQuery(document).ready(function(){
jQuery('#page-container').ajaxify({requestDelay:400,forms:false});
});
})(jQuery);
Also, I've modified the theme file to have id=page-container instead if class=page-container.
In these conditions, on menu click, the links are changed (like it should), menu/ logotext elements seems to working almost fine (sometimes get skippy changing position), but the content is not loading correctly in all cases; Same here, everything is getting back to normal on manual page refresh (f5), but doesn't help.
LE3: It looks like the conflict is (at least) between Revolution Slider plugin and Ajaxify.
errormessage="Revolution Slider Error: You have some jquery.js library include that comes after the revolution files js include." ;="" +=" This includes make eliminates the revolution slider libraries, and make it not work." "<="" span="">"
Site live link here. Any thoughts / alternative in this area? (not interested in using other different platforms, different WordPress themes, etc. just a workaround in this existing situation)
LE4: As far as I can see, there are many users that voted up the Jake Bown answer that could be indeed a solution; but I can't find the reason that didn't work correctly implemented into my theme (without errors) live link here The elements logotext / menu are still fading on refresh, are not kept non-refreshed. Any thoughts #Jake Bown / anyone?
LE final.
Buzinas delivered the closest answer for my needs, taking in consideration my site environment (plugins installed, etc).
From what you said I think I might have found the solution you're looking for - you want to load content dynamically whilst keeping the logo and navigation untouched? If so, this might be what you're looking for.
In the example, the pages are loaded in from a div within the page but could be used to load another URL or file:
$('.viewport ul li a').on('click', function(e) {
e.preventDefault();
var link = this.hash.substring(1, this.hash.length);
if($('.'+link).length) {
$('.viewport span.body').html($('.'+link).html());
}
});
TL;DR
I've created a plunker for you, take a look, and play with it as long as you can. You'll learn a lot from it!
I think you're trying too many things here, but didn't try the simplest:
The main goal is to keep non-refreshed the logotext and the menu ,without clipping on page refresh or while the content is loading from a page to another. Also the menu state should be preserved from a page to another.
If you want to do that, there are a few steps:
Create a 'master' page, that we're going to call index.html from now on.
So, our index must have the static part of our page, e.g menu, logo, footer etc.
Then, our 'subpages' must be cut down (no html, head, body, script, style tags, only the content that should be showed into our master page).
That done, now we must change our links to use AJAX instead of doing full refresh:
/* we add a 'click' event handler to our menu */
document.getElementById('menu-menu-2').addEventListener('click', function(e) {
var el = e.target;
/* then, we see if the element that was clicked is a anchor */
if (el.tagName === 'A') {
/* we prevent the default functionality of the anchor (i.e redirect to the page) */
e.preventDefault();
/* we show our spinner, so the user can see that something is loading */
spinner.classList.remove('hidden');
/* and we call our AJAX function, passing a function as the callback */
ajax(el.href, function(xhr) {
/* we get our main div, and we replace its HTML to the response that came
from the AJAX request */
document.getElementById('main').innerHTML = xhr.responseText;
/* since the request was finished, we hide our spinner again */
spinner.classList.add('hidden');
});
}
});
Ok, now our pages are already working via AJAX, and not reloading our static content.
But now, we see that we have some issues. For example, if someone tries to open one of our pages directly via URL, he'll see unstyled page, without the menu/logo etc. So, what should we do?
We have a few more steps now:
Simulate that our links are effectively transfering between pages using the History API:
/* inside our ajax callback, we save the fake-redirect we made into the pushState */
ajax(el.href, function(xhr) {
document.getElementById('main').innerHTML = xhr.responseText;
/* save the new html, so when the user uses the back button, we can load it again */
history.pushState({
html: main.innerHTML,
title: el.textContent + '| neuegrid'
}, '', el.href);
/* (...) */
});
/* and outside it, we add a 'popstate' event handler */
window.addEventListener('popstate', function(e) {
/* so, if we've saved the state before, we can restore it now */
if (e.state) {
document.getElementById('main').innerHTML = e.state.html;
document.title = e.state.title;
}
});
And we need that when the user enters directly to another page, e.g about-us, we redirect him to the index.html, and then load the about-us page from there.
So we create a redirect.js file, and we reference it in all of our
subpages:
/* save the page that the user tried to load into the sessionStorage */
sessionStorage.setItem('page', location.pathname);
/* and them, we redirect him to our main page */
location.replace('/');
And then, in our index.html page, we see if there is any page in the sessionStorage, and we load it, if there is, otherwise we load our home page.
var page = sessionStorage.getItem('page') || 'home';
/* we look into the menu items, and find which has an href attribute
ending with the page's URL we wanna load */
document.querySelector('#menu-menu-2 > li > a[href$="' + page + '"').click();
And that's it, we're done now. Take a look at the plunker I've been making to you.
And play with it as long as you can, so you'll learn a lot from it.
I hope I could help you! :)
Note: Just for reference, this is our ajax function:
function ajax(url, callback, method, params) {
if (!method) method = 'GET';
var xhr = new XMLHttpRequest();
xhr.open(method, url);
if (callback) xhr.addEventListener('load', function() {
callback.call(this, xhr);
});
if (params) {
params = Object.keys(params).map(function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
xhr.send(params);
} else {
xhr.send();
}
}
GOING AJAXED WITH WORDPRESS
demo: http://so.devilmaycode.it/how-to-keep-elements-non-refreshed/
follow these simple steps (let's take as example theme "twentyfifteen" on the WP templates folder):
edit single.php, page.php, index.php and all other pages having get_header() and get_footer() functions and replace it respectively with below code:
NOTE: this is important because if someone (ex: search-engine) reach your pages directly from the link, it is still fully available and 100% working. (useful for SEO)
<?php
//get_header()
if(!isset($_REQUEST['ajax'])){
get_header();
}
?>
<!-- other code --->
<?php
//get_footer()
if(!isset($_REQUEST['ajax'])){
get_footer();
}
?>
open the header.php add the below code inside the <head> section at the very end
<script>
!(function($) {
$(function() {
$('.menu-item a, .widget-area a, .page_item a').on('click', function(e) {
e.preventDefault();
var href = this.href;
var query = href ? (href + (!/\?/g.test(href) ? '?' : '&') + 'ajax=1') : window.location;
/* IMPLEMENT SOME LOGIG HERE BEFORE PAGE LOAD */
/* ex: kill instance of running plugins */
$('#content').hide().empty().load(query, function() {
/* IMPLEMENT SOME LOGIG HERE AFTER PAGE IS LOADED */
/* ex: refresh or run a new plugin instance for this page */
jQuery(this).show();
});
});
});
})(jQuery);
</script>
in the header.php file put the code below at the end of the file, 90% of times you need it under the navigation. In this case we already have this on the "twentyfifteen" theme.
NB: most probably you have the opening tag <div id="content" class="site-content"> inside the header.php file and the closing tag </div> on the footer.php file, this doesn't matter, you can leave it as is.
<div id="content"></div>
NOTE: consider this a proof of concept; it may work as is, but you still need to tailor it to suit your needs; you may need to:
Add a menu (in case it is not already set) by going under Appeareace > Menus > [check Primary Menu] > Save Menu in order to activate the menu. it's tested and working.
You may want to add some other class to the jQuery function like .widget-area a in order to ajax also widget links.
if you are using 3d party plugins you may need to ensure that all dependencies of each plugin are loaded also on the main page from where you want everything is displayed without refreshing content.
you may need to check and kill those 3d party plugin before a new page load and run or refresh plugin needed in the loaded page.

Javascript function onclick, back button to "refresh" page

I have looked around, but I'm not seeing anything that specifically addresses this. My goal is to have a link, which can be clicked to either add content or "undo" the act of adding that content. I am trying to us the following:
function ShowDiv() {
if (null == window.set) {
document.getElementById("box2").innerHTML = "Some Content";
window.set = "set";
} else
location.reload();
}
Link
<div id="box2"></div>
This allows me to click the link to show some content inside some div. And then to click the link again to remove that content.
However, I am wondering if there is a way to achieve this result, that also allows the user to click the browser's back button to return the page to the state it was in before triggering the function (e.g., to reload the page).
You are looking for the HTML5 history API. This allows you to push state onto the history as if the browser loaded a different location without actually sending a request and replacing all content and javascript state. This allows the back and forward buttons to work, as long as your JavaScript code shows the correct content according to the current URL.
Resources:
W3C
MDN
Dive Into HTML5

How to change URL path when paging using ajax + jQuery

I am using ajax post requests for doing paging on a feed in my site. When getting the post request data I am reforming the page by clearing previous data and rendering the new data that came from the request. I want to be able to change the URL as well so saving the new page link will get the user to the current page.
Example:
User on page example.com/feed - seeing content of page #1
User clicking to get to page #2 -> ajax post is send and data on the page is changed using js (no refresh)
URL is still example.com/feed but the content is of example.com/feed?page=2
How can I set the URL to point to the new page without triggering a refresh (no redirect) ?
I am using Nodejs + express.
I understand you are aiming at a single page application.
While keeping the url is nice, note you might want distinct urls for directly accessing different parts of your application. Still, you can load content with AJAX and keep a smooth application. The way to go is using the hash part of the location.
The Sammy.js framework gives you a nice base to build upon, you can try it out.
You can use history pushstate but some browsers does not support.
history.pushState({id: 'SOME ID'}, '', 'myurl.html');
And don't forget about window.onpopstate, it pops if user clicks back button.
Redirect the user to an anchor point.
Page 2
And in your document.ready:
if (window.location.hash.length > 1){
var pageNumber = window.location.hash.substring(1);
loadPage(parseInt(pageNumber));
} else{
loadPage(0);
}
I don't believe it is possible to change the query part of the URL without triggering a refresh (probably due to security issues). However you may change the anchor and use an event listener to detect when the anchor is being changed.
//Listener
$(window).on('hashchange', function() {
if(loaction.hash.length > 1) {
//The anchor has been changed.
loadPageWithAjax("example.com/feed.php?page=" + location.hash.substring(1));
} else {
//Load standard page
...
}
});
Change the anchor to load new feed
Page 2
Remember to not use an anchor that is used as an id, since this makes the browser scroll to that element.

is it possible to change change the url in address bar or browser on certain event

you all have used pinterest, you can see that when you click on any pin, a div is added and lightbox is shown on the same page but the url is changed to that of actual pin page. i have the same lightbox to show data, is it possible to change the url like that?..
one thing i want to tell is that, i have link which has onclick event which calls view() method, in which i am calling another page with ajax request, which shows the content of that page on my page, i want to change url when this link is clicked and back to previous url when closed..here is my code
function view(){
$.get('mypage.jsp', function(html) {
$(html).hide().appendTo('body').fadeIn(500);
}, 'html');
};
This feature is known as HTML5 Push State. Here's a related StackOverflow question which may provide more insight. Good tutorial for using HTML5 History API (Pushstate?)
I haven't checked Pintrest's solution. But is hash what you're looking for?
window.location.hash="Whatever-you-want-to-add-to-the-URL"
This will change http://stackoverflow.com/posts/11968693/ to http://stackoverflow.com/posts/11968693/#Whatever-you-want-to-add-to-the-URL
Yes, with HTML5's new history API. Where the lightbox is triggered, add something like this:
var hist = window.history;
hist.pushState({ image: [IMAGE URL] }, 'lightbox', [URL]);
This will change the current URL without reloading the page, and will create an entry in the browser history, so users can use their browser back button to return to the previous state (in this case, before they opened the lightbox).
You can change the url (not only the hash) by using the pushState or replaceState functions on the history object. More details: http://diveintohtml5.info/history.html

passing different variables to same page

I am trying to build a web app mainly using html and javascript. I use a number of different variables in the app that are passed through the url.
here are the problems, I have some links that link to the page the app is currently on, just with changed variables, but while clicking on the links does change the url value, the page does not change/reload for the new values when using and an href, is there a clean way to force the page to reload if you link to the current page, or change the url?
currently I am using jQuery to set the window.location with the new variables then reloading the page.
also, I have a similar problem for using the back button on the browser. It will change the url but not refresh the page, so if you have a variable set to 1 you change it to be 2, that works and the page will reload with the variable set o 2, but if you go back using the browser history the url will say that your variable should be 1, but the rest of the page will still act like the variable is 2, until you refresh the page.
is there someway to set a page so that the it will automatically refresh when you go to the page from the same page, either through links or going forward or backward with the browser history?
as per request here is part of the parts of the code I am having problems with:
first is the code for the creating the html elements onload
var sel_tags=document.getElementsByName("selected_tags")[0];
var temp="";
if(Tags==null)
{
temp="\<p>All Notes\<\/p>";
}
else//Tags not empty, and there are tag filters
{
var click= new Array("",a+ AtTagShow);
var GoTo="PageViewNotes.html?"
for (var i=0; i < Tags.length; i++) {
//if we are showing #tags, or a tag is not an #tag
if(AtTagShow||Tags[i][0]!="#")
{
click[0]=t+Tags[i];
if (temp.length>0)
{temp+="\<span class=\"spacer\">\/<\/span>"};
temp+="\<a class=\"selected_tags_label\""+
"href=\""+GoTo+click.join("&")+"\">\<span>"
+Tags[i]+"\<\/span>\<\/a>"
}
};
};
sel_tags.innerHTML=temp;
here is the jquery code for setting the onclick:
$(".selected_tags_label").live("click",function(){
window.location=(this.href);
window.location.reload();
});
an example url for this issue would be:
page.html?Tags=#rediculous,#meeting&AtTagShow=true
by clicking on the rediculous element the url would change to:
page.html?Tags=#rediculous&AtTagShow=true
window.location.href="page.html?Tags=#rediculous&AtTagShow=true"
Take a look at the jQuery History plug-in for setting your site up to have back / forward history. It helps with setting up states on your page, that call data based on what query parameters are in the URL string.
In modern browsers (IE8+, Opera 10.6+, Fx 3.6+, Safari 5+) you have hashchange event.
Instead of reloading page, maybe you can achieve desired results with something like this:
<script>
document.onhashchange = function(){
// do something
}
</script>
MDN might be also helpful.
If you are using query parameters (things after the ? mark in the URL), then changing a query parameter and setting window.location to that new URL should cause a new page load from the server.
If you are using hash values (things after the # mark int he URL), then changing the hash value will not cause a new page load.
So, if you want a fresh page load from server each time you change a value, then you should be using query parameters. Back and forward should also work fine when using query parameters.
If you're purposely trying to do all of this with hash values to avoid an actual server page reload, then you will have to do more coding to intercept hash changes and process them. That is easier to do in modern browsers than older browsers using the window.onhashchange event. See this page on MDN for more info.
Browser reloads the page, whenever any of these parts of the URL are updated via window.location:
Domain
Port
Path
Query string
But it won't load the current document, if you change the fragment_id part (which is simply a reference to an HTML element inside the current document).
Thus from what you say, I guess you're updating the fragment id.
Also this might help to know that window.location.reload() method does the work of F5 key.

Categories

Resources