Javascript to rewrite all external links on mousedown? - javascript

How can i rewrite all external links with a single onmousedown event?
Kinda like what facebooks does with it's link shim
Please check the original Facebook Article about the link shim:
http://on.fb.me/zYAq0N
Requirements:
Should work for all subdomains on mainsite.com.
Should redirect example.com to
mainsite.com/link.cgi?u=http://example.com
Should only redirect links not belonging to mainsite.com.
Uses:
This is for security of the users of a private web app, and to protect referrers.
Best to do it on the fly for good UI as pointed out in the FB article.
That's so when users hovers over some link it shows the correct link but when he clicks it, js redirects it to my.site.com/link.cgi=http://link.com
Thanks in advance
SOLVED: https://gist.github.com/2342509

For an individual link:
function $(id){ return document.getElementById(id); }
$(link).onclick = function(){ this.href = "http://otherlink.com"; }
My Sheisty Link
So to get all external links:
window.onload = function(){
var links = document.getElementsByTagName("a");
for(a in links){
var thisLink = links[a].href.split("/")[2];
if(thisLink !=== window.location.hostname){
links[a].href = "http://mainsite.com/link.cgi?u=" + links[a]; }
// Or you could set onclick like the example above
// May need to accommodate "www"
}}
Edit:
Found this answer and got a better idea.
document.onclick = function (e) {
e = e || window.event;
var element = e.target || e.srcElement;
if (element.tagName == 'A') {
var link = element.href.split("/")[2];
if(link !=== window.location.hostname){
links[a].href = "http://mainsite.com/link.cgi?u=" + links[a]; }
return false; // prevent default action and stop event propagation
}else{ return true; }
}};

If you use jQuery then the following will work
$('a:link').mousedown(function() {
this.href = 'http://my.site.com/link.cgi=' + this.href;
});
Otherwise
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
var a = anchors[i];
if(a.href) {
a.addEventListener('mousedown', function(e) {
this.href = 'http://my.site.com/link.cgi=' + this.href;
}, false);
}
}

Related

find and replace a unique html (href) string using javascript

Using Javascript, how can I change this classless anchor (assuming targeting unique href string):
to this, on page load:
You can select the element based on its href prop.
$('a[href="/unique-url-string/"]').prop('href', '/replacement-url-string/');
If you want to only search the pathname of these urls and keep the domain name the same you can try something like:
$('a').filter(function() {
return this.pathname === "/foo/bar"
}).prop('href', function () {
this.pathname = '/butt/butt/butt';
return this;
});
Using only JavaScript without library
function replaceLink(oldLink, newLink) {
var x = document.getElementsByTagName("a");
for(var i = 0; i < x.length; i++)
if(x[i].href == oldLink) {
x[i].href == newLink;
break;
}
}
}
Try this:
$(function(){
$('a[href="/unique-url-string/"]').attr('href', '/replacement-url-string/');
});
To replace a portion:
$(function(){
var a = $('a[href="/unique-url-string/"]');
a.attr('href', a.attr('href').replace('unique', 'replacement'));
});
var link = document.getElementById('linkToChange');
console.log(link.href);
link.href = "http://www.google.com";
me
Just do this :
$().ready(function(){
$('a').attr("href").replace("unique","replacement");
});

How to prevent Wordpress built-in “browse link” entering the data in wp-editor

