Google analytics in SPA - hash

I have a website which is like this
http://domain/?key=32dxzQW
where the key is auto generated from other site per user
What I need to know are the sections most visited, so I was thinking in use GA, and as my webpage is SPA the sections are handled using hash (#) in the URL. Here some examples:
http://domain/?key=32dxzQW#start
http://domain/?key=32dxzQW#section1
http://domain/?key=sfd2ACS#start
http://domain/?key=sfd2ACS#section1
http://domain/?key=sfd2ACS#section2
http://domain/?key=ssC56tE#start
I want to know if there is a way to get by GA a summary of the sections, like this:
start 3
section1 2
section2 1
Help please
Update:
I already did the change to handle fragments and works:
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
function sendToGA() {
ga('create', 'XXXXXXXXXXX', 'auto');
ga('send', 'pageview', {
'page': location.pathname + location.search + location.hash
});
}
sendToGA();
window.onhashchange = sendToGA;

The first thing that came to my mind is to add click or other events on the sections you want to track and check them in the Behavior -> Events section in GA.

GA doesn't track hashes (URL fragments) by default, but you can follow this guide to help with setting up virtual page views for each section of your page:
Tracking URL page fragments

Related

Using a Chrome extension to insert characters into sites such as Facebook

I have created a chrome extension to allow users to right-click in a textbox, and insert special characters. This works on many sites such as StackOverflow, but does not work on sites such as Facebook. This is because Facebook is not using a standard text box form control. Instead for each line in a text message, it seems to be using a div > div > span > span construct. Is there a way to create a Chrome extension to target page components such as this?
An portion of my Chrome extension code looks like this:
main.js:
chrome.contextMenus.create({
title: "\u038F",
contexts:["editable"],
onclick: function(info, tab){
chrome.tabs.sendMessage(tab.id, {action: "insertCharacter", character: '\u038F'});
}
});
content.js
chrome.extension.onMessage.addListener(function(request, sender, sendResponse){
var objField = document.activeElement;
if (request.action == "insertCharacter"){
insertAtCursor(objField, request.character);
}
});
function insertAtCursor(sField, sValue){
if (sField.selectionStart || sField.selectionStart == '0'){
var nStart = sField.selectionStart;
var nEnd = sField.selectionEnd;
sField.value = sField.value.substring(0, nStart) + sValue + sField.value.substring(nEnd, sField.value.length);
sField.selectionStart = nStart + sValue.length;
sField.selectionEnd = nStart + sValue.length;
}
else {
sField.value += sValue;
}
}
Is there a more general purpose way I can do this to handle various situations on different sites? If not, is there a way to specifically target Facebook as most of the time myself (and likely others) are going to be using my extension on Facebook. (Of course having it work for email sites such as GMail would be a benefit as well).
In case it helps someone else, this is what I modified my code to based on wOxxOm's suggestion:
chrome.extension.onMessage.addListener(function(request, sender, sendResponse){
if (request.action == "insertCharacter"){
insertAtCursor(request.character);
}
});
function insertAtCursor(sValue){
document.execCommand("insertText", false, sValue);
}
It's much more compact than my original approach and insertText handles the selection aspect automatically.

Protractor - get specific element in a list

I have a list of pages in a table and need to click on the next page.
<td><span>1</span></td>
<td>2</td>
<td>3</td>
So, if the browser is currently on page 1, I need to click on page 2.
I am currently getting the elements by "td", going through a for loop (or mapping function) to try and find the current page, and then trying to find the next page. I keep getting memory issues or timeouts the way I'm currently trying to solve it.
Mapping function (memory issues) gist: https://gist.github.com/CaseyHaralson/9965492d894565bfe9d7
For loop (timeout) gist: https://gist.github.com/CaseyHaralson/7153be9f437f4e3a7f5c
The for loop also looks like it has the potential issue of not necessarily resolving the pages in the correct order.
Note: I can't change the html.
Assuming your current page is has the span, something like this should work...
var clickNextPage = function() {
$('td span').getText().then(function(pageNum) {
element(by.cssContainingText('td a', pageNum + 1)).click();
});
};
This function should click the href based on the page number you pass in.
var visitPage = function (pageNumber) {
$('a[href="' + pageNumber + '"']).click();
};
it('should visit page three', function () {
expect(browser.getCurrentUrl()).toContain('1');
visitPage('3');
expect(browser.getCurrentUrl()).toContain('3');
});

