History replaceState problem in AJAXified Wordpress Theme - javascript

I made an Ajax enabled Wordpress theme with the main feature that internal links are not reloading the whole page but only the new content. So when URL's hash is changed, the new content is put in the #primary section and the map in the background stays untouched:
var $mainContent = $("#primary")
$(window).bind('hashchange', function(){
url = window.location.hash.substring(1);
url = url + " #content";
$mainContent.animate({opacity: "0.1"}).html('<p>Please wait...</>').load(url, function() {
$mainContent.animate({opacity: "1"});
});
});
Everything works fine, also history back and forward navigation. You can check out the basic funcionality here.
Now I want nice URLs hiding the hashes, so for example a link like http://geraldkogler.com/places/#/places/place/stwst/ gets changed to http://geraldkogler.com/places/place/stwst/. I do this adding this code to line 47 of ajax.js:
var oPageInfo = {
title: "places",
url: window.location.origin+window.location.hash.substring(1)
}
window.history.replaceState(oPageInfo, oPageInfo.title, oPageInfo.url);
Now the URL gets rewritten - but history doesn't work any more.
So I think I should listen to popstate events, I try to do the following and so back works once, but not more:
window.onpopstate = function(event) {
if (event.state) {
var host = "http://"+location.hostname;
location.hash = event.state.url.substring(host.length);
}
};
This (wrong) behaviour with the mentioned code is shown on this page. Any idea what I'm doing wrong in ajax.js?

Related

How to create a URL on (and within) an overlay

In a web application I'm working on, when someone wants to change their search location (for a map), they click on a button which brings up an overlay... the overlay has 3 tabs: Search by Location, Variables, and Stations. What I am trying to do is have the url updated whenever the overlay is up and also change depending on which tab they are on. This way when they share the URL, the exact overlay will be shown for the other person as well.
I've tried the push/replaceState() from https://developer.mozilla.org/en-US/docs/Web/API/History_API , which updates the url; but when I close the overlay, the same url is still shown... also, when I try to go back to that same url, the overlay is not shown.
Any ideas will be appreciated. Thank you!
Code... be advised I've tried several different scenarios which is why there's commented lines
// function addURL(element) {
// $(element).attr('href', function() {
// window.location.href = window.location +"&"+ "searrch";
// // return window.location.href
// });
// }
var stateObj = { foo: "bar" };
function change_my_url()
{
// history.replaceState(stateObj, "page 2", "#search");
// Prevent default click action
event.preventDefault();
// Detect if pushState is available
if(history.pushState) {
history.pushState(null, null, $(this).attr('href'));
}
return false;
}
var link = document.getElementById('nav-search-btn');
link.addEventListener('click', change_my_url, true);

Using pushstate to load certain pages on my ajax website