Working with Wordpress Meta Box and I used the code of Dale Sattler from this How can I use the built in Wordpress “browse link” functionality? to create a custom field with wp browse link it works fine, but it inserted the data in wp-editor too.
I try to prevent the default event using code here Use WordPress link insert dialog in metabox? but doesn't work, I try that code too but it have a bug too.
here is my code
var _link_sideload = false; //used to track whether or not the link dialogue actually existed on this page, ie was wp_editor invoked.
var link_btn = (function($){
'use strict';
var _link_sideload = false; //used to track whether or not the link dialogue actually existed on this page, ie was wp_editor invoked.
var input_field = '';
/* PRIVATE METHODS
-------------------------------------------------------------- */
//add event listeners
function _init() {
$('body').on('click', '.link-btn', function(event) {
_addLinkListeners();
_link_sideload = false;
input_field = $(this).attr('href');
var link_val_container = $(input_field);
if ( typeof wpActiveEditor != 'undefined') {
wpLink.open();
wpLink.textarea = $(link_val_container);
} else {
window.wpActiveEditor = true;
_link_sideload = true;
wpLink.open();
wpLink.textarea = $(link_val_container);
}
return false;
});
}
/* LINK EDITOR EVENT HACKS
-------------------------------------------------------------- */
function _addLinkListeners() {
$('body').on('click', '#wp-link-submit', function(event) {
var linkAtts = wpLink.getAttrs();
console.log(linkAtts);
var link_val_container = $(input_field);
link_val_container.val(linkAtts.href);
_removeLinkListeners();
return false;
});
$('body').on('click', '#wp-link-cancel', function(event) {
_removeLinkListeners();
return false;
});
}
function _removeLinkListeners() {
if(_link_sideload){
if ( typeof wpActiveEditor != 'undefined') {
wpActiveEditor = undefined;
}
}
wpLink.close();
wpLink.textarea = $('html');//focus on document
$('body').off('click', '#wp-link-submit');
$('body').off('click', '#wp-link-cancel');
}
/* PUBLIC ACCESSOR METHODS
-------------------------------------------------------------- */
return {
init: _init,
};
})(jQuery);
please help, please ....
Ok I think I found a way to remove the link from the content. In your submit event you need to add:
$('body').on('click', '#wp-link-submit', function(event) {
var linkAtts = wpLink.getAttrs();
var link_val_container = $(input_field);
link_val_container.val(linkAtts.href);
var $frame = $('#content_ifr'),
$added_links = $frame.contents().find("a[data-mce-href]");
$added_links.each(function(){
if ($(this).attr('href') === linkAtts.href) {
$(this).remove();
}
});
_removeLinkListeners();
return false;
});
$('#content_ifr') is the iframe that loads tinymce editor with content inside. Since the iframe is loaded from the same domain you can mess around it (luckily). So you just go through its contents and you're looking for anchors that have data attribute called mce-href, and if the link that you've just added has the href value as the one you've added it removes them.
I re did this part of the code because I've noticed that all the links in my content had this attribute so you cannot just remove all anchors that have
data-mce-href attribute because that would remove all of them. And you only want to remove those you've added in your metabox.
This did the trick for me :)

How to dynamically change the anchor tag link?

I'm trying to remove a landing page when I click on a link on a page. The page isn't mine so I'm trying to change the href with a user script.
Without any modification, the link looks like this:
https://www.domain.com/out.php?u=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DPUZ1bC-1XjA%26amp%3Bfeature%3Drelated
What I want:
http://www.youtube.com/watch?v=PUZ1bC-1XjA&feature=related
What I got so far:
http://www.youtube.com%2fwatch%3fv%3dpuz1bc-1xja%26amp%3bfeature%3drelated/
But that adress doesn't work in the browser.
This is my current code:
$('a').each(function(index) {
var aLink = $(this).attr('href');
if(aLink) {
if(aLink.indexOf("out.php?u=") > 0) {
aLink = aLink.substring(51);
console.log(aLink);
$(this).attr('href', "http://"+aLink);
console.log($(this).prop('href'));
}
}
});
All help and tips are appreciated.
You need to decode the URL using decodeURIComponent
Change:
$(this).attr('href', "http://"+aLink);
To:
$(this).attr('href', 'http://' + decodeURIComponent(aLink));
Take a look at decodeURIComponent
You can also make use of the hostname, pathname, and search parameters of anchor elements.
// general function to turn query strings into objects
function deserialize_query_string(qs) {
var params = {};
var fields = qs.split('&');
var field;
for (var i=0; i<fields.length; i++) {
field = fields[i].split('=');
field[0] = decodeURIComponent(field[0]);
field[1] = decodeURIComponent(field[1]);
params[field[0]] = field[1];
}
return params;
}
$(document.links).each(function(i){
if (this.hostname=='www.domain.com' && this.pathname=='/out.php') {
var params = deserialize_query_string(this.search);
if (params.u) {
this.href = u;
}
}
});