How do I get the Onmouseover method to apply universally to all links?

We're aware of that amazing trick which allows users to highlight a link. But, you must repeat it for each link. for example: a href="https://www.yahoo.com" Onclick="window.open(this.href); return false" onmouseout="this.style.color = '#0000ff';" onmouseover="this.style.color = '#e3FF85';" align="justify">Yahoo. But, I would like this code to apply to every link on the page. I've explored 2 possible methods. One is to use STYLE TYPE and CLASS= methods. Another possibility is using STYLE H1 /H1 (similar to W3 schools). But, I haven't even come close to getting a universal application.
1. You can try this:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; ++i)
{
links[i].onmouseenter = function() {links[i].style.color = '#e3FF85';};
links[i].onmouseout= function() {links[i]..style.color = '#0000ff';};
}
You get the list of all links using getElementsByTagName('a') ('a' is tag name for links), and you can do anything you want with them.
2. You can also try it with jquery:
var allLinks = $('a');
allLinks.mouseenter(function() { $(this).css('color', '#e3FF85'); });
allLinks.mouseout(function() { $(this).css('color', '#0000ff'); })
3. If you just care about changing style (like color or background) when mouse is over your link, you can do it from CSS:
a:hover
{
color: #123456;
}

Can't detect click on links generated by jQuery

I'm generating some links for pagination of some data.
Here's the function that generates the links:
function BuildPaginationNav(targetPage, pageSize) {
var numRecords = $('#movieListTable').children().length,
numPages = Math.ceil(numRecords / pageSize),
startRecord = ((targetPage - 1) * pageSize);
for (var i = startRecord; i <= startRecord + pageSize - 1; i++) {
$('div#movieListTable > div:eq(' + i + ')').fadeIn(200);
}
// Only use prev page and first page buttons/links if not on first page
if (targetPage > 1) {
$('#pagination').append('<br>First Page | Prev Page | ');
} else if (targetPage = 1) {
$('#pagination').append('<br>First Page | Prev Page | ');
}
// Add the current page label
$('#pagination').append('<label id="currentPage">' + targetPage + '</label>');
// Only use next page and last page buttons/links if not on last page
if (targetPage < numPages) {
$('#pagination').append(' | Next Page | Last Page');
} else if ( targetPage === numPages) {
$('#pagination').append(' | Next Page | Last Page');
}
}
The above works as intended and the function is called at the end of the success function in an $.ajax call that gets the data that the pagination is for.
Here's what the generated HTML looks like if it's not on the first or last page:
<div id="pagination">
<br>
First Page |
Prev Page |
<label id="currentPage">2</label> |
Next Page |
Last Page
</div>
What I need to do is get the ID of the link that is clicked on so I can take the appropriate action. I've tried this:
$('#pagination a').click(function() {
console.log(this.id);
});
and I've also tried this:
$('#pagination a').on('click', function() {
console.log(this.id);
});
But neither works - well, if I put the generated HTML and the above jQuery in a jsFiddle it does work, but it doesn't in the full code.
I am especially surprised that $.on() doesn't work in this case, as I use that function elsewhere in my code.
If I put the generated HTML as HTML in the page itself, the jQuery does work, so it's got to have something with the fact that the links are generated dynamically.
How can I get clicks on those links to be detected?
I figured it out:
I found the function $.delegate();
I added this code at the end of the BuildPaginationNav() function:
$('#pagination').delegate('a', 'click', function() { console.log(this.id); });
I'll just call a function from there (where the console.log() is) that will perform the necessary actions.
If there's a different (or even better) way, let me know!
Your links are not created yet when binding event. You need to bind live action on some existing element.
$(document).ready(function() {
$("#pagination").on('click', 'a', function() { .... });
});
The '#pagination' element is supposed to be available in time of binding event. It's called delegated event - http://api.jquery.com/on/
I would have done it in following way.
Your way:
// Only use prev page and first page buttons/links if not on first page
if (targetPage > 1) {
$('#pagination').append('<br>First Page | Prev Page | ');
} else if (targetPage = 1) {
$('#pagination').append('<br>First Page | Prev Page | ');
}
My Way:
// Only use prev page and first page buttons/links if not on first page
if (targetPage > 1) {
$FirstPage=$('First Page');
$FirstPage.click(function() { .... });
$('#pagination').append($FirstPage);
//same for Prev page...
} else if (targetPage = 1) {
// same as above..
}
This way...i'm able to locate my links behaviour at one place only i do not need to search in the whole page to know.. what click event for anchors..and many more !!

