Problem:
You have a regular set of URL links in a HTML page e.g.:
Foo Bar
You want to create a JavaScript function such that when any HTML links are clicked, instead of the client's browser navigating to that new URL "/foo/bar" a JavaScript function is executed instead (e.g. this may for example make an Ajaxian call and load the HTML data without the need to reload the page).
However if the JavaScript is disabled OR a spider crawls the site, the UTL links are maintained gracefully.
Is this possible? Does it already exist? What's the usual approach?
EDIT 1:
These are some great answers!
Just a follow on question:
If the user clicks on the back button OR forward button, this would naturally break (as in it would go back to the last physical page it was on as opposed to one that was loaded).
Is there any way (cross browser) to maintain the back/forward buttons?
(e.g create an array of links clicked and over ride the browser buttons and use the array to navigate)?
<script type="text/javascript">
function your_function() {
alert('clicked!');
}
</script>
<a onclick="your_function();" href="/foo/bar">Foo Bar</a>
If Javascript is off, the link behaves normally.
In this case, unless your_function() does not return false, the link will be followed when clicked as well.
To prevent this, either make your_function() return false, or add return false; just after the function call in your onclick attribute:
<script type="text/javascript">
function your_function() {
alert('clicked!');
return false;
}
</script>
<a onclick="your_function();" href="/foo/bar">Foo Bar</a>
Or:
<script type="text/javascript">
function your_function() {
alert('clicked!');
}
</script>
<a onclick="your_function(); return false;" href="/foo/bar">Foo Bar</a>
Using element.addEventListener()
With default anchor behaviour following click:
<script type="text/javascript">
document.addEventListener("load", function() {
document.getElementById("your_link").addEventListener("click", function() {
alert('clicked');
}, true);
}, true);
</script>
<a id="your_link" href="/foo/bar">Foo Bar</a>
Without:
<script type="text/javascript">
document.addEventListener("load", function() {
document.getElementById("your_link").addEventListener("click", function(event) {
event.preventDefault();
alert('clicked');
}, true);
}, false);
</script>
<a id="your_link" href="/foo/bar">Foo Bar</a>
Given current HTML and W3C APIs, I would go for:
<script src="linkify.js"> </script>
in the markup, with linkify.js containing something like:
window.onload= function() {
document.addEventListener('click', function(ev) {
ev.preventDefault();
var el = ev.target;
if (el.tagName === 'A') {
// do stuff with el.href
}
}, false);
};
See e.g. http://jsfiddle.net/alnitak/nrC7G/, or http://jsfiddle.net/alnitak/6necb/ for a version which doesn't use window.onload.
Note that this code uses a single listener function registered on the document object, which will act on every <A> tag on the page that doesn't trap clicks for itself.
Use an onclick attribute:
click?
The return false prevents the default behaviour, in the absence of JavaScript, however, the link will be followed.
function do_whatever (e)
{
e.preventDefault ();
// do whatever you want with e.target
}
var links = document.getElementsByTagName ("a");
for (var i=0; i<links.length; ++i)
links[i].addEventListener ('click', do_whatever);
http://jsfiddle.net/bTuN7/
All done inside script and it won't 'hurt' if JavaScript doesn't work.
If you think about AJAX, then you have to know, that googlebot tries to parse it. http://www.youtube.com/watch?v=9qGGBYd51Ts
You can code like:
$('a').click(function() {
doSomethingWithURL($(this).attr('href'));
return false;
});
JavaScript is not executed in case it's disabled or if it's some web crawler, so from my point of view this is preferable.
There's quite a few methods out there such as this:
http://www.malbecmedia.com/blog/development/coding-a-ajax-site-that-degrades-gracefully-with-jquery/
Remember, though, that by virtue of a well setup server and caching you're not going to gain yourself much performance with an Ajax Load.
Related
I'm trying to change a href link programmatically (according to a result from an ajax async operation) and open it in a new window (I don't want to use window.open as it behaves like a popup and being blocked in IE).
The following code works only after clicking MANUALLY on the link for a second time, how can I make it work on the first click?
Simplified example:
trying to change href link dynamically
<script type="text/javascript">
document.getElementById('link').addEventListener("click", function (e) {
if (!e.target.hasAttribute("target")) //only preventDefault for the first time..
{
e.target.setAttribute("target", "_blank");
e.preventDefault();
updateLink();
}
});
function updateLink() {
// --HERE I PERFORM AN AJAX CALL WHICH TAKES A WHILE AND BY ITS RESULT I DECIDE WHICH URL TO USE - BUT HERE I JUST USE IT HARDCODED--
document.getElementById('link').setAttribute("href", "http://google.com");
document.getElementById('link').click();
}
I organized your code in this jsFiddle: http://jsfiddle.net/mswieboda/Hhj4D/
The JavaScript:
var $link = document.getElementById('link');
$link.addEventListener("click", function (e) {
if (!e.target.hasAttribute("target")) {
//only preventDefault for the first time..
e.target.setAttribute("target", "_blank");
e.preventDefault();
updateLink();
}
});
function updateLink() {
$link.setAttribute("href", "http://google.com");
$link.click();
}
This worked for me when I ran it. Hovering the link, you could see http://demo.com but clicking it takes you to http://google.com. Is this the desired functionality? You can definitely use the updateLink function any time (after an AJAX call) to change the href, also, you could probably set the _target in that function as well, makes more sense to me that way.
On my website (Password is "WS" without the quotes) I created a grid with a plugin (UberGrid).
To make each cell a popup I added the following code inside this Wordpress page:
<script type="text/javascript">
function popWin(url)
{
var thePopCode = window.open(url,'','height=800, width=1000, top=500, left=200, scrollable=yes, menubar=yes, resizable=yes');
if (window.focus)
{
thePopCode.focus();
}
}
</script>
Inside the plugin (inside the Debra Porter cell) I added the following link:
javascript: onclick=popWin('http://www.weybridgestrategies.com/team/debra-porter-president-ceo'); return (false);
It works fine in Google Chrome but no results in Firefox or Safari.
Have a look on what HTML is produced:
<a class="uber-grid-hover" href="onclick=popWin('http://www.weybridgestrategies.com/team/debra-porter-president-ceo'); return (false);" >
How it should look like:
<a class="uber-grid-hover" href="http://www.weybridgestrategies.com/team/debra-porter-president-ceo"
onclick="popWin('http://www.weybridgestrategies.com/team/debra-porter-president-ceo'); return false;">
So your popWin function is already ok, but you need to justify the anchor's attributes href and onclick. onclick is javaScript, so you don't need the javaScript prefix, and also you don't need inline onclick= because this creates a global variable. The return false will prevent the browser to follow the href, if javascript is available. By using this.href this is will not do what you expect at least in IE, because this is in IE the event, not the anchor.
EDIT: Actually your TestLink does what you intended, as of Firefox Aurora v24, without blocking-a-popup.
But I have to follow Brian's comment, that your new window may be considered a popup, so it would be the best if you do window.open(url, '_blank') or simply use <a target="_blank" href="..."> - and looking for a javaScript "popup" that doesn't load a new page, but looks more HTML5ish, for example using jQuery UI or by trying your own jS (and that would be another answer to a much bigger question... ;))
UPDATE: A good idea unleashing your jQuery already included, lets speak javaScript:
<script type="text/javascript">
function popWin(url)
{
var thePopCode = window.open(url,'','height=800, width=1000, top=500, left=200,scrollable=yes, menubar=yes, resizable=yes');
if (window.focus) {
thePopCode.focus();
}
}
jQuery(document).ready(function ($) {
// here is your HTML DOM ready
// create an onclick event for every a.uber-grid-hover
$("a.uber-grid-hover").click(function (event) {
event.preventDefault(); // this is "like" return false
// this get's the href from your anchor, using jQuery sugar
var url = $(this).attr("href");
// call your fun
popWin(url);
});
});
</script>
Using this script, you should no more need to create onclick attributes for every single anchor. Simply put that into your wordpress source, this should work as is.
Now simply make the <a> using class="uber-grid-hover", this is required so that jQuery can select the hovers easily, then you need the href and you may include also target="_blank" so that non-javascript users will also have the page in a new window.
<a class="uber-grid-hover" target="_blank"
href="http://www.weybridgestrategies.com/team/debra-porter-president-ceo">
Try this code :
function popwin(url) {
window.open('', url, 'height=800, width=1000, top=500, left=200, scrollable=yes, menubar=yes, resizable=yes');
url.target =url;
}
And for link,use the same code
javascript: onclick=popWin('http://www.weybridgestrategies.com/team/debra-porter-president-ceo'); return (false);
I want to disable right click link and i found this code:
<script type="text/javascript" language="javascript">
$(document).ready(function()
{
$('body').on('contextmenu', 'a', function(e){ return false; });
});
</script>
I want to add on a specific domain. something like this code (adfly fullpage script)
<script type="text/javascript">
var ad5fly_id = 4484512;
var ad5fly_advert = 'int';
var domains = ['depositfiles.com', 'rapidshare.com'];
</script>
<script src="https://cdn.adf.ly/js/link-converter.js"></script>
Basically, I dont want visitor to right click on my ad5fly link because they can bypass it easily. im talking about this: http://ad5f.ly/4484512/www.google.com : they can copy it and copy only the google link . then i wont earn any. help me guys.
thanks !!
sorry for my bad english
This is what you might be looking for
<script type="text/javascript">
$(document).load(function(){
$('body').on('contextmenu', 'a[href*=ad5f]', function(e){
e.preventDefault();
//or return false; does the same
});
});
</script>
If the anchor have a href which contains ad5f somewhere, then the contextmenu will be prevented.
Update:
I've added to be on LOAD instead of READY because if on ready, it might trigger before the link-converter.js ended doing it's thing (swapping urls) and the selector might fail.
Haven't tested this, but this is the solution from this thread here:
Disabling right click on images using jquery
$('body').bind('contextmenu', function(e) {
return false;
});
If that doesn't work, you could also try attaching the function you document or window instead.
You could iterate through the domains and cancel the right-click menu on page load.
var domains = ['depositfiles.com', 'rapidshare.com'];
for (var i = domains.length - 1; i >= 0; i--) {
$('body').on('contextmenu', 'a[href*="'+domains[i]+'"]', function(e){ return false });
};
As mentioned in the title is the question what does this all affect.
The code works fine and you want really see anything happen expect of the "href" attribute from the <a> tag gets changed to "iref".
I do this to load the content later via jquery.load()
Should I do this different? What would be the "right" way to do it?
What about google, does it affect google robots? I ask this because: if there is no javascript turned on, the links want change from href to iref and work off course. So the robots can follow them or not?
Thanks for all the answers.
There is a fiddle
<a class="top-nav animMainBox" href="/home.html">Home</a>
<a class="top-nav animMainBox" href="notathome.html">Not at home</a>
<a class="top-nav animMainBox" href="/contact.html">Contact</a>
<style type="text/css">
a{margin:10px;}
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(document).ready(function(){
hrefToIref();
$(document).on('click','.animMainBox',function(){
loadNewBox($(this), true);
});
});
function hrefToIref() {
$('.animMainBox').each(function(){
var url = $(this).attr('href');
$(this).attr('href','javascript:;').attr('iref',url);
});
$('.button').each(function(){
var url = $(this).attr('href');
$(this).attr('href','javascript:;').attr('iref',url);
});
}
function loadNewBox($this,animate) {
// loading and returning new boxes via
// var url = $this.attr('iref');
// $(".wrapper").load(url+' .toggle.box',{noncache: new Date().getTime()}, function(response, status, xhr) {}
}
</script>
Should I do this different?
Yes, definitely. iref attributes look quite invalid.
Can robots follow them or not?
Yes, they usually will only look at your static HTML markup with the href attributes.
What about google, does it affect google robots?
Google is a bit different I think as they can view pages with JS turned on. I don't know whether your script will stop them from following the links.
What would be the "right" way to do it?
Just leave the href attributes as they are. Prevent following them when they're clicked.
$(document).on('click','.animMainBox, .button', function(e){
e.preventDefault();
loadNewBox($(this), true);
});
function loadNewBox($this,animate) {
var url = $this.attr('href');
// ^ just use the correct attribute
…
}
Why not just like this :
$(document).ready(function(){
$('a').click(function(){ return false; });
$(document).on('click','.animMainBox',function(){
loadNewBox($(this), true);
});
});
This will stop the links from working and you can load something later on.
Search robots can still visit the links yes.
index.php
<html>
<head>
<title>My Title</title>
<script type="text/javascript">
function getLink(data) {
document.getElementById("box").innerHTML="This is "+data;
}
</script>
</head>
<body>
Home<br />
Profile<br />
Message<br />
Setting<br />
<hr />
<div id="box"></div>
</body>
</html>
Output
Home
Profile
Message
Setting
This is Home
As the code says my Div contents updated when i click any of the link but the problem is that when user goes back by clicking Back Button of Browser the content of my Div donot changes.
I want that either user Goes Back, Goes Forward or he directly puts the path in the address bar www.*****/index.php#profile the content of my Div should be change.
Note
I used document.location.hash to get the value of hash like this :
<head>
<script>
var hashValue=document.location.hash;
alert(hashValue);
</script>
</head>
but it works only when user goes back and then refresh the page
Plz help me how can i achieve this :(
You need to use hashchange event:
function hash_changed() {
var data = document.location.hash.substr(1);
var box = document.getElementById("box");
if (data) {
// inner page
box.innerHTML="This is " + data;
}
else {
// homepage
box.innerHTML = "";
}
}
window.onhashchange = function () {
hash_changed();
};
window.onload = function () {
hash_changed();
};
Also when you are using hashchange event, there is
no need to set onclick for your links:
Home
Profile
Message
Setting
When user click on a link, the hash automatically changes (with href attribute of link),
and hashchange event get fired.
Check DEMO here.
First Time
When a user come to your page for the first time with a hash:
http://fiddle.jshell.net/B8C8s/9/show/#message
We must show the wanted page (message here), so we must run hash_changed() function
we declare above, at first time. For this, we must wait for DOM ready or window.onload.
Check the HTML5 history API. It allows you to work with the browser history
HTML5 history api
$(window).on('hashchange', function() {
alert(location.hash);
});
or window.onhashchange event if you don't want to use jQuery
If you're going to be using AJAX, you'll really want to look into using jQuery instead of raw javascript unless your intention is educational. jQuery is just a mainstay of the web now.
If you must use those hashes...
Use jQuery Special Events, and use the hashchange event:
<a href='#home'>Home</a>
Script:
$(window).on('hashchange', function() {
$('#box').html("This is "+event.fragment);
});
However, for your scenario...
You don't need to use those # values at all as you're passing the values in your function arguments anyway according to the code you provided, just do this:
Home<br />
Alternatively (and preferably, as you're using AJAX according to the tags) you can use jQuery and its builtin selector click events which use Event Listeners:
<a href='javascript:void();' class='divLink' id='home'>Home</a><br/>
Script is this easy:
$('.divLink').click(function(){
$('#box').html("This is "+$(this).id());
}