I am installing a social network sharing plugin to my website and I notice that I can only share one link.... the main index link.. How would I go about using pushstate to change the url in my browser to load each specific page on my website when sharing. Becuase using my ajax code I only have one URL and thats https://trillumonopoly.com. Im not familiar with pushstate but ive read that it is what im looking for.
for example if I want to social share the page for music on my website so when people click the link it will take them to my website index page with that specific page loaded into the div. How will I do it.
heres my jquery / ajax code
$(document).ready(function () {
loadMainContent('main');
$('body').delegate('.navMenu', 'click', function (event) {
event.preventDefault();
loadMainContent($(this).attr('href'));
});
});
function loadMainContent(page) {
$('#main').load('pages/' + page + '.php');
}
If you have a url like yoursite/someroute then you'll get a not found error. So you'll need to tell apache to serve index.php for those routes using rewrite.
In document.ready you need to check for the url (document.location.pathname) and load the content according to what the path is.
The index page should always show a loading spinner that will be replaced with the actual content based on the path name in the url
Here is some simple sample code of how you could do this:
//if path is /contact then return object with the url to php content page
// and title of the page
const pathToPage = path => {
switch (path) {
case "/contact":
return {
url:"/contact.php"
,title:"Contact"
,path:path
};
}
}
//when user navigates back and forward
window.addEventListener(
"popstate"
,event =>
//only set content, do not mess with history
onlyLoadmain(
pathToPage(location.pathname)
)
);
//load main content with or without messing with history
const loadMainBuilder = (push)=>(page)=> {
//if page is undefined then path is not of known content
if(page!==undefined){
if(push){
//set the url
history.pushState(
{},
page.title
,page.path
);
}
document.title = page.title
//#todo: should show loading here
//$('#main').html(loading);
$('#main').load(
'pages/' + page.url + '.php'
);
}
}
const loadMainAndPush = loadMainBuilder(true);
const onlyLoadmain = loadMainBuilder(false);
//... other code
$(document).ready(function () {
//load the content of current page
// when user gets a url in their email like yoursite/contact the
// apache rewrite rule will serve index.php but main content is
// showing loading untill your code actually replaces it with something
onlyLoadmain(pathToPage(location.pathname));
$('body').delegate('.navMenu', 'click', function (event) {
event.preventDefault();
//the element clicked should have href with the path, not the php file path
//so /contacts not /pages/contacts.php
loadMainAndPush(pathToPage($(this).attr('href')));
});
});

Check URL when page is loading

I need to change website pages with hashtag when site is loading.
For example when in browser address bar type:
http://example.com/#about
about page open in browser.
I use this:
$(window).bind('hashchange', function(e){
var anchor = document.location.hash;
nextPage(anchor);
});
for change page when user press on menu button and it works well, but I need this check happen in first of load website too.
If you want to trigger an event immediately, use trigger():
$('selector').on('event', function(e) { ... }).trigger('event');
So you would do:
$(window).bind('hashchange', function(e){
var anchor = document.location.hash;
nextPage(anchor);
}).trigger('hashchange');

What is the correct way to load a linked page, execute an event, and then unload it in a Chrome extension?

I have a Chrome extension that allows you to download data from certain sites.
For the past few days, I have attempted to add a feature that will download data from the sites when they are linked from other sites without having to visit the page and click the addon created download button IF the link to the site ends with #ndslink.
I figured out a solution, but it is INCREDIBLY sloppy and I am looking for a better way to implement this.
Here's the behavior:
Site A links Site B with an href ending in #nddownload. The link is clicked.
The extension disables the default action (open a new window), and instead creates an iframe on Site A and loads the linked URL into the frame.
The extension now runs Site B's content script, which specifically looks for #nddownload in the url, and, when found, proceeds to download some data that would normally be downloaded through a manual "Download" button added onto the page via the extension.
Here is my code.
Site B's content script:
var decklist = [];
$('.col-name').each(function(i, el) {
// IRRELEVANT CODE TRIMMMED
}
});
var data = decklist.join("\r\n");
var saveData = (function () {
// IRRELEVANT CODE TRIMMMED
}());
$(document).ready(function(){
var html = $('.t-deck-title').html();
fileName = $('.t-deck-title').text() + '.txt';
//html = html.replace(/hearthstonedeckdl/, '</br><a class="download" href="#download">DOWNLOAD</a>');
$('.t-deck-title').html(html);
if (window.location.href.indexOf("#ndslink") > -1) {
saveData(data, fileName);
}
$(document).on('click', 'a[href="#download"]', function(){
saveData(data, fileName);
});
});
Script loaded on all URLs (incl Site A):
var $jg = jQuery.noConflict();
$jg(document).ready(function(){
$jg('a[href$="#ndslink').click(function(e) {
e.preventDefault();
});
$jg(document).on('click', 'a[href$="#ndslink"]', function(){
//saveData(data, fileName);
var frameurl = $jg(this).text();
$jg('body').prepend('<iframe id="nddownload" />');
$jg("#nddownload").attr("src", frameurl);
//e.preventDefault();
// Send link to background and download.
});
});
I feel as if I am committing a horrible sin by going this route, but being new to Chrome extensions and generally being inexperienced I could not find a proper way to handle this. I've probably also broken my extension 10 different ways while attempting to do this so a real solution would be much appreciated.
I'm also actually unsure how to go about properly destroying the iframe once the saveData function completes.