YUI AutoComplete Example Problem

I was hunting for an implementations of YUI AutoComplete and I came across this script from the site asklaila.com -
<script type="text/JavaScript">
YAHOO.example.ACJson = new function() {
this.oACDS = new YAHOO.widget.DS_XHR("/AutoComplete.do",
["Suggestions[0].Results","Name"]);
this.oACDS.queryMatchContains = true;
this.oACDS.scriptQueryAppend = "city=Mysore"; // Needed for YWS
function fnCallback(e, args) {
document.searchForm.where.focus();
acSelected = true;
return false;
}
this.oAutoComp = new YAHOO.widget.AutoComplete('what','whatContainer', this.oACDS);
this.oAutoComp.itemSelectEvent.subscribe(fnCallback);
this.oAutoComp.formatResult = function (oResultItem,sQuery) {
return oResultItem[0];
}
this.oAutoComp.queryDelay = 0;
this.oAutoComp.useIFrame = true;
this.oAutoComp.prehighlightClassName = "yui-ac-prehighlight";
this.oAutoComp.minQueryLength = 2;
this.oAutoComp.autoHighlight = false;
this.oAutoComp.textboxFocusEvent.subscribe(function() {
this.oAutoComp.sendQuery("");
});
this.oAutoComp.doBeforeExpandContainer = function(oTextbox, oContainer, sQuery, aResults) {
var pos = YAHOO.util.Dom.getXY(oTextbox);
pos[1] += YAHOO.util.Dom.get(oTextbox).offsetHeight + 2;
YAHOO.util.Dom.setXY(oContainer,pos);
return true;
};
}
</script>
It is implenting the YUI AutoComplete Dropdown. What I want to understand is what this
this.oACDS = new YAHOO.widget.DS_XHR("/AutoComplete.do", ["Suggestions[0].Results","Name"]);
does and its effects on code.
That's using an older version of YUI, but it is setting up a DataSource for the autocomplete to read from. This particular DataSource uses XHR to request information from the server to populate the autocomplete field.
"Autocomplete.do"
Is a relative URL that is being queried by the DataSource every time the autocomplete fires while the user is typing.
["Suggestions[0].Results","Name"]
Is the responseSchema that tells the DataSource how to parse the results from the request to the URL. It needs to know how to parse the data so that it can show the proper results.
this.oACDS = new YAHOO.widget.DS_XHR("/AutoComplete.do", ["Suggestions[0].Results","Name"]);
On every key press, it fetches a json response from the server, and uses it to populate the autocomplete dropdown. The json contains names to display only at this node, "Suggestions[0].Results" in the "name" field.
If you have any trouble, ask ahead. I wrote that piece of code for asklaila.com
I was hunting for implementations of
YUI Autocomplete and I came across
this script...
Why not take a look at YUI AutoComplete page for in-depth examples.
Yahoo! UI Library: AutoComplete