http://fh80.student.eda.kent.ac.uk/fyp/ Live example
If you see this page, click sports/venues/athletes etc it lets you browse around but it is all called in via AJAX.
This works fine but I'm having problems with inline links. For example:
Go to sports
Go to athletics
Go to "Hampden Park" link in red
This link doesn't reload within the AJAX window, it loads it in a new window...
This is the code that should set anything with the class ajaxLink
as possible to load the AJAX page into the div #grid
(same as the way it's done for all the other pages)
var newLink = $('.ajaxLink');
newLink.click(function (e) {
$.ajax({
url: newLink.attr('href'),
type: 'POST',
success: function (data) {
$('#grid').remove();
successHandler(data)
}
});
e.preventDefault();
});
Here is the code for the AJAX I am using (it's long):
//on document ready
$(function () {
var ajaxElement = $('#browserMenu a, .ajaxLink');
ajaxElement.on('click', function (e) {
var src = $(this).attr('href');
console.log(src);
//this element clicked
var thisEl = $(this);
var runAJAX = (src && src != '#') ? true : false;
if (runAJAX) {
var targetElement = $('#grid');
var parentElement = $('#ajaxParent');
if (src === 'index.html') {
$('#content').load('index.html #inner-content', function () {
$('.selected-menu').each(function () {
$(this).removeClass('selected-menu');
});
thisEl.addClass('selected-menu');
$('#jsCode code pre').load('js/nocomments.js');
});
} else {
$.ajax({
url: src,
dataType: 'html',
statusCode: {
404: function () {
console.log(src + ' - not found');
}
},
cache: false,
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
},
success: successHandler
});
}
e.preventDefault();
}
function successHandler(data) {
targetElement.remove();
//remove any selected classed
$('.selected-menu').each(function () {
$(this).removeClass('selected-menu');
});
thisEl.addClass('selected-menu');
var newContent = $('<div id="grid" />');
newContent
.html(data) //grab the HTML from AJAX and place it in to <div id="content"> </div>
.css("opacity", "0"); //hide the div until were ready to animate it in.
parentElement.append(newContent);
newContent.animate({
opacity: 1
}, 500);
var newLink = $('.ajaxLink');
newLink.click(function (e) {
$.ajax({
url: newLink.attr('href'),
type: 'POST',
success: function (data) {
$('#grid').remove();
successHandler(data)
}
});
e.preventDefault();
});
}
});
$('#jsCode code pre').load('js/nocomments.js');
});
Let's step through what happens from when the user loads the page to when the user clicks on the "Hampden Park" link:
User loads the page:
The document ready
event handler is called. It adds a click
event handler to $('#browserMenu a, .ajaxLink')
, which matches the "Sports" link inside <div id="browserMenu">
. There are no elements with the "ajaxLink" class in the document at this point, so only the four menu links get this click
event handler.
User clicks on the "Sports" menu link:
The click
event handler from 1. is called. It loads content from the Sports page using Ajax, then passes that data to successHandler()
. successHandler()
removes the old <div id="grid">
and adds a new <div id="grid">
with the new content, which is a jQuery UI Tabs widget and content for the first tab (content for the other tabs are loaded using Ajax).
At this point, successHandler()
tries to add a click
event handler to $('.ajaxLink')
, but there are still no elements with the "ajaxLink" class in the document, so no click
handlers are added.
User clicks on the "Athletics" tab:
The jQuery UI Tabs widget loads the content for the Athletics page with Ajax and displays it.
User clicks on the "Hampden Park" link:
This link has the "ajaxLink" class, but as noted in 2., it has no click
event handler, so the browser opens this link normally.
For cases where content is loaded dynamically, it is easier to use event delegation rather than trying to bind new event handlers every time the content changes.
Basically, every* event "bubbles up" from the original element where the event occurred, to its parent element, its parent's parent, all the way up to the document
element. You can attach handlers to a parent element to respond to events that originate from its children.
From jQuery's documentation, you will notice that on()
takes an optional selector
parameter. For example, with this:
$('body').on('click', handler);
handler()
will be called whenever the user clicks on the page, no matter if the user clicked on a link, an image or a blank space. When a selector is present:
$('body').on('click', 'a', handler);
handler()
will only be called when the user clicks on a link (inside the body
element). Any click
events from elements that do not match the selector will be ignored (including any clicks that occur directly on the body
element).
*As with many other cases, jQuery works around any browser inconsistencies so that event delegation works for all events.
Assuming you want one event handler to handle clicks to both menu links and content links, you can attach a click
event handler to either <div class="slideWrapper">
or <body>
, as they are parents / ancestors of both <div id="browserMenu">
and <div id="grid">
:
$('body').on('click', '#browserMenu a, .ajaxLink', function (e) {
// load content using Ajax
// on success, replace old content with new
});
You need to use the on
function of jQuery to do this. Start here. click
will not work with dynamic content, but the newish event API will catch dynamic content generated from an AJAX response and inserted into the DOM. This is a google example from that page:
$( "#dataTable tbody" ).on( "click", "tr", function() {
alert( $( this ).text() );
});
What that does is catches all incoming tr
elements into dataTable
's tbody
and give them a click
event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With