Load a part of the page without AJAX - html

I'm developing a web site where I want the left menu to stay fix, while the content of the clicked option is loaded.
Actually, what I do is that each menu link using AJAX it return the requested content. Everything works fine but I would like to avoid it because then statistics are difficult to follow (among some other things like Google boots).
How can I do the same affect/similar (http://www.foundcrelamps.com/) without javascript?

What I would do is a bit different. I'd make the links on the menu valid links that point to the content. Eg Contacte to point to http://www.foundcrelamps.com/contacte so that if you paste that link in the browser, it will load the page directly.
Then keep the ajax, so that the user does not reload the whole page on every click.
You can use History.js to keep the browser history and modify the URL so that back/next buttons work, even with ajax.
Edit, if you use conventional a elements with standard href it might look like this:
$('a').click(function(){
$('YOUR CONTAINER').load($(this).attr('href'));
return false; // so that it does not load the whole page
});
Then on the server you should do something like this:
/* AJAX check */
$isAjax = false;
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest') {
$isAjax = true;
}
if (!$isAjax) {
outputHeader();
}
outputMainContent();
if (!$isAjax) {
outputFooter();
}
This way when you do ajax, you will load only the inner content. When not, it will load the whole page.
There is an alternative method - you might load the whole page with jQuery but only use inner part of the html to replace the original content.

Related

How can you click an href link but block the linked page from displaying

It was hard to encapsulate my question in the title.
I've rewritten a personal web page that made extensive use of javascript. I'm simplifying matters (or so I hope).
I use a home automation server that has a REST interface. I can send commands such as 'http://192.168.0.111/rest/nodes/7%2032%20CD%201/cmd/DON to turn on a light. I'm putting links on my simplified web page using an href tag. The problem is that it opens the rest interface page and displays the XML result. I'd like to avoid having that page show up. ie when you click on the link it 'goes' to the link but doesn't change the page.
This seems like it should/would not be possible but I've learned not to underestimate the community.
Any thoughts?
You can use the fetch function if your browser is modern enough:
document.querySelector(lightSelector).addEventListener('click', e => {
e.preventDefault(); // prevent the REST page from opening
fetch(lightURL).then // put promises here
})
The variables lightSelector and lightURL are expected to be defined somewhere.
The code listens for clicks on the link, and when one comes, we prevent the REST page from opening (your intention) then we send a request to your light URL with fetch. You can add some promises to deal with the response (e.g. print "light on" or "light off" for example) using then but that's another matter.
If you make the "link" a button, you can get rid of e.preventDefault(); which is the part preventing the REST page from opening.

How to make "Pretty" URL after dynamic content load using ajax

I am currently developing a website that will dynamically load the page content using ajax triggered by hash changes.
The code looks like this
$("*").delegate("a", "click", function () {
// Trigger Hash Change
window.location.hash = $(this).attr("href");
return false;
});
$(window).bind('hashchange', function () {
let newHash = window.location.hash.substring(1);
$("#main-content").load(newHash + " #ajax-content", function (responseTxt, statusTxt, xhr) {
}).hide().fadeIn();
});
Basically what I am working on now is making the URL look "Pretty", I have modified the .htaccess file to remove the .html extension
So a URL that looks like this
www.example.com/about.html
will become this
www.example.com/about
If I navigate the index (home) "www.example.com" page of the website and then navigate from there to the about page, the URL looks fine. "www.example.com#about" since the server does not display the "index" in the URL.
However, if I navigate straight to the about page like this www.example.com/about, then from the about page to another page, for example, the contact page. I get a URL that looks like this www.example.com/about#contact. When it should look like this www.example.com#contact.
My question is what is the best way to handle this? should I use jquery to redirect all to the index page and then add the hash to load the correct content? or is there some way I can not display the unnecessary part of the URL?
I hope my question was clear, I'm new to the server-side stuff involving the .htaccess file. FOr the ajax stuff I was following this tutorial from CSS tricks
https://css-tricks.com/video-screencasts/85-best-practices-dynamic-content/
You can use history.pushState
window.history.pushState("object or string", "Title", "/new-url");
The url will be www.example.com/new-url
in fact you can get history.state after use this method.
console.log(window.history.state)
output should be "object or string"
You can see the docs here.
Remember to use / to override the entire path.
To do what i think that you want, you can just override the url to / and set the hash.
This is probably not the best way to do this, but I have managed to redirect any page to the home page and then replace the / with the hash value so that the site wont end up wit "messy" URLs.
if(window.location.pathname != "/home.html")
{
window.location.replace("home.html" + window.location.pathname.replace("/", "#"));
}
what happens id the user navigates to "*www.example.com/about*" they will actually be sent to the homepage with the #about.html. So the never end up like this "*www.example.com/about#about*"

