This is the question:
I have an iframe that displays any web page (not necessarily developed by me).
On this page may be attached events (which presumably I do not know).
How can I dynamically intercepting these events and store them for later replicate?
For example:
suppose that when the mouse moves over a certain div it changes color.
I would like to make sure that when you trigger the event that would change color to the div it is "registered" with all a series of information that will allow me (without user interaction) to replicate it at a later time.
Ideas for both the recording and subsequent replication?
The short answer is: you cannot.
You cannot access the document object of "any web page" with JavaScript on your page if it is on a different domain, which I assume if you say "any web page", because of the Same Origin Policy. You would need the website in the IFRAME to cooperate with your script to achieve this, which will not happen with "any web page".
IFRAME on same domain
If your web page is on the same domain then you can access the events of the IFRAMEs body element by adding a listener for every event you want to catch like described here. This is possible for all events that bubble up to the body. So if you have Events that are prevented from bubbling upwards to the body, they will not be catched with this solution.
jQuery('#website body').on('click mouseover mouseout', function(event) {
console.log(event.type);
});
Assuming you have an IFRAME with the id website you can catch the events you wish by listing them separated with spaces as above. The example catches click, mousover and mouseout.
Maybe this is closer to what you want?
Add event handlers to your divs. For your example you could use
$('#div').mouseover(function(e) { ... })
or
('#div').on('mouseover', function(e) { ... })
For 'replication', you'd have to store information about past events in some object. You could even store the event object itself.
Related
I have created a few variables for custom dimension on pageviews.
Pageview trigger: windowload or history change
The data is being pushed through, but it's only getting previous pages'
for example,
page/1 div class "page date" is 25th Jul, I would get undefined, but
when I click onto page/2, i would get the page/1's "page date"
function() {
return window.document.getElementsByClassName('page date')[0].innerText;
}
It seems that the history event is triggered before the corresponding page content is loaded into the DOM. This is nothing you can blame GTM for (GTM sees a history change, inspects the DOM, and grabs whatever it finds there, and that's the normal/expected behaviour).
Your solutions:
Make sure content is updated in DOM BEFORE the history event is triggered: this is something to sort out on the application side, and that may not be easily changed (if you use a framework like react it's probably best if you don't start hacking its core behaviour).
Delay the history event triggers: have a look at this solution which describes how to achieve this. Please note that solutions based on delays are never 100% reliable because there's a race condition between your delay and the loading of content, and you don't know for sure who will come first (and increasing the delay too much can cause the side effect of users changing pages in quick successions before analytics had a change to capture them).
Detect DOM changes: a more robust alternative would be to monitor the DOM for a particular element that is unique to each page (eg a <meta> element with the page ID or URL). You could use a tag to initiate the monitoring of this element when you receive the history change, and when the element actually changes it means the DOM has been updated, and you could fire your own trigger. This could be done via the MutationObserver or using a setInterval/setTimeout loop to check manually. However if the DOM is changed in several phases (blocks by blocks) this would not work (your <meta> element would have changed but not the div you're looking for), requiring you to start monitoring on a per-element or per-block level, which will be quite some work.
Push a dataLayer from your application: this would be my preferred option. I would hook into the logic of your application (you should be able to extend the routing method or the app framework should give you event listeners you can bind a custom function of yours with in which you can tell GTM that the page has been changed (eg dataLayer.push({'event': 'page_changed'});)
I'd like to make a tool which allows to process data picked from an iframed page.
Something similar to this:
http://jsfiddle.net/jr6uG/4/
I stopped on events (hover, click, etc.).
Is it possible to do it my way? Is there a better way?
I need somthing like this:
$('iframe body *').bind('click', function(event){
console.log('clicked', this);
});
The iframe runs a separate DOM, meaning there's no interoperability between DOM objects in the original document and the iframe document.
You'd have to do this over the network. A little like JSFiddle captures console logs from within the iframe generated to the console in the document you're viewing.
To process data picked from an iframed page, as you're intending to do, you'd be looking to direct any page that you're trying to process through a bespoke proxy, where you could inject your own scripts, for example, to create an alert when an element is clicked.
as the title says, i would like to know if theres any possibility in javascript (jquery) to check if there is any action in the document, and if not. something like a screensaver should pop up!
if someone is on the page and looks here, looks there and after a while he doesnt do anything, the mouse (or touch finger) stands still, i want to say the document after a minute without activity...
function noactivity() { //after 60000ms start something here }
i want that global for the whole document!
thanks ted
It can be done relatively simply in jquery using:
setTimeout();
http://jsfiddle.net/bernie1227/hNkTy/1/
I had this issue a while back while I was working on an iframe resizing issue. What I wanted was to tell the parent page whenever there is a change in height of the document.
What I found was that jQuery does not give such facility directly. The main reason for this is that there are too many activities happening to DOM which are not visible, when you are watching it (bind). You could however watch for a specific property like mouse moving on a document.
$(document).mousemove(function(e){
console.log(e.pageY);
console.log(e.pageX);
});
But then again that does not at all mean that the user is interacting with your page. That merely signifies that the user is on your page and his mouse is moving. The user might also be not moving the mouse and merely using his keyboard to interact with your page. So now you would have to watch for keyboard interaction aswell.
$(document).keyup(function(e){
console.log('active');
});
Using these you could create a countdown function which checks for a flag after a set interval of time. You could set the flag if user makes an activity. And after a set amount of time that function the 'noactivity()' function id the flag has not been set.
Another approach to watching the document activity could be you watching the DOM subtree being modified.
jQuery(document).bind('DOMSubtreeModified', function() {
console.log('active');
});
This works for Chrome/FireFox/IE8+ but not on Opera (any version). The main reason being that the operation is too heavy on your browser's resources. And I would discourage using this approach because listening for DOM mutation events may harm performance and the relevant W3C working groups are trying to find a better way to do this and deprecate DOM mutation events for this reason - it's hard or impossible to make a good and performant implementation.
I am not saying that the other options that I mentioned above are good either. They are also expensive operations if you are watching document and should be avoided. Another issue with those options is that the iframe content is not particularly the part of your document and these options will not work if user is interacting with iframe content.
So the conclusion is that W3C did not yet finalize a cheap way where user can watch changes in document subtree.
I have an image map that uses a third party script(mapper.netzgesta.de) to highlight the different areas of the image map. Basically the script adds onmouseover events to the areas via javascript. How can i have the areas already on when the page is loaded as opposed to any user based event?
I already have onload events and cant interfere with those. All the other events depend on user interaction. The cms i am using currently doesnt work with jquery.
any suggestions?
You can try to simulate the mouse over events.
Simulate Mouse Over in Vimperator plugin
You can also append to onload so you don't lose your current event handlers.
window.attachEvent("onload", function(){alert('Welcome')});
After further study and a great amount of help from the developer I was given an answer. The product i was using (mapper.js) does not support this. The reply was use another product of his called mapzoom.js. The preselection will allow the specified areas to stay on when loaded and not be dependent on an user interaction like onmouseover.
I have a website, where I allow other developers to host content.
My aim is to log clicks on every hyperlink (even the content that is hosted by other developers) ,which exists on the page.
My initial approach was as follows:
$('a').click(function(event)
{
//do my logging
return true;
}
);
Now with the above approach , I am facing the following issues:
Developers may have images inside the anchor link, so the events target is an image rather than href
Many developers have their own way of handling an href click , using an onclick event rather than a simply href='' attr
Some developers add their custom attr , to the tag, and have custom functions to handle the clicks
so basically , the issue is , there is a huge variety of anchor tags available, and logging clicks is not as simple.
Many cases allowed me to log the data I wanted, but a few cases , broke the code badly.
My aim to post on this forum was:
to discuss what is the right approach to do hyperlink clicks logging in a dynamic environment
is there a plugin out there , which allows a functionality like this.
I know facebook and google have this , but they have a totol control, on what is being hosted in their environments.
Any help is greatly appreciated.
Adding a click handler to every link is not a good idea. You should make use of event delegation (which will only attach one event handler at the root of the document):
$(document).delegate('a', 'click', function(event) {
// logging
});
Update (17.12.2011):
Since jQuery 1.7, one would use .on() [docs]:
$(document).on('click', 'a', function(event) {
// logging
});
Regarding your problems:
Developers may have images inside the anchor link, so the events target is an image rather than href
Events bubble up as long as propagation is not canceled. It depends on what you want to log. With delegate the event.target property will point to the image, but this (inside the handler) will point to the a element.
So you should have no problems here (example: http://jsfiddle.net/cR4DE/).
But that also means to you will miss clicks if the developers cancel the propagation.
(Side note: You could solve this letting the event handler fire in the capturing phase, but IE does not support this (hence jQuery does not either).)
Many developers have their own way of handling an href click , using an onclick event rather than a simply href='' attr
This will not touch existing event handlers.
Some developers add their custom attr , to the tag, and have custom functions to handle the clicks
Not sure what you mean here.
It also depends on how the other content is included. E.g. the above code won't track clicks in iframes.
In your logging code you should check for the bad cases and deal accordingly.
For example in your first case i you get the image and walk the dom up until i would find an a tag and log the href from there.
There will be some cases in which you will not be able to do the logging but if they are small compared with the cases you can do that you will be fine :).