I have a javascript file that I am loading for some of the pages for tracking different events. Javascript has a list of selectors and just attaches listeners to them and call a tracking api when selectors are clicked.
Some of the elements are links. I am wondering if there is a possible case when navigation to links href will be done before the attached listener will run and call the tracking api.
Don't know if this can help you, but to navigate to the URL and logging after it, would'nt this be the same as logging on each page load? You might be able to get the URL of traffic origin to trace everything.
Or, if you implement pjax, or load in new pages through ajax, you can wait for the new page to load and log the request after the loading is done.
Or, you could end up doing some voodoo like this:
$(document).on('click', 'a:not([href="#"])', function(e) {
e.preventDefault();
// Do logging here
window.location = $(this).attr('href');
});
(edit: oh yeah, I used jQuery...)
Since you already have specific selectors for the elements you bind the tracking event to, you could simply target all links with said selector, prevent the default behaviour with preventDefault(), call the tracking api and redirect (possible as a callback if the api call allows it) to the url in href property of the link.
Related
I have a situation where I have to manually decorate a specific link across my entire website with the Google Analytics linkerParam.
This is to pass the GA client ID from my main site over to my ecommerce site in order to maintain the session.
Normally this would occur automatically through the auto linker settings but there is a server-side redirect page that sits between my site and the ecommerce site.
That redirect page would pass along the GA client ID but it's never given a chance because it's a page on my domain and not the external domain. Auto linker won't work in that situation which is why I need to manually do it myself.
The solution that I've been given basically adds a javascript addEventListener to each link to the redirect page.
That solution does work.
Is it better to use the addEventListener for when people actually click on the specific link to only then decorate that link with the linkerParam?
Or is it better to simply modify each link when the page initially loads?
Thanks
In my custom linkers I decorate the link only after is has been clicked. My reasons (which you may or may not find convincing) are:
if a user hovers over a link I do not want him to see an attached client id
since search engines now execute javascript they might index decorated links
I can decorate links only after they are actually on the page (but I can attach a callback function to links that are created after the fact), so if a user leaves before DOM ready the link is not decorated
On a page with lot's of links decorating all of them actually takes some time and performance for something that I do not really need (after all I only need the clicked link decorated)
As to Ithans comment above (where I think he referred to the DOM rather than the sinister sounding "doom"), since the user leaves the page in any case after clicking the link (you would not decorate in-page linking), so multiple DOM operations are not an issue.
You can change all the links when the page load
something like
var linksToChange = document.querySelectorAll('.theLinkClass');
for (var item of linksToChange ) {
item.href= "http://google.es";
};
I need something to detect changes on the url but the page doesn't do post back, it changes dynamically adding just the div inside the html, so the URL page is something like this
http://www.examplepage/conversations/44455
and when I click on another section of the page it it is
http://www.examplepage/conversations/44874
it changes not only at the end but like this
http://www.examplepage/settings
without doing post back and reloading the javascript so my question is, is there a way to detect those changes? and event listener but how?
I search and everyone says hash event but I don't have any value after any hash so it doesn't work
EDIT
Just for the record I have no code of the page nor I have access, I'll explain better, I am doing a background google extension and I just added a slide out to an existing page, this page changes its url the way I explained above. the url changes like every page does, but they change the div inside the html so that the page doesn't have to charge everything again
You need to store the URL when the page loads as a starting point and setInterval to check for changes and modify based on that.
The following code does this check twice a second (500ms):
// store url on load
let currentPage = location.href;
// listen for changes
setInterval(function()
{
if (currentPage != location.href)
{
// page has changed, set new page as 'current'
currentPage = location.href;
// do your thing..
}
}, 500);
There is no "clean", event-based way to detect such URL changes from a content script.
They are done with history.pushState API - and using that API doesn't emit any DOM event.
Two possible indirect event-based approaches, besides the already mentioned poll-based one:
An extension can override history.pushState with an injected script to additionally emit a DOM event that can be listened to in a content script.
This approach is described in detail here.
The downside is that, depending on the code of the page in question, the injected script may need to be injected early, needing run_at: document_start which is suboptimal for page load performance.
Use a background page that listens to chrome.webNavigation.onHistoryStateUpdated event.
If you need to detect this in a background page — perfect,
you're done, without ever needing a content script.
If you need to detect this in a content script, you can use details.tabId in the event listener to send a message to the right content script.
So, I have a page that has several links with onClick events that will retrieve data from external files and fill a div with this data. This works as intended. When I refresh the page, however, the div empties again. What I would like to happen is that after a refresh, the div will maintain the last content retrieved.
I'd prefer not to go down the road of cookies and have looked into adding data to the URL which I think is the way I want to go with this.
Is there some nice JQuery calls that can append data to url when a link is clicked and then on refresh restore the required content to the div?
My loadContent function is:
function loadContent (url, container) {
var target = $(container);
target.load(url, function (text, statusText) {
if (statusText === "success") {
target.find("a[rel^='gridnav']").initgn();
}
});
}
edit: I forgot to mention, the line
target.find("a[rel^='gridnav']").initgn();
is used to re-initialise a script on the new content loaded.
So when I click a link, the onClick event calls the function like this
TEST</li>
where xyz.html contains only the data I want inside the div "#right"
Is there a way to edit this function to do what I want ?
You can append data to the url by using
window.location.hash
https://developer.mozilla.org/en-US/docs/DOM/window.location
If you search for QueryString in jQuery plugins, there should be dozens of plugins that simplify this task.
I'd use localStorage. It's like cookies but much, much easier to maintain. The only downside is that it's not supported by all legacy browsers (See http://caniuse.com/#search=localStorage for browser support). For an orview on thhe feature, see https://developer.mozilla.org/en-US/docs/DOM/Storage If you want to go with completely no cookie like features at all; well then it has to be done server side to the best of my knowledge
Without cookies, your task will be a little bit harder. But I may have two solution for you:
Using session on server, you can control which ajax has been call, so next time when the main page is loaded, you can append the new content to it.
Using url hash to append ajax anchor has been click #anchorname so you can click it a gain after reload.
The comment tells you how you can modify the url without a page load. You could use that. If you have to work with older browsers, then you can still use the fragment (or do both things).
There are some history plugins for jQuery/JavaScript that manage this .. it's a technique called "deep linking." You may be able to find something simple to work with. Basically when loadContent runs you would want to update the url from /whatever to /whatever#right with the fragment indicating the load-content ID or something like that.
Another alternative would be to set some flag on the server that loads into that div when the page loads initially, which would save you an ajax request too. Depending on how your server code is set up that may not work for you, though.
I don't want to use hashbangs, or shebangs, as they are known. I want to do it the way Facebook does. You click on Profile, the bar remains unchanged and the content is loaded using AJAX. I was wondering if the new HTML5 History API could be used.
EDIT: I think I'm going to go ahead and dive into HTML5's history API. Keeping the question open in case anyone has better suggestions.
The HTML 5 history API is the right way to go.
see here: https://www.new-bamboo.co.uk/blog/2011/02/03/degradable-javascript-applications-using-html5-pushstate/
The pushState and replaceState methods will allow you to change the URL without making an HTTP request. The difference being that pushState pushes a new state on to the history stack, while replaceState replaces the item at the top of the stack.
Also take a look at jquery-pjax
You don't need to do that. You can just prevent the default action from occuring. For instance, with jQuery we have;
function(event) {
event.preventDefault();
// this is different from event.stopPropogation()
// do some stuff
}
this will prevent the link's default action (following the url) from occurring.
P.S. I've always heard shebang refers specifically to this: #!, and not just #, but I could be misinformed...
I have a problem with a javascript set of functions that I made.
This functions walk the entire Html page and then add the onclick event to every anchor it finds.
It do some check on the anchor href and redirect to it (using window.location.href)
My problem is that the cronology don't work properly this way, and the :visited selector don't work anymore.
How I can preserve the chronology and let the :visited selector work properly?
Regards
There's no need to set location.href manually: The link will be followed properly if you don't prevent it explicitly via returning false or calling event.preventDefault() (event.returnValue = false in IE) in the onclick handler.
Are you tracking their visits for that session?
If so, what about a server side solution instead of using Javascript.
Each time you serve up a page request, you log that Url, Page Title, etc, into their session - That way you can keep track of where they have been.
In that regard, the :visited tags will still work and you'll have a somewhat more reliable source for page history.
Use jQuery?
$('a').live('click', function(event){
// do something
});
As long as you don't call event.preventDefault in that function you should be fine.