How to target anchors in a div in the same page

I'm struggling with some anchors / other html pages ( buttons on left) to be displayed in another div in the same page ( to be more exactly in the right ). Are there any solutions to this with div? Or maybe with frame/iframe, even jQuery any tips please?
Are there any solutions to this with div?
Fetch the content with JavaScript (e.g. XMLHttpRequest).
Strip out the bits you don't need (e.g. everything except the contents of the <body>
Use DOM manipulation to add it to the div
Or maybe with frame/iframe
That is exactly what iframes were designed for. Set the target attribute of the anchor to the name of the iframe
Loading content into a portion of a page comes with a lot of gotchas. At the very least it interferes with the ability of visitors to link to the content they are actually viewing (although you can use the History API and pushState to compensate for that). It is almost always a better idea to just link to a new page which includes (via a template) any content that is common to all the pages.
If the page links to a HTML page you can append an iframe using jQuery as follows:
$(document).ready(function(){
$('.button').click(function(){
// Prevent Default Action
event.preventDefault();
// get the href parameter
var url = $(this).attr('href');
// Append the iframe
$('#content').append('<iframe src="'+ url +'"></iframe>');
});
});
Here is a working Example
If you are able to return a JSON or XML response you can use $.ajax to get the response and then append it inside a div instead of an iframe.

Keeping the basic layout same across the web pages

I have a website in which I finished with the basic layout, design, fonts, styles, css etc.
For almost whole of the website, the layout i.e the sidebar, the footer, the background etc. will remain the same. There are custom embedded fonts used as well.
Since this basic layout will remain the same all across the website, I wanted to ask how can I prevent downloading of this content (like side-bar, fonts, or javascript etc.) again for the user, so that the other pages after the start do not take as much time as the start page.
I am sure there would be some mechanism since most of the websites have header/footer/sidebar in common across the pages. My website is in plain html/css, and there's no backend being used. Any ideas?
Your images, fonts, css and other contents will most likely be cached by the client's browser on the first hit, so it will be downloaded just once.
For the html page itself, since you use static html content, the only way I can think of is using AJAX request.
You probably want to use includes. So on each page you'd have a header include, a footer include, a sidebar include and even an include containing links to your css/js files.
Simplest way to do this would be to change your pages to be .php pages and use php includes to pull in the header file, footer file etc.
You can static-site generator like Jekyll.
You may design a basic layout first.
Avoid inline and embedded CSS maximum and add a class (can assign to multiple) or id (can assign to single) to common selectors.
Make a master stylesheet like master.css and attach this to every page.
Hope this helps.
You can do this in two way. You say you don't have a backend, however the server where your website is hosted can be the backend.
Without any backend interaction:
If you really prefer not to use the backend at all, you can make this a single page website, with some javascript to switch the content you have in there. The idea is you have your website structure, and your default data available the way you normally have it right. But you also have the html for your other pages in hidden divs. Then when you want to switch to say the about link you use javascript to get the content from the hidden div with that content and you place that content in the main div.
<!--First lets use jquery thought it can use some other framework-->
<script src="http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery"></script>
<script>
$('a[href=#myAboutPage]').on('click',function(){//Whenever link that points to #myAboutPage is clicked
var getHTMLFROM = document.getElementById('myAboutPageHiddenContent').innerHTML;
//And place it on main div
document.getElementById('mainDivContent').innerHTML = getHTMLFROM
});
</script>
If you wanted to use some ajax interactions:
The process would be the same with the exception that the getHTMLFROM content, would actually be an html file that you request from the server.
Both of this javascript oriented methods will work, but would NOT recommend if you want your information to be SEO friendly. With that said reuse an external piece of css, to minimize redownloading the styling of your interface every single time.
There are definitely many ways to do this. I am a fan of dynamic inclusion. Here is a link to a great tutorial which explains how to set it up for your own page very simply. Dynamic Inclusion Tutorial NOTE: Don't be afaid of PHP, or having to change your file extension to PHP. It won't change your coding experience at all. It will just enhance your abilities.
I also have used the Javascript feature to hide certain elements. Depending on the size of your website, it may be just as easy to reload your CSS and navigation elements. However, if you really don't want your menu and logo to blink momentarily while it is reloading, you can just hide/reveal elements very simply with a bit of JS.
Here is an example function from my website:
function toggleVisible(e){
var i = e.id;
if(e.className == 'collapsed')
{
e.className = 'expanded';
e.innerHTML = 'Hide'
var hiddenArray = document.getElementsByClassName('hidden' + i);
hiddenArray[0].setAttribute('class', 'expanded' + i);
}
else if (e.className == 'expanded')
{
e.className = 'collapsed';
e.innerHTML = 'Show More';
var expandedArray = document.getElementsByClassName('expanded' + i);
expandedArray[0].setAttribute('class', 'hidden' + i);
}
}
The above code will run when the following link is clicked:
ANYWEBSITE.com || <a onClick="toggleVisible(this)" id="4" class="collapsed">Show More</a> || View PDF
Also, another user mentioned caching. Caching appears to be unreliable. Check out the following links for more info:
AJAX cache
HTML5 Application cache
2009 article about browser caching from stackoverflow.com question

