I am trying to make a chrome extension which requires me to collect the post links. But the problem with collecting the link is that it is available on the anchor tag on the timestamp that FB provides over each post.
But the href of the anchor tag is populated dynamically when you hover over the element.
I tried dispatching a mouseover and mouseenter events on the element but the href is still not populated.
My function :
const hoverOverTag = (element) => {
var event = new Event('mouseover', {
'view': window,
'bubbles': true,
'cancelable': true
});
element.addEventListener('mouseover', function(e) {
console.log("hover");
console.log(e);
});
element.dispatchEvent(event);
}
The event listener runs and logs the event properly. But still href does not get populated.
I am running this in a content script, is there any way i can get the post link ?
In the following I will describe my method I followed to tackle the issue, the findings and a solution that worked for me.
After loading the Facebook page, I used the Google Chrome Development Tools to inspect the <a> element.
Then I added an XHR/fetch Breakpoint on any XHR or fetch. Then hovered the mouse to trigger the event and immediately the code was interrupted and the stopped at the breakpoint.
After following the code it became clear that the front-end retrieve the post-id of dynamically by sending an Ajax request to the API node /bulk-route-definitions/ at Facebook. Although it is theoretically possible to get the post-id by manually calling that API node with the correct request header data, pursuing that potential solution is simply too time consuming because of all security/privacy protection Facebook currently employs.
Right after that I started looking at triggering the event programmatically as mentioned in the question above, so I triggered the breakpoint again and checked the call stack and reverse followed the obfuscated and uglified code.
Eventually I found it:
var event = new FocusEvent('focusin', {
'view': window,
'bubbles': true,
'cancelable': true
});
the_a_element.dispatchEvent(event); //reference to the_a_element in the page DOM
Done.
Related
I'm having a problem with a href target _blank on my website.
I cannot determine why it is not opening the link in a new tab, in the section: LATEST PROJECTS > Boranito skat and others, in fact, is instead opening the link in the same tab... can someone explore my website and tell me what is happening and how to solve it? I think it does have to be something with the JS but I am not able to find the problem in the Javascript code since I am a javascript rookie and cannot understand properly what the javascript code here does...
from what I have understood due to previous google and StackOverflow research and behavior watching, it is because javascript is handling the event target _blank in a different way, in fact, javascript here is being used for website change( i mean every click you do on the menu, some divs appears, some divs disappears and it is being handled by 3 js classes), already examined the JS files, clicked right-click, used element inspector> elements> event listeners>click event to see which JS files are being triggered while clicking...
see here detailed image
as you can see, two javascript archives are executing while doing the click event:
1: `jquery.pagepiling.min.js. //// 2: animsition.js`
3: scripts.js
so apparently both javascript classes are handling the events: on click, but since I am a newbie in javascript I cannot understand how to handle this or even understand what the JS does to the website ( i am just tinkering with the given template to try to understand it and to customize it better, (and hence, make the target _blank work properly( as exposed before, while clicking the link, it opens the link in the same page) so I come here for some support of you
Here is the code snippet for you to be able to locate easily inside my website the code while using the code explorer in chrome:
<a href="project-detail.html" target="_blank" class="project-box">
<div class="project-box-inner">
<h5>Boranito<br>Skat</h5>
<div class="project-category">House Design</div>
</div>
</a>
however, will leave the javascript source files here since I am requested to give all possible details here to avoid users being in the need of accessing , here are all the 3 javascript classes handling all the template events which I don't know what they do:
(since I am not able to attach the source code of the javascript classes, I will attach a link for each js file so you could check it, thanks in forward.....
Thank you in advance.
Problem
Your script (scripts.js) on line 13 toggle animsition's feature for links: linkElement: "a.project-box". This will add an handler to every a element with a project-box class. The handler is the following code (I've commented for your understanding):
function(event) {
event.preventDefault(); // prevent the default behavior for links (prevent the behavior you want)
var $self = $(this);
var url = $self.attr('href'); // get the url of the link
if (event.which === 2 || event.metaKey || event.shiftKey || navigator.platform.toUpperCase().indexOf('WIN') !== -1 && event.ctrlKey) {
// open the link in a new tab ONLY IF I clicked on it with the middle mouse button or with Ctrl/Cmd pressed
window.open(url, '_blank');
} else {
// Else do the animation and open the link in the same tab
__.out.call(_this, $self, url);
}
}
Fix
To fix your problem, you can either
Change the way you setup Animsition, be aware that it can modify other links/behaviors in your site
Change the class of your link so it is not matched as the linkElement of your Animsition's setup. For example: remove the class of the a element (it will affect the styling) and you will see that the link opens in a new tab.
Appendix
You can find the handler's code in the devtools -> your link element -> handlers -> click.
I'm developing a new Chrome extension, that return meta of a website. My problem is that I have always the same result, even if the content of web page change. To get the correct and actual meta elements I must to refresh the tab (F5).
The code of my button is :
chrome.tabs.executeScript({file: 'app/js/get_metas.js'});
And the code of my get_metas.js is :
document.head.addEventListener("DOMContentLoaded", getMeta(), true);
function getMeta() {
const meta = document.head.querySelector("meta[property='****']").getAttribute("content");
alert(meta);
}
The result is always the same, I must refresh the page with F5 to get the actual meta element.
If you enter following code in your console you will see the alert immediately:
document.head.addEventListener("DOMContentLoaded", getMeta(), true);
function getMeta() {
alert("test");
}
Reason is that the function will be called immediately. To change that remove the (), and also I believe the event is fired on the document itself (I'm not sure the event traverses down the whole document and the useCapture=true would work). So use something like:
document.addEventListener("DOMContentLoaded", getMeta, true);
It will still only fire once when document is loaded. If you need to run the function after some other event you'd need to add a listener for that event.
If you want to call your function after a change to the document (including ajax navigation) you could look into using Mutation Observers.
I am currently using analytics.js (the newer version of GA) and I am trying to track all types of events from my website, including when a user clicks on an anchor tag pointing to an external URL.
I am currently using this setup:
(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');
ga('create', 'UA-KEY-HERE', { 'alwaysSendReferrer': true, 'allowAnchor': true });
and I send the events when hitting a link like this:
$(document).on("click", ".anchor-class", function (event) {
label = //get data from anchor element here ...
ga('send', 'event', 'Link Clicked', 'Click Details', label);;
return;
}
});
and this does not send anything to GA (even though the event handler is calling the ga(send...) method).
How ever, if I use this exact technique for but with event.preventDefault(); at the beginning of the function, the event is sent and it appears in GA dashboard.
Is there some setting that I missed in order to make this work properly?
Use the hitCallback function:
$(document).on('click','a', function(event){
event.preventDefault();
var label = $(this).attr('href');
ga('send', 'event', 'Link Clicked', 'Click Details', label, {
'hitCallback': function(){
window.location.href = label;
}
});
});
As pointed out by Blexy, the correct way to do this is to use a hit callback. However, you also need to take into account that users may block Google Analytics using some privacy protection tool such as Ghostery, in which case the hit callback will never be executed. The following article explains how to implement this correctly:
http://veithen.github.io/2015/01/24/outbound-link-tracking.html
We currently had this issue and ported our analytics code off of the website and into GTM. Another issue is that we have hundreds of sites that cannot have the new code released to them to deprecate the on-page analytics, but we already had GTM on them.
We were able to find the jQuery events that were bound to the click event and write code in GTM that removes the jQuery event on those clicked buttons via the exact event handler. Then we were able to apply standard GTM click triggers and tags so we didn't get double eventing.
Assuming you can easily remove the code from the page the following should work great using GTM.
This will fire an event off to analytics when a user clicks a given element and it will make any navigation wait until the corresponding tags have finished firing first before letting the page navigate away.
GTM Implementation
This is the quick and standard way now with the newer GTM.
Pre-Setup
Variables
You will need access to the Click Element Built-In variable. You can enable this under Variables --> Configure --> Click Element.
Also enable the Page Path or Page URL Built-In variable. This is later used to help you determine which pages to run the trigger on.
It looks like you're trying to get some text off of the clicked element for the event. If so you should create a Custom JavaScript variable. This just gets the inner text of the element, but you could also get an attribute or whatever other data you're looking for at this step.
Name: Click Element - Inner Text
Variable Type: Custom JavaScript
Custom JavaScript: function() { return {{Click Element}}.innerText; }
Triggers
Create a new trigger
Trigger Type: Click - Just Links
Wait for Tags: Enable this, this is the magic you're looking for.
Max wait time: set this to what you feel is appropriate and if you can live with the possibility that you may loose some analytics for a better user experience. Imagine what the wait time may be for a 3G user on a mobile device. Is 5000ms enough, not enough, maybe 10000ms. The user probably understands their connection is bad.
Enable this trigger when all of these conditions are true:
NOTE: you should only run this on pages that you need to run it on. Google isn't very clear if there is a performance loss and their "Learn More" says nothing about it.
If you need this to run on all pages though, configure it like so:
Page Path matches RegEx .*
Otherwise you should write something like:
Page Path matches RegEx ^/path/my-page$ specific page
Page Path matches RegEx ^/path/my-page/.*
NOTE: I'm not sure if those regex are correct, I'm not sure if you'll get a path with a proceeding or appended forward slash / or if you need anchors - normally it's best to be explicit on anchors so you don't get any funny business.
This trigger fires on: Some Link Clicks
Fire this trigger when an Event occurs and all of these conditions are true. Choose one below that fits your needs and change it how you need it.
Click Element matches CSS selector a
or maybe something more specific?
Click Element matches CSS selector .container .calls-to-action a
maybe only on external links? Assuming all internal links are relevant pathing.
Click Element matches CSS selector a[href^="http"]
Tags
Create a new tag
Tag Type: Event
Category: Link Clicked
Action: Click Details
Label: {{Click Element - Inner Text}}
Google Analytics Settings: best to use these for reusability and consistency rather than manually setting them up.
Firing Triggers: The Link Clicking Trigger you created above.
Basically, I want to handle hash listening and everything in my own code, but I can't get jQM to stop listening to hash change events and generally mucking about with the URL. I've tried the code from their documentation:
$(document).bind('mobileinit', function() {
$.extend($.mobile, {
hashListeningEnabled: false,
pushStateEnabled: false,
ajaxEnabled: false,
linkBindingEnabled: false
});
});
The mobileinit event doesn't ever get fired on the first page load though (even though it seems like it should), so that doesn't work for me. What does get the code to execute is putting it in $(window).bind('load'), and I can verify in the Firebug console via $.mobile.hashListeningEnabled === false that the values are getting set properly in there - but, they don't seem to do anything! When I enter, say, <mysite>/index.html in the address bar, it loads my default page, but if I enter <mysite>/index.html#anything it just shows the jQM loading spinner and never loads anything (I presume because it's looking for a page with data-role=anything inside the file, which is its default functionality). Additionally, the pushStateEnabled override evidently isn't working either, since if I run window.location.hash = /somethingelse.html the URL bar in any supported browser shows http://<mysite>/somethingelse.html, instead of the expected http://<mysite>/index.html#somethingelse.html.
Basically, what I want is for jQuery Mobile to handle page layout and DOM manipulation, and absolutely nothing else. Is this possible?
I do not know if these are the correct properties to be setting (did not check the documentation) but I had this issue before. To solve it you need to bind the event before you include the script so this:
<script type="text/javascript">
$(document).bind('mobileinit', function() {
$.extend($.mobile, {
hashListeningEnabled: false,
pushStateEnabled: false,
ajaxEnabled: false,
linkBindingEnabled: false
});
});
</script>
<script src="//code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
The reason you must do this is that the mobileinit event fires when the jquery mobile file is loaded.
I am adding some custom tabs to a jquery ui tab control.
$("#tabs").tabs("add","#tabContent0","CLICK ME TO CHANGE PAGE",0);
$('a[href="#tabContent0"]').attr("href","javascript:window.location='http://www.google.co.uk';");
Yes this is a bit of a hack, but it is exactly what i need and provide a nice way to give links back to previous parent pages.
jquery throws the following exception: "jQuery UI Tabs: Mismatching fragment identifier."
This is thrown on the line which appears to attempt to make the tab container visible in jquery ui (exact line wont help as is minified and custom build from official site).
Obviously im just redirecting but jquery has additional code to select the tab (which doesnt exist). In internet explorer, if the user has script errors enabled they will see the exception be thrown just before the window location changes, which I just cant have happen.
I cant put try catch around this code because it is the code inside jquery ui that throws the exception.
Is there anyway I can prevent this exception being thrown or achive the same thing but a different way without having to modified jquery ui ?
Edit: I am now wondering if there is a way to override the on click event hook placed on the element by jquery .. its definitely doing something there i cant see.
Edit: I have to log off now but I have made some progress, if someone can just help me get the right URL, using this code it prevents the exception, but redirects me to "http://myurl/undefined"
$('#tabs').bind('tabsselect', function(event, ui) {
if(ui.index<2) //ignore this will change to get current tab count -1 (so the end tab is left as it is
{
window.location=$('#'+ui.tab).attr("href"); //attr href is undefined, how do i use ui.tab properly to get the right url
return false;
}
});
It works OK for me in Chrome and IE8.
I also tried this code and it worked:
$("#tabs").tabs("add","#tabContent0","CLICK ME TO CHANGE PAGE",0);
$('a[href="#tabContent0"]').click(function() {
document.location='http://www.google.co.uk/';
});
Instead of changing href attribute, I add a handler on the click event of the new tab. This will make the tab to be switched and then the location changed.
From the jQuery UI docs:
$('#example').tabs({
select: function(event, ui) {
var url = $.data(ui.tab, 'load.tabs');
if( url ) {
location.href = url;
return false;
}
return true;
}
});
Though, jQuery's tabs, uh, method, ought to support passing in a selector for the tabs and panels so you could just make things links, instead of having to kick against the pricks.