How to make a link not to "Open in new window"

When we click with right mouse button on a any site link, there's a dropdown menu. One of the options here is "Open in new window". For some reasons, I need to disable this possibility for all site links. Is it possible?
Thanks in advance.
UPDATE
The reason for doing this
The site menu has 2 types of menu items: ordinary links to pages and fake links, that cause popup window with certain information. I have a jquery function, that shows this popup and returns false for the link. And when a user "Open in new window" some of fake links, page reloads, but popup does not appear. And the user is looking at the empty page. That's not good I think :)
No, not in all browsers, probably not in any browser. You can't change it's GUI without the specific browser giving you access to it, as the browser GUI isn't a standard in any way.
And why would you like to do that anyway?
You can use javascript to change the url and add the action on click so when the user try to open it in new windows nothing happens
As far as I know you cant disable this option since its provided by the web browser itself and each one implements the feature differently. You can however check the referrer value in the HTTP headers and ensure that its a correct value. When a user opens a new window the referrer should be set to null allowing you to intervene.
I would also hope that you consider not implementing this because some browsers have inconsistent behavior or an appliance on the network might remove the header information which would leave people unable to use your site.
If you are using javascript, you might as well make clicking links execute a javascript method. That way opening it up in a new page does nothing.
Remove the HREF attribute from the tag, but apply CSS styling to make it look like a link in all browsers. Then use a Javascript onclick function to do what it is you want to do. Easy. Case in point: look at the "add comment" link / button on this very page. If you right-click on it, you notice that there is no "Open in new Window" option :)
that ain't good for website reference, but if you REALLY need to block access from new windows...
How about generating your page content with Ajax?
something like that:
HTML
JAVASCRIPT
function xmlhttp() {
var x;
try {
x = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {
try {
x = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
x = new XMLHttpRequest();
} catch (e) {
x = false;
}
}
}
return x;
}
function page(idMenu) {
var http = xmlhttp();
if (!http) {
alert('XmlHttpRequest non supporté');
} else {
var url = 'pageOutput.php?pageNo=' + idMenu;
http.open('GET', url, true);
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
document.getElementById('pageContent').innerHTML = http.responseText;
}
}
http.send();
}
}
now all you have left to do is create a PHP where you check whatever menu ID is called and echo page content according to $_GET['pageNo']. if you already got your pages on many PHP/HTML you may also just do include and echo them...
if(isset($_GET['pageNo'])){
//echo page code here according to $_GET['pageNo'] value
}else{
//echo main page
}
EDIT: You may also add URL param to refer the current page so the user can reload your page from a new window without having no params loaded...
disable right click should do it...
http://www.billybear4kids.com/clipart/riteclic.htm
UPDATE
It's possible to disable context menu on any element we want:
$('selector').contextmenu( function() {
return false;
});
To disable context menu on the page completely, we can use the following:
$('*').contextmenu( function() {
return false;
});
OLD ANSWER
OK, guys, if we can't change browsers specific features, then we have to think of some other way. As for me, the most suitable idea has been suggested by Quentin. So I wrote a little jquery script to replace all links, that I need to be fake, with span elements.
// transform links with .fake class only
$('.nav >li > a.fake').each(function () {
// save all necessary link information
var href = $(this).attr('href');
var text = $(this).html();
// add fake span
$(this).after('<span>'+text+'</span>');
// save new span into a variable and after this we can remove the link
var mySpan = $(this).siblings('span');
$(this).remove();
// emulate link default behaviour
mySpan.click(function () {
window.location.href = href;
});
});

Categories