The scenario is a lot of html files with a lot more of links between them. When I call the first one of them (it would be the index), the link pass several parameters through the URL (we could call them preferences).
Now I want that, when clicking any of the several links of the page, those parameters would be added. So the problem would be similar to this other ( How to add parameters to a URL that already contains other parameters and maybe an anchor) but doing it just after clicking the link.
I know that one solution could be changing the onclick event on each link, but as there may be thousands of them, without a regular url format... I'm looking for a solution that could be on the script at the head; perhaps something relative to onbeforeunload event.
Anyway I couldn't find how to do it. Any ideas?
This will append a string to anything containing an href-attribute when being clicked:
window.addEventListener("click", function(e) {
var href = e.target.getAttribute("href");
if(href) {
location.href = href + "?q=stackoverflow";
e.preventDefault();
}
});
Example here: http://jsfiddle.net/E5Q7P/
Won't work in < IE9
Instead of changing the onclick-attribute of each link, or using the onbeforeunload-event, I guess one way would be to attach a clickevent-listener to all anchor-elements when the page loads. The callback could then intercept the browsers default behavior to follow the link. You could then get the src attribute of the a-element that was just clicked, add the desired preferences to the URL and then send the user to the proper location (including preferences) by setting window.location.href to the proper URL.
There is a great aricle on MDN about event-listeners, that I believe would be helpful to you. Note specially the section about older versions of IE
A very crude example of what it could look like:
function callback(e){
// Get the src of the clicked a-element
var src = this.src;
// Add preferences to the url, this need
// improvement depending on your needs
src += "?somesetting=foo";
// Send user to the url with preferences
window.location.href = src;
}
// Get all anchors on page
var anchors = document.getElementsByTagName("a");
// Loop over the elements and attach listener
for(i=0 ; i < anchors.length ; i++){
// Extend with support for older IE if needed
anchors[i].addEventListener("click", callback, false});
}
Related
I am writing a userscript for a website to change link targets from "_blank" to "_self".
The website's links are all handled by an EventListener on Click action, which reviews the id attribute for every <a> element to set the click URL and load it in a new tab. None of the <a> elements have a href or target attribute.
I would like all clicked links to load in the same tab (rather than a new tab).
Is there any way to modify link targets set by an event listener, or to simply set/override the default link target for all links on a webpage?
Provided you want to override the behavior of links that open in a new tab, you could override window.open as such:
window.open = (open => (href => open.call(window, href, '_self')))(window.open);
For anchor tags with an explicit target of _blank, you could theoretically override the click method to force the target:
window.HTMLAnchorElement.prototype.click = function() { window.open(this.href, '_self') };
However, this is in fact a hacky solution and might not be the best idea to use in production.
you can do select your element with document.querySelector().target = "_self"
EDIT Jan 12, 2023: there is a much better and easier way to do this, if you're using Tampermonkey.
GM_addElement allows you to do exactly what I described in the request, to insert code into actual page:
https://www.tampermonkey.net/documentation.php#api:GM_addElement
I used the script version, to add a function (you have to enclose it in quotes, like text).
This solution works much better with stricter websites and browsers, so you won't get CSP errors.
OLD ANSWER:
The answer to this question solved my issue:
How to overwrite a function using a userscript?
I re-wrote the open function from skara9's answer, and then inserted it with the addJS_Node function from the above question.
Userscripts are separated from the target page, hence why simply re-declaring the function was not overwriting the default global open function.
I have a anchor link like
<a id="myanchor" href="http://google.com" target="_blank">Google</a>
How to open href target in a new tab programatically?
Try the following:
$("#myanchor")[0].click()
As simple as that.
There's a difference in invoking the click event (does not do the redirect), and navigating to the href location.
Navigate:
window.location = $('#myanchor').attr('href');
Open in new tab or window:
window.open($('#myanchor').attr('href'));
invoke click event (call the javascript):
$('#myanchor').click();
Even though this post is caput, I think it's an excellent demonstration of some walls that one can run into with jQuery, i.e. thinking click() actually clicks on an element, rather than just sending a click event bubbling up through the DOM. Let's say you actually need to simulate a click event (i.e. for testing purposes, etc.) If that's the case, provided that you're using a modern browser you can just use HTMLElement.prototype.click (see here for method details as well as a link to the W3 spec). This should work on almost all browsers, especially if you're dealing with links, and you can fall back to window.open pretty easily if you need to:
var clickLink = function(linkEl) {
if (HTMLElement.prototype.click) {
// You'll want to create a new element so you don't alter the page element's
// attributes, unless of course the target attr is already _blank
// or you don't need to alter anything
var linkElCopy = $.extend(true, Object.create(linkEl), linkEl);
$(linkElCopy).attr('target', '_blank');
linkElCopy.click();
} else {
// As Daniel Doezema had said
window.open($(linkEl).attr('href'));
}
};
window.open($('#myanchor').attr('href'));
$('#myanchor')[0].click();
It worked for me:
window.location = $('#myanchor').attr('href');
$(":button").click(function () {
$("#anchor_google")[0].click();
});
First, find the button by type(using ":") if id is not given.
Second,find the anchor tag by id or in some other tag like div and $("#anchor_google")[0] returns the DOM object.
You cannot open in a new tab programmatically, it's a browser functionality. You can open a link in an external window . Have a look here
I have page the has some data in tabs, Im trying to write a function so that when links are click from another page can load the page with the tabs on and show the correct tab. This is working with the code below, minus the actual changing tabs function. But for some reason using the window.location..... as a variable still scroll the page down to the matching id. Is there another way to get the string in the url after the #. Or can i do it this way but not have to jump to the id? thanks
function loadTab(){
var linkToTab = window.location.hash.substr(1);
var linkClass = '.'+linkToTab
if(window.location.hash != '') {
changeTabs(linkClass);
}else{
$('.companyLink:first').addClass('active');
$('.companyBio:first').addClass('active');
$('.companyBio:first').fadeIn();
};
}
The hash character is for anchors.
Use a question mark instead of a hash.
<a href="index.html?tabname">
and
var linkToTab = window.location.search.substr(1);
var linkClass = '.'+linkToTab
if(window.location.search != '') {
The # part of the URL is traditionally used for anchors. The 'jumping' you see is the original feature.
Modern websites and web-applications use it build a history as HTML5's history feature isn't widely supported yet.
To avoid the jumping add event.preventDefault to your links, like:
Tab1
<script type="text/javascript">
document.getElementById("tab1handle").onclick = function (event) {
event.preventDefault();
}
</script>
You can also make sure the anchor is not defined. In this case the browser will jump to the top of the page. It's up to you whether this is undesirable or not.
I am using JavaScript to make a small iframe application, and I cannot seem to figure out a way to update the URL in my URL bar I made when someone clicks a link inside the iframe.
It needs to be instantaneous, and preferably without checking every millisecond whether or not the value of document.getElementById('idofiframe').src has changed.
I can't seem to find a simple property to tell when the url has changed, so if there is not one, then solving this programmatically will work as well.
Thanks for the help!
This will be difficult to do because it is considered xss and most browsers block that.
There are most likely some workarounds involving AJAX.
First of all, what you want to do will be possible only if the source of your iframe points to the same domain as the parent window. So if you have a page page.html that iframes another page iframed.html, then both of them have to reside on the same domain (e.g. www.example.com/page.html and www.example.com/iframed.html)
If that is the case, you can do the following in the iframed.html page:
<script type="text/javascript">
window.onload = function() {
var links = document.getElementsByTagName('a');
for (var i=0, link; link = links[i]; i++) {
link.onclick = function() {
window.parent.location.href = '#' + encodeURIComponent(this.href);
}
}
}
</script>
This will make it so that whenever you click on a link in iframed.html, the url bar will put the url of the link in the "hash tag" of the url (e.g. www.example.com/page.html#http%3A%2F%2Fwww.example.com%2FanotherPage.html)
Obviously, you would have to have a script like this on every page that is to appear inside the iframe.
Once this is in place, then you can put this snippet inside of page.html, and it will make the iframe automatically load the url in the hash tag:
window.onload = function() {
var url = window.location.hash.substr(1);
if (url) {
document.getElementById('iframe').src = url;
}
}
I unfortunately haven't run this code to test it, but it is pretty straight forward and should explain the idea. Let me know how it goes!
You could add an onload event to the iframe and then monitor that - it'll get thrown whenever the frame finishes loading (though, of course, it could be the same URL again...)
Instead, can you add code to the frame's contents to have it raise an event to the container frame?
In IE, the "OnReadyStateChanged" event might give you what you want.
Background: I have an HTML page which lets you expand certain content. As only small portions of the page need to be loaded for such an expansion, it's done via JavaScript, and not by directing to a new URL/ HTML page. However, as a bonus the user is able to permalink to such expanded sections, i.e. send someone else a URL like
http://example.com/#foobar
and have the "foobar" category be opened immediately for that other user. This works using parent.location.hash = 'foobar', so that part is fine.
Now the question: When the user closes such a category on the page, I want to empty the URL fragment again, i.e. turn http://example.com/#foobar into http://example.com/ to update the permalink display. However, doing so using parent.location.hash = '' causes a reload of the whole page (in Firefox 3, for instance), which I'd like to avoid. Using window.location.href = '/#' won't trigger a page reload, but leaves the somewhat unpretty-looking "#" sign in the URL. So is there a way in popular browsers to JavaScript-remove a URL anchor including the "#" sign without triggering a page refresh?
As others have mentioned, replaceState in HTML5 can be used to remove the URL fragment.
Here is an example:
// remove fragment as much as it can go without adding an entry in browser history:
window.location.replace("#");
// slice off the remaining '#' in HTML5:
if (typeof window.history.replaceState == 'function') {
history.replaceState({}, '', window.location.href.slice(0, -1));
}
Since you are controlling the action on the hash value, why not just use a token that means "nothing", like "#_" or "#default".
You could use the shiny new HTML5 window.history.pushState and replaceState methods, as described in ASCIIcasts 246: AJAX History State and on the GitHub blog. This lets you change the entire path (within the same origin host) not just the fragment. To try out this feature, browse around a GitHub repository with a recent browser.
Put this code on head section.
<script type="text/javascript">
var uri = window.location.toString();
if (uri.indexOf("?") > 0) {
var clean_uri = uri.substring(0, uri.indexOf("?"));
window.history.replaceState({}, document.title, clean_uri);
}
</script>
There is also another option instead of using hash,
you could use javascript: void(0);
Example: Open Div
I guess it also depends on when you need that kind of link, so you better check the following links:
How to use it: http://www.brightcherry.co.uk/scribbles/2010/04/25/javascript-how-to-remove-the-trailing-hash-in-a-url/
or check debate on what is better here: Which "href" value should I use for JavaScript links, "#" or "javascript:void(0)"?
$(document).ready(function() {
$(".lnk").click(function(e) {
e.preventDefault();
$(this).attr("href", "stripped_url_via_desired_regex");
});
});
So use
parent.location.hash = '' first
then do
window.location.href=window.location.href.slice(0, -1);
As others have said, you can't do it. Plus... seriously, as the jQuery Ajaxy author - I've deployed complete ajax websites for years now - and I can guarantee no end user has ever complained or perhaps ever even noticed that there is this hash thing going on, user's don't care as long as it works and their getting what they came for.
A proper solution though is HTML5 PushState/ReplaceState/PopState ;-) Which doesn't need the fragement-identifier anymore:
https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
For a HTML5 and HTML4 compatible project that supports this HTML5 State Functionality check out https://github.com/browserstate/History.js :-)