CodeIgniter + jQuery(ajax) + HTML5 pushstate: How can I make a clean navigation with real URLs?

I'm currently trying to build a new website, nothing special, nice and small, but I'm stuck at the very beginning.
My problems are clean URLs and page navigation. I want to do it "the right way".
What I would like to have:
I use CodeIgniter to get clean URLs like
"www.example.com/hello/world"
jQuery helps me using ajax, so I can
.load() additional content
Now I want to use HTML5 features like pushstate to
get rid of the # in the URL
It should be possible to go back and forth without a page refresh but the page will still display the right content according to the current URL.
It should also be possible to reload a page without getting a 404 error. The site should exist thanks to CodeIgniter. (there is a controller and a view)
For example:
A very basic website. Two links, called "foo" and "bar" and a emtpy div box beneath them.
The basic URL is example.com
When you click on "foo" the URL changes to "example.com/foo" without reloading and the div box gets new content with jQuery .load(). The same goes for the other link, just of course different content and URL.
After clicking "foo" and then "bar" the back button will bring me back to "example.com/foo" with the according content. If I load this link directly or refresh the page, it will look the same. No 404 error or something.
Just think about this page and tell me how you would do this.
I would really love to have this kind of navigation and so I tried several things.
So far...
I know how to use CodeIgniter to get the URLs like this. I know how to use jQuery to load additional content and while I don't fully understand the html5 pushstate stuff, I at least got it to work somehow.
But I can't get it to work all together.
My code right now is a mess, that's the reason I don't really want to post it here. I looked at different tutorials and copy pasted some code together. Would be better to upload my CI folder I guess.
Some of the tutorials I looked at:
Dive into HTML5
HTML5 demos
Mozilla manipulating the browser history
Saner HTML5 history
Github: History.js
(max. number of links reached :/)
I think my main problem is, that everybody tries to make it compatible with all browsers and different versions, adds scripts/jQuery plugins and whatnot and I get confused by all the additional code. There is more code between my script-tags then actual html content.
Could somebody post the most basic method how to use HTML5 for my example page?
My failed attemp:
On my test page, when I go back, the URL changes, but the div box will still show the same content, not the old one. I also don't know how to change the URL in the script according to the href attribute from the link. Is there something like $(this).attr('href'), that changes according to which link I click? Right now I would have to use a script for every link, which of course is bad.
When I refresh the site, CodeIgniter kicks in and loads the view, but really only the view by itself, the one I loaded with ajax, not the whole page. But I guess that should be easy to fix with a layout and the right controller settings. Haven't paid much attention to this yet.
Thanks in advance for any help.
If you have suggestions, ideas, or simple just want to mention something, please let me know.
regards
DiLer
I've put up a successful minimal example of HTML5 history here: http://cairo140.github.com/html5-history-example/one.html
The easiest way to get into HTML5 pushstate in my opinion is to ignore the framework for a while and use the most simplistic state transition possible: a wholesale replacement of the <body> and <title> elements. Outside of those elements, the rest of the markup is probably just boilerplate, although if it varies (e.g., if you change the class on HTML in the backend), you can adapt that.
What a dynamic backend like CI does is essentially fake the existence of data at particular locations (identified by the URL) by generating it dynamically on the fly. We can abstract away from the effect of the framework by literally creating the resources and putting them in locations through which your web server (Apache, probably) will simply identify them and feed them on through. We'll have a very simple file system structure relative to the domain root:
/one.html
/two.html
/assets/application.js
Those are the only three files we're working with.
Here's the code for the two HTML files. If you're at the level when you're dealing with HTML5 features, you should be able to understand the markup, but if I didn't make something clear, just leave a comment, and I'll walk you through it:
one.html
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script>
<script src="assets/application.js"></script>
<title>One</title>
</head>
<body>
<div class="container">
<h1>One</h1>
Two
</div>
</body>
</html>
two.html
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script>
<script src="assets/application.js"></script>
<title>Two</title>
</head>
<body>
<div class="container">
<h1>Two</h1>
One
</div>
</body>
</html>
You'll notice that if you load one.html through your browser, you can click on the link to two.html, which will load and display a new page. And from two.html, you can do the same back to one.html. Cool.
Now, for the history part:
assets/application.js
$(function(){
var replacePage = function(url) {
$.ajax({
url: url,
type: 'get',
dataType: 'html',
success: function(data){
var dom = $(data);
var title = dom.filter('title').text();
var html = dom.filter('.container').html();
$('title').text(title);
$('.container').html(html);
}
});
}
$('a').live('click', function(e){
history.pushState(null, null, this.href);
replacePage(this.href);
e.preventDefault();
});
$(window).bind('popstate', function(){
replacePage(location.pathname);
});
});
How it works
I define replacePage within the jQuery ready callback to do some straightforward loading of the URL in the argument and to replace the contents of the title and .container elements with those retrieved remotely.
The live call means that any link clicked on the page will trigger the callback, and the callback pushes the state to the href in the link and calls replacePage. It also uses e.preventDefault to prevent the link from being processed the normal way.
Finally, there's a popstate event that fires when a user uses browser-based page navigation (back, forward). We bind a simple callback to that event. Of note is that I couldn't get the version on the Dive Into HTML page to work for some reason in FF for Mac. No clue why.
How to extend it
This extremely basic example can more or less be transplanted onto any site because it does a very uncreative transition: HTML replacement. I suggest you can use this as a foundation and transition into more creative transitions. One example of what you could do would be to emulate what Github does with the directory navigation in its repositories. It's an intermediate manoever that requires floats and overflow management. You could start with a simpler transition like appending the .container in the loaded page to the DOM and then animating the old container to {height: 0}.
Addressing your specific "For example"
You're on the right track for using HTML5 history, but you need to clarify your idea of exactly what /foo and /bar will contain. Basically, you're going to have three pages: /, /foo, and /bar. / will have an empty container div. /foo will be identical to / except in that container div has some foo content in it. /bar will be identical to /foo except in that the container div has some bar content in it. Now, the question comes to how you would extract the contents of the container through Javascript. Assuming that your /foo body tag looked something like this:
<body>
foo
bar
<div class="container">foo</div>
</body>
Then you would extract it from the response data through var html = $(data).filter('.container').html() and then put it back into the parent page through $('.container').html(html). You use filter instead of the much more reasonable find because from some wacky reason, jQuery's DOM parser produces a jQuery object containing every child of the head and every child of the body elements instead of just a jQuery object wrapping the html element. I don't know why.
The rest is just adapting this back into the "vanilla" version above. If you are stuck at any particular stage, let me know, and I can guide you better though it.
Code
https://github.com/cairo140/html5-history-example
Try this in your controller:
if (!$this->input->is_ajax_request())
$this->load->view('header');
$this->load->view('your_view', $data);
if (!$this->input->is_ajax_request())
$this->load->view('footer');