I am loading pages using AJAX. In every web page I have 2 div common - header div and content div. Now when I navigate from one one page to another than I load the content div of the next page into the current page by using
$("#content").load(URL+" #content");
Now as I am using AJAX to load pages so I am changing the URL and manipulating history using History API.
So now when someone press the back button of the browser then there is a problem, both the header div of both the pages is being showed during loading but disappears after loading is finished . So can anyone help me how to hide the header div of the loading page.
Here is the code that I am using to handle back button of browser
function swap(href) {
var x = document.getElementById("myTopnav");
x.className = "topnav";
var req = new XMLHttpRequest();
req.open("GET",
"http://localhost/" +
href.split("/").pop(),
false);
req.send(null);
if (req.status == 200) {
document.getElementById("content").innerHTML = req.responseText;
$("#content").load(" #content");
return true;
}
return false;
}
window.addEventListener("popstate", function(e) {
swap(location.pathname);
e.preventDefault();
});
I think this should work. It wraps the response in a DIV in case #content is the outermost element, since .find() only searches contents.
function swap(href) {
$("#myTopNav").addClass("topnav");
var url = href.split('/').pop();
$.get('http://localhost/' + url, function(response) {
var fragment = $("<div>", {
html: response
});
$("#content").replaceWith(fragment.find("#content"));
}
});
}
window.addEventListener("popstate", function(e) {
swap(location.pathname);
e.preventDefault();
});
Related
This site (http://nelation.net/) loads pages by using AJAX and pushState. AJAX retrieves the contents of section#body and the path for the new CSS.
The following code sends the AJAX request, retrieves the new contents of section#body (page contents) and a new CSS path. Then it inserts those into the page, and after that it calls the "pageLoad" event - That's the event I believe is triggered too early.
function loadPage(url) {
var target = document.getElementById("body");
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.onreadystatechange = function() {
if (xhr.readyState < 4) {
target.innerHTML = "";
}
if (xhr.readyState == 4 && xhr.status == 200) {
// Function to decode the new page
var decodeEntities = (function() {
// this prevents any overhead from creating the object each time
var element = document.createElement('div');
function decodeHTMLEntities (str) {
if(str && typeof str === 'string') {
// strip script/html tags
str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
element.innerHTML = str;
str = element.textContent;
element.textContent = '';
}
return str;
}
return decodeHTMLEntities;
})();
var resultJSON = JSON.parse(xhr.responseText);
var page = decodeEntities(resultJSON.page);
// Remove existing CSS and insert new one
$(".page-css").remove();
if (resultJSON.css != "none") {
$("<link/>", {
"class": "page-css",
rel: "stylesheet",
type: "text/css",
href: resultJSON.css
}).appendTo("head");
}
// Insert page contents, then trigger the pageLoad event
$(target).html(page);
$("body").trigger("pageLoad");
}
};
xhr.send();
}
// Detect link clicks, and make AJAX calls out of them + pushState.
$("body").on("click", '[data-ajax="true"]', function(event) {
event.preventDefault();
// detect which page has been selected
var newPage = $(this).attr("href");
if (newPage != window.location) {
window.history.pushState({path: newPage}, "", newPage);
}
loadPage(newPage);
});
The "pageLoad" event handler is found in this script. It re-executes most of the script, most notably the centerPlayButton_Featured() function if you're in the home page. That function resizes the overlay you see when you hover the image on the home page; It works fine when you load the page normally, but when you get to the page via AJAX it will not. The function is still executed (Logs to console), but I suspect it executes before the content is loaded properly into the page.
// DOES NOT RE-EXECUTE ON AJAX
function centerPlayButton_Featured() {
console.log("centerPlayButton_Featured() just executed");
var coverWidth = $("section.home-latest-release img.cover").width();
var coverHeight = $("section.home-latest-release img.cover").height();
$("section.home-latest-release div.cover-overlay").css({
"height": coverWidth + "px",
"width": coverHeight + "px"
});
}
$("body").click(function(e) {
if ($(e.target).hasClass("dropdown-text")) {
if ($(e.target).siblings(".menu").hasClass("open")) {
$(e.target).siblings(".menu").removeClass("open");
$(e.target).removeClass("open");
} else {
$(".dropdown .menu, .dropdown .dropdown-text").removeClass("open");
$(e.target).siblings(".menu").addClass("open");
$(e.target).addClass("open");
}
} else {
$(".dropdown .menu, .dropdown .dropdown-text").removeClass("open");
}
});
// RE-EXECUTES ON AJAX
$("body").on("pageLoad", function() {
$(function() {
// HOME PAGE
if ($("#body").children().hasClass("home-latest-release")) {
centerPlayButton_Featured();
$(window).on('resize', function() {
centerPlayButton_Featured();
});
}
// MUSIC PAGE
if ($("#body").children().hasClass("music-tracks")) {
//...
}
// CONTACT PAGE
$(function() {
if ($("#body").children().hasClass("contact")) {
$("textarea").bind("input", function() {
var offset = this.offsetHeight - this.clientHeight;
$(this).css("height", "auto").css("height", this.scrollHeight + offset);
});
}
});
});
});
$("body").trigger("pageLoad");
I appreciate any help/feedback. Go to the link to see more of the code, and tell me if you need to see the back-end. I apologize if the code is messy and comment-lacking. Thank you very much for the help.
Another problem I'm having is when you go to the music page, you may see all the dropdown menus fading out. Not as important as the main question, but help would be appreciated :)
The pageLoad event is not triggered because it is bound to the window load event:
$(window).bind("load", function() {
$("body").trigger("pageLoad");
});
load happens only once during the lifetime of a window, and that time has long passed when an ajax request can even start. Trigger pageLoad directly.
$(function () {...}) is executed once when the DOM has finished loading. Effectively, you are wrapping the code to be executed twice with the same event load which only happens once. Execute your setup code directly inside the pageLoad event handler. I'd write it like this:
function pageSetup () {
// HOME/MUSIC/CONTACT PAGE setup code
}
$("body").on("pageLoad", pageSetup);
pageSetup();
This is my first question on stackoverflow.
I want to load a different page in a certain space of my homepage. I tried it with JavaScript many times but hitting a wall. I can do it with iframe. But I was thinking if there is any other way to do it. And I want to load the page when the user clicks the link.
The way I did it is like this:
document.getElementById('aboutUs').onclick = function() {
document.getElementById('newDiv').style.display = "none";
document.getElementById('iFrame').style.display = "block";
}
Thank You!!!
You need to make request to load the static content.
Hope this snippet will be useful
//A generic function to load the static page
function loadContent(target, staticPageLoc) {
var r = new XMLHttpRequest(); // making request to load the static page
r.open("GET", staticPageLoc, true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
target.innerHTML = ""; // removing any previous content
target.innerHTML = r.responseText; // response will be the static page
};
r.send();
}
document.getElementById('aboutUs').onclick = function() {
loadContent(document.getElementById('id of dom element where page will load'), 'page path')
}
Alternately you can explore jquery.load function & better to run it in a server or else you may come across CORS
I have a page that has a header and sidebar with a right content panel that is an Iframe.
In a page loaded into the right content panel, I am trying to have a clicked link update the Browser URL in the parent window to the URL of the new page that is loaded into the Iframe.
I do not want the actual parent window to reload the URL but simply to update the URL in the address bar.
Something like:
window.history.pushState('obj', 'newtitle', '/bookmarks/list/');
Is this possible from an Iframe?
I was able to accomplish updating the parent windows URL in the address bar using history.pushState by sending the new URL to the parent from the child Iframe window using postMessage and on the parent window listening for this event.
WHen the parent receives the child iframes postMessage event, it updates the URL with pushSTate using the URL passed in that message.
Child Iframe
<script>
// Detect if this page is loaded inside an Iframe window
function inIframe() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
// Detect if the CTRL key is pressed to be used when CTRL+Clicking a link
$(document).keydown(function(event){
if(event.which=="17")
cntrlIsPressed = true;
});
$(document).keyup(function(){
cntrlIsPressed = false;
});
var cntrlIsPressed = false;
// check if page is loaded inside an Iframe?
if(inIframe()){
// is the CTRL key pressed?
if(cntrlIsPressed){
// CTRL key is pressed, so link will open in a new tab/window so no need to append the URL of the link
}else{
// click even on links that are clicked without the CTRL key pressed
$('a').on('click', function() {
// is this link local on the same domain as this page is?
if( window.location.hostname === this.hostname ) {
// new URL with ?sidebar=no appended to the URL of local links that are clicked on inside of an iframe
var linkUrl = $(this).attr('href');
var noSidebarUrl = $(this).attr('href')+'?sidebar=no';
// send URL to parent window
parent.window.postMessage('message-for-parent=' +linkUrl , '*');
alert('load URL with no sidebar: '+noSidebarUrl+' and update URL in arent window to: '+linkUrl);
// load Iframe with clicked on URL content
//document.location.href = url;
//return false;
}
});
}
}
</script>
Parent window
<script>
// parent_on_message(e) will handle the reception of postMessages (a.k.a. cross-document messaging or XDM).
function parent_on_message(e) {
// You really should check origin for security reasons
// https://developer.mozilla.org/en-US/docs/DOM/window.postMessage#Security_concerns
//if (e.origin.search(/^http[s]?:\/\/.*\.localhost/) != -1
// && !($.browser.msie && $.browser.version <= 7)) {
var returned_pair = e.data.split('=');
if (returned_pair.length != 2){
return;
}
if (returned_pair[0] === 'message-for-parent') {
alert(returned_pair[1]);
window.history.pushState('obj', 'newtitle', returned_pair[1]);
}else{
console.log("Parent received invalid message");
}
//}
}
jQuery(document).ready(function($) {
// Setup XDM listener (except for IE < 8)
if (!($.browser.msie && $.browser.version <= 7)) {
// Connect the parent_on_message(e) handler function to the receive postMessage event
if (window.addEventListener){
window.addEventListener("message", parent_on_message, false);
}else{
window.attachEvent("onmessage", parent_on_message);
}
}
});
</script>
Another solution using Window.postMessage().
Iframe:
/test
/test2
<script>
Array.from(document.querySelectorAll('a')).forEach(el => {
el.addEventListener('click', event => {
event.preventDefault();
window.parent.postMessage(this.href, '*');
});
});
</script>
Main page:
Current URL: <div id="current-url"></div>
<iframe src="iframe-url"></iframe>
<script>
const $currentUrl = document.querySelector('#current-url');
$currentUrl.textContent = location.href;
window.addEventListener('message', event => {
history.pushState(null, null, event.data);
$currentUrl.textContent = event.data;
});
</script>
See demo on JS Fiddle.
I am reloading a part of my page every 5 seconds with Javascript. This works fine!
However, if I add a parameter I am getting the same page without reloading.
If I open it without reloading, I am seeing the jQuery UI progress bars correctly.
If I open the reloading page, they are not shown anymore - although the script get's the unreloading site and write it into the div, so you should see them.
I am afraid this happens because they stylesheets or the jquery part is loosing his old values or is overwritten.
This is the reloading page: http://lasertra.de/table.php
This is how it should be, unreloading page: http://lasertra.de/table.php?refresh=true
Also if I am not reloading the jQuery scripts it doesn't show up correctly, if they scripts are not added in the not reloading page, it doesn't show the progress bars too, so it seems like it is needed.
I am not reloading the whole page, only the signals div which is placed in the body
function update_table()
{
var old_id = document.getElementById('number').value;
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
if(req.readyState == 4)
{
if(req.status == 200)
{
var new_table = req.responseText;
var new_id = document.getElementById('number').value;
if(new_id != old_id)
{
var someSound = soundManager.createSound({
url: 'signal.mp3'
});
someSound.play();
}
document.getElementById("signals").innerHTML = new_table;
setTimeout(update_table, 1000);
}
}
}
var link = "table.php?refresh=true";
req.open("GET", link, false);
req.send();
}
I want to load a form directly into a using ajax call.
The container page has already all the needed css/scripts inclusion for x-editable forms.
I can load the html code directly inside the div, but the problem is that the x-editable fields are not rendered.
Here is my code:
The div that will contain the remote content
<div id="mycontent">
....
</div>
And the javascript function:
$("#create-button").click(function(){
document.location.href = '/fip-dt/insertProject';
$('#mycontent').html('');
ajaxRead('/insertProject');
});
function ajaxRead(file){
var htmlObj = null;
if(window.XMLHttpRequest){
htmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
htmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}
htmlObj.onreadystatechange = function(){
if(htmlObj.readyState == 4){
updateObj(htmlObj);
}
}
htmlObj.open ('GET', file, true);
htmlObj.send ('');
}
function updateObj(data){
document.getElementById("mycontent").innerHTML=data.responseText;
}
I cannot use jquery directly to updated the content of div, because it seems to entirely remove the tags.
Into the remote div, i have the following javascript code:
$.fn.editable.defaults.mode = 'inline';
$('table#projectform > tbody > tr > td > a').editable();
$('.myeditable').editable({
url: '/post'
});
$('#project-name').editable('option', 'validate', function(v){
if(!v) return 'Required Field';
});
$('#save-btn').click(function(){
$("p#prova").html("TEST");
});
It seems that this piece of code is not executed when the remote content is loaded into the div.
Any idea?
Try adding your code after the div has been renderd