Remove specific JS code with a click?

I've tried searching around but couldn't find a solution to this.
I am running two main JS functions on a site I am building. One which is lazy load, and one which is a smooth scroll, the latter for an anchor link to the bottom of the page.
However, with them both being present, they conflict each other as you can't anchor smooth scroll to the bottom of the page with lazyload... it just isn't happening.
Is there a way to disable lazyload if the user clicks on the anchor link? Thus making it work, and if they don't, then the lazyload works just fine?
Lazy Load:
<script>
$("img").lazyload({
threshold : 10000,
placeholder : "images/white.gif",
effect : "fadeIn"
});
</script>
Smooth scroll (although unfortunately this works for ALL anchor links... grrr):
<script>
$(document).ready(function() {
function filterPath(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
}
var locationPath = filterPath(location.pathname);
var scrollElem = scrollableElement('html', 'body');
$('a[href*=#]').each(function() {
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath
&& (location.hostname == this.hostname || !this.hostname)
&& this.hash.replace(/#/,'') ) {
var $target = $(this.hash), target = this.hash;
if (target) {
var targetOffset = $target.offset().top;
$(this).click(function(event) {
event.preventDefault();
$(scrollElem).animate({scrollTop: targetOffset}, 1400, function() {
location.hash = target;
});
});
}
}
});
// use the first element that is "scrollable"
function scrollableElement(els) {
for (var i = 0, argLength = arguments.length; i <argLength; i++) {
var el = arguments[i],
$scrollElement = $(el);
if ($scrollElement.scrollTop()> 0) {
return el;
} else {
$scrollElement.scrollTop(1);
var isScrollable = $scrollElement.scrollTop()> 0;
$scrollElement.scrollTop(0);
if (isScrollable) {
return el;
}
}
}
return [];
}
});
</script>
Thanks in advance,
R
You could replace the contents of the script with the contents surrounded by comments /* / on click and then re-enable by removing these comments / */. If the script never needs to be used again on the same page you could place the script inside a container element with an id and use jquery to remove that element from the page on click event. Another option that may work would be to alter the javascript to check a 'flag' that is toggled upon clicking the anchor link, the 'flag' can just be a javascript variable in the page that prevents the scripts you don't want to run from running.

Detecting Href Is Clicked

I'm trying to detect if certain element is clicked on onbeforeunload. I can't get it to work. Below is examples of the Javascript code and HTML code on the project (Please note that I have no control over the HTML element as it is not my site)
function checkLeave() {
var p = document.getElementByElementById('yeah');
if (p.href.onclick) {
//do something
}
else {
//do something else
}
}
window.onbeforeunload = checkLeave;
HTML CODE
//The goSomewhere goes to another page
<a id="yeah" href="javascript:goSomewhere();">
<img src="smiley.png">
</a>
Thanks in advance,
J
What you need to do is bind an event handler to each on the page.
This can be done with the following:
// Select all links
//var allLinks = document.querySelectorAll('a[href]');
var allLinks = document.links;
// Bind the event handler to each link individually
for (var i = 0, n = allLinks.length; i < n; i++) {
//allLinks[i].addEventListener('click', function (event) {});
allLinks[i].onclick = function () {
// Do something
};
}
You are testing for the presence of the onclick property to the <a> tag. It isn't present in the markup. Rather than using the onclick, the markup calls a script as the element's href. So you need to look for a script in the href instead:
var p = document.getElementByElementById('yeah');
if (p.href.indexOf("javascript") === 0) {
//do something
}
else {
// do something else
}
Maybe something like this? (just the idea)
document.getElementById('yeah').onclick = function() {
clicked = this.href;
};

Categories

Resources