Javascript - Check for Hash, Ignore Analytics Code following - javascript

We are adding a video to the home page of a site, and want to be able to automatically pop up the video (in a lightbox-style container) whenever the #video tag is present in the URL:
http://www.domain.com#video
The video needs to pop up if a link is clicked internally on the site (ie: <a href="#video">) and also if the hash is present in the URL on page load.
Easy enough to check for the hash in the URL using window.location.hash or when a link with the hash is clicked and fire the associated javascript function. That's working as expected without any issues.
However as this URL will be sent out in emails with Google Analytics code automatically added, the analytics code is appended to the end of the URL:
http://www.domain.com#video?utm_source=...
Because the analytics code will change with each email campaign, I can't do a simple Javascript replace() to ignore the analytics code.
How do I go about checking whether the hash is present in the URL, but ignore anything after a ? if present?

Isn't the proper form of a URL to have the hash at the end after the query parameters? Then, the location.hash variable will work properly and you won't need special code. Your URL should look like this and then you can just directly use location.hash which will be #video:
http://www.domain.com?utm_source=xxx#video
I don't advise this as the solution (I think you ought to get the URLs fixed to be legal), but you can use this code to parse the hash value out of the URL even if it's in the illegal position:
var matches = window.location.href.match(/#(.*?)(\?|$)/);
if (matches) {
var hash = matches[1];
}
This code extracts from the "#" to either end of string or "?" whichever comes first. You can see it run on a bunch of test URLs here: http://jsfiddle.net/jfriend00/HuqL7/.

location.hash.match(/[^?]*/)
Assuming the hash is always first, that should do it.

(This is a literal answer to your question, but there is a huge caveate) Technically, you can just test:
var h = window.location.hash;
var ind = h.indexOf( '?' );
var test = ind <0?h:h.substr(0, ind)
If you want Google Analytics to work, you may have problems #. The rule is that everything after a # is not sent to the server, which means that your Analytics may go out the window. You need to make sure that your hash is added after all of the Google stuff. If it is, then you won't need to worry about testing anything.

Related

Passing Url params from one page to another

So I have a filter form on a page that show paginated results. Currently when you apply the filter settings using a get request everything works but when you try to switch pages it resets. I have thought of passing a url from one page to another using a script like the one below. This copies the url but does not actually change the page, just copies the string. You can see in the urls below that the url does change page but the actual webpage stay on the first page regardless of the url. I am using Django and Django filters. Maybe a there is a better jQuery solution, Any suggestions?
script
document.querySelectorAll('.fqs')
.forEach((el) => el.attributes.href.value += window.location.search);
Url
Without script:
/relations/?createdBy=&occursIn=&createdAfter=&createdBefore=&terminal_nodes=&project=1
With Script:
/relations/?page=2?createdBy=&occursIn=&createdAfter=&createdBefore=&terminal_nodes=&project=1
Next Page Link
<a class="fqs" href="?page={{ relations.next_page_number }}">Next ยป</a>
Url when pressing previous button
?page=1&page=2&createdBy=&occursIn=&createdAfter=&createdBefore=&terminal_nodes=&project=1
If I understand correctly you're adding pagination server-side ?page={{...}} and you adding already existing url parameters via js.
The resulting urls have two ? in it which may be why the link doesn't give you the correct page.
location.search includes the ? so to add that to your ?page=x you'd have to replace ? with &:
document.querySelectorAll('.fqs')
.forEach((el) => el.attributes.href.value += window.location.search.replace("?", "&"));
EDIT: if this works it may stop working on next pages as location.search would then include page=x giving duplicate page query parameters.
To filter out page parameter from location.search you could do something like:
document.querySelectorAll('.fqs')
.forEach((el) => {
var params = window.location.search.replace("?", "&").split("&");
params = params.filter((v) => v.indexOf("page") == -1).join("&");
el.attributes.href.value += params;
});
BTW, note that arrow functions don't work in legacy browsers like IE11.
In order to accomplish this I decide to not use any javascript at all and use python instead. I added
gt = request.GET.copy()
if 'page' in gt:
del gt['page']
context = {
'paginator': paginator,
'relations': relations,
'params': urlencode(gt),
'filter': filtered,
}
to my view. It copies the params, then deletes the param matching page and encodes in the context.

Redirect page and call javascript function

I need to redirect to another page onClick of submit and call a function making an ajax call. This is what I have :
$('#submitButton').click(function() {
window.location.href = "otherPage";
displayData();
});
Also, Another way I tried is to set the form fields on otherPage by using
var elem = window.document.getElementById(field);
elem.value = "new-value";
so that I could call the eventhandler of a submit button present on otherPage, but it doesn't work. Please let me know where I am wrong.
I'm not sure if there is a neat way to achieve this, but you can add a hash in your url you redirect to, then just simply check if the hash exists, execute function and remove hash.
Here are some handy URLs:
Location.Hash - information about this function and how to use it.
Removing hash from url without a page refresh - This was a bit of an issue, as window.location.href = ''; removes everything after the hash.
A hash (as Arko Elsenaar said) or a querystring parameter added to the target URL would allow you to detect what to do once there.
The hash makes it a bit easier while the querystring is cleaner if you want to pass more information.
For instance on the first page: window.location.href = "other/page.html#displayData";
On the second page:
if (window.location.hash === '#displayData') {displayData();}
Another way could be to use the HTML5 Storage API, if and only if the 2 pages are on the same domain.
1st page would do, before the redirection:
localStorage.displayData = true
And the 2nd:
if (localStorage.displayData) {displayData();}
However in this case you'll need to clean up the localStorage.displayData value when used, otherwise it will stay there forever and your second page would always find it set to true.
delete localStorage.displayData
All in all, the hash method seems best here.

hide variables passed in URL

We've been working on a web application and we've just about got it finished up, but there's one thing that bothering us (although by no means is it going to stop production.)
When we call one of the pages (index.html), we sometimes have to pass it a variable in the URL (searchid). So we get a page like http://domain.com/index.html?searchid=string.
We'd ideally like to not show the ?searchid=string, but I'm not sure how we'd do that.
My group doesn't own the index.html page (but we are working with the group that does), so I don't know how much we'd be able to do with anything like .htaccess or similar.
I was thinking about POSTing the variable, but I don't know how to receive it with just HTML and jQuery. Another person in my group thought that after the page loaded we could remove it from the URL, but I assume we would need a page refresh which would then lose the data anyway.
I'm trying to avoid XY problem where the problem is X and I ask about Y, so what's the right way to remove the variable from the URL?
You can use the History API, but it does require a modern browser
history.replaceState({}, null, "/index.html");
That will cause your URL to appear as /index.html without reloading the page
More information here:
Manipulated the browser history
Your question seems to indicate that the target page is not and will not be powered by some server-side script. If that's the case, I'd suggest changing the querystring to a hash, which has the advantage of being directly editable without triggering a page-load:
http://yourdomain.com/page.html#search=value
<script type='text/javascript'>
// grab the raw "querystring"
var query = document.location.hash.substring(1);
// immediately change the hash
document.location.hash = '';
// parse it in some reasonable manner ...
var params = {};
var parts = query.split(/&/);
for (var i in parts) {
var t = part[i].split(/=/);
params[decodeURIComponent(t[0])] = decodeURIComponent(t[1]);
}
// and do whatever you need to with the parsed params
doSearch(params.search);
</script>
Though, it would be better to get some server-side scripting involved here.
It's possible to rewrite the URL using JavaScript's history API. History.js is a library that does this very well.
That being said, I don't think there's any need for removing the query-string from the URL, unless you're dynamically changing the contents of the page to make the current query-string irrelevant.
You could post the data, then let the server include the posted data in the page, e.g.:
echo "<script> post_data = ".json_encode($_POST)." </script>";
This works cross-browser.

Modify Query String Without new HTTP Request

Is it possible to manipulate the query string without actually submitting a new HTTP request?
For example, I have a page that allows the user to make a bunch of changes to some configuration options. When they first go to the page it will be the following URL:
www.mysite.com/options
As they click certain elements on the page, a link here or a radio button there, the URL would be changed to something like:
www.mysite.com/options?xkj340834jadf
This way the user can copy the URL and later go to the same page and have the configuration be exactly how it was before, but I don't want to submit new requests as they click the options.
Is this something that is possible using javascript/jquery?
I don't think this is possible.
Your best solution would be to add an anchor tag to the end of the URL, which can then be read by jquery to determine a HTTP redirect.
I believe google also indexes when you use #! for this purpose.
What's the shebang/hashbang (#!) in Facebook and new Twitter URLs for?
The best solution is by using hash. As Curt stated, #! is the way you tell Google that this is a webapp but if you don't need crawling, don't worry.
You can use then something like this:
var hash = location.hash; //or window.location.hash
hash = hash.replace(/^.*#!/, ''); // strip #! from the values
//do something with the values you got stored in `hash` var
If you need other things to happen, like everytime the hash changes, you do something, you can bind the 'hashchange' event.For example:
I use jQuery hashchange event by Ben Alman for that:
$(window).hashchange( function(){
var hash = location.hash;
hash = hash.replace(/^.*#!/, '');
// do something with 'hash' everytime it changes
// EXAMPLE:Set the page title based on the hash.
document.title = 'The hash is '+hash+'.';
return false; //this prevent browser from following the # after doing what you wanted
});

Cut string obtained with Javascript inside hyperlink

I made a bookmark that users can add and it sends them to my site capturing the referrer.
Bookmark
My problem is that for some reason the location.href part instead of printing http:// it prints: "http%3A//". I want to remove it and get just the domain.com
I have a similar code that maybe could be useful but I'm having a hard time figuring out how to implement it inside HTML.
// Function to clean url
function cleanURL(url)
{
if(url.match(/http:\/\//))
{
url = url.substring(7);
}
if(url.match(/^www\./))
{
url = url.substring(4);
}
url = "www.chusmix.com/tests/?ref=www." + url;
return url;
}
</script>
Thanks
In most browsers, the referrer is sent as a standard field of the HTTP protocol. This technically isn't the answer to your question, but it would be a cleaner and less conspicuous solution to grab that information server-side.
In PHP, for example, you could write:
$ref = $_SERVER['HTTP_REFERER'];
...and then store that in a text file or a database or what-have-you. I can't really tell what your end purpose is, because clicking a bookmark lacks the continuity of browsing that necessitates referrer information (like the way that moving from a search engine or a competitor's website would). They could be coming from a history of zero, from another page on your site or something unrelated altogether.
Like already stated in my comment:
Be aware that this kind of bookmarking may harm users privacy, so please inform them accordingly.
That being said:
First, please use encodeURIComponent() instead of escape(), since escape() is deprecated since ECMAScript-262 v3.
Second, to get rid of the "http%3A//" do not use location.href, but assemble the location properties host, pathname, search and hash instead:
encodeURIComponent(location.host + location.pathname + location.search + location.hash);

Categories

Resources