Track click coordinates of a page, including iframes - javascript

I'm working on creating a basic heatmap for a site using the following:
$(document).ready(function() {
$(document).on('mousedown', function(evt) {
console.log('X: '+ evt.pageX);
console.log('Y: '+ evt.pageY);
$.post('clickmap.php', {
x:evt.pageX,
y:evt.pageY
});
});
});'
fiddle: http://jsfiddle.net/8jjo7q5y/
Works great, besides when also including click coordinates of a click over an iframe. It appears that this is possible when using CrazyEgg and I've personally tested CrazyEgg by clicking a Google Ad (housed inside an iframe) and the heatmap data returned properly to CrazyEgg.
Any ideas on how to accomplish click tracking an entire page body with iframes included.

HTML:
<div></div>
<iframe src="http://www.jsfiddle.net"></iframe>
CSS:
div {
position: absolute;
width: 300px;
height: 150px;
z-index: 2;
}
iframe {
position: absolute;
width: 300px;
height: 150px;
z-index: 1;
}
JavaScript:
$(window).click(function(e) {
console.log("x:" + e.pageX + ", y:" + e.pageY);
});
FIDDLE http://jsfiddle.net/a9owgqrv/

If the iframe content doesn't need any user interaction at all (clicking, scrolling, etc.), you could place a transparent div on top of it, which would capture the mouse clicks. Otherwise, I think you're out of luck.
(Thanks to #Andranik for showing that the div doesn't actually need transparent (opacity) styling.)

short answer for iframes pointing to different domain without making use of proxys or putting a div over the iframe that causes not to be able to click in the iframe: no
nevertheless here is some bloody attempt
it uses the blur event that gets fired when clicked "outside" of window e.g inside iframe, i added mousemove event to have the coordinates where user clicks into iframe, but this only works once, to work again the user must click outside the iframe and inside again, but its better than nothing ;-)
$(document).ready(function() {
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
$(window).blur( function(e){
console.log("clicked on iframe")
console.log('X: '+ mouse.x);
console.log('Y: '+ mouse.y);
});
$(document).on('mousedown', function(evt) {
console.log('X: '+ evt.pageX);
console.log('Y: '+ evt.pageY);
//$.post('clickmap.php', {
//x:evt.pageX,
//y:evt.pageY
//});
});
});
http://jsfiddle.net/8jjo7q5y/1/

Related

Jquery set div at mouse position

I want to have an div under my mouse at all times, this div I want to use to display tool-tips.
This is the code i'm trying to use. But this code gives an error:
" Cannot read property 'pageX' of undefined"
My question is why is pageX undefined, and how do I fix this problem?
$( document ).ready(function() {
AppentMouse(); //Setup div that is used for mouse icon
window.setInterval(function(){
SetMouse(); //Set div that is used for mouse icon at mouse location
}, 5);
});
function AppentMouse(){
$( 'Body' ).append( "<div id='Mouse'>Mouse</div>");
}
function SetMouse(){
var e = window.event || e;
var left = e.pageX + "px";
var top = e.clientY + "px";
var div = document.getElementById('Mouse');
div.style.left = left;
div.style.top = top;
}
Considering this is your html code:
<body>
<div>Your content</div>
</body>
And you have these styles for the div:
div {
position: absolute;
border: solid 1px #fc0;
}
Using jQuery, attach mousemove event listener to the document and make the div to have top and left styles changed on every move:
$(document).on('mousemove', function(e){
$('div').css('top', e.pageY);
$('div').css('left', e.pageX);
});
See this JSFiddle
EDIT:
Considering your code, variable e is undefined. And the error says that an undefined value does not have a pageX property.
That is because you need an mouse event (for your case) to have object event defined. And that object is received by the event listener that we add in the code that I provided.
As for your code, you will have to bind the event to the div.
An easy way to do this would be to not dynamically generate the div, just show and hide it. (As in my example). This is faster as well.
Alternatively, each time you generate the div, define and trigger the set mouse event from within the function that generates it.
Providing an alternate way of doing this:
Firstly, the HTML. Add the following anywhere inside the body.
<div id="tooltip"></div>
Now the CSS (add more to make it look pretty):
#tooltip {
position: absolute;
display: inline-block;
opacity: 0;
}
Make a class called tips and have all elements that you wish to provide tool tips for, belong to that class.
And then the jQuery:
//For every element in ".tips" have an attribute "tooltiptext"
$('.tips').mouseenter(function(e) {
$("#tooltip").css("left", e.pageX + 10);
$("#tooltip").css("top", e.pageY+ 10);
$("#tooltip").html($(this).attr("tooltiptext"));
$("#tooltop").show();
});
$('.tips').mouseout(function() {
$("#tooltip").hide();
});
Do tell me if this works.

how to create a popup next to the mouse according to a container div

I'm trying to display a div when mouse is over an element but the div is always inside the container div. Example (hover over any model at the bottom of this page) https://3dexport.com/
I've tried to get mouse position in the page and the mouse position inside the div but didn't work. Thanks in advance.
This is the main code I've used to display and hide a big div but the hidden process is not working though the alert is displayed (the black div is hidden by default)
$(".homeModelItem").mouseenter(function(){
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY;
console.log(mouse.x);
if(mouse.x<400 && mouse.x>0){
$(".black").css({"left":"200px","display":"block"});
}
});
});
$(".homeModelItem").mouseout(function(){
alert("xxx");
$(".black").css({"display":"none","left":"0"});
});
You're adding a new mousemove listener every time the mouse enters a .homeModelItem. In that handler you set display: block for .black, and this will override the hiding in mouseleave handler.
It looks like you want to position .black related to the currently hovered .homeModelItem. You can do it for example like this:
$(".homeModelItem").mouseenter(function (e) {
$(e.target).append($('.black')); // Move the .black to the target element
$(".black").css({
display: "block"
});
});
$(".homeModelItem").mouseleave(function (e) {
$(".black").css({
display: "none"
});
});
Addition to .homeModelItem CSS:
position: relative;
and to .black CSS:
left: 100px;
top: 0px;
z-index: 100;
A live demo at jsFiddle.
If you'll need the mousemove somewhere, you can add it, but outside of any event handler (unles you will remove it in another handler).

Move around image like a map

I'm trying to make a online map for a game. But I have problems with moving around the map...
This code works only if I set the container (div with map image)
to height: 6000px; and width:6000px;
But I must use height: 100%; width: 100%; to get "background-size: cover;" working to have the map "zoomed out"/"fit to the screen" for the best look imo
$(document).ready(function()
{
var
clicked,
clickY
;
$(document).on(
{
'mousemove': function(e) {clicked && updateScrollPos(e);},
'mousedown': function(e)
{
clicked = true;
clickY = e.pageY;
clickX = e.pageX;
},
'mouseup': function()
{
clicked = false;
$('html').css('cursor', 'auto');
}
});
var updateScrollPos = function(e)
{
$('html').css('cursor', 'all-scroll');
$(window).scrollTop($(window).scrollTop() + (clickY - e.pageY));
$(window).scrollLeft($(window).scrollLeft() + (clickX - e.pageX));
}
});
This is currently how it looks: http://5.231.49.167/map/
Use "google inspect element" to test out what I mean. (Change the 100%'s to 6000px in #container)
The problem is that when you set a 100% height value it take the longitud from the parent container. If the conatiner is the body tag it ajustment to the size of the content it self that could be very samll. You need to set up the size to a specifycally size you can use the window size for example.

Emulate Frameset Separator Behavior

The HTML5 current specification removed the <frameset> tag.
There is a nice feature of <frameset> which is not easy to reproduce without it:
In a frameset, you can change the position of the line separating the frames with the mouse.
How would I provide the same functionality with with using DIVs in JavaScript?
I've come across the following which demonstrates the behavior I'm looking for. However I would like to avoid using JQuery, even though using jQuery should be the preferred way.
After looking at your example fiddle, I can say that this is actually quite easy without jQuery.
All the functions there are just simple innerHTML and style manipulation, and event subscription.
A direct rewrite of that code without jQuery would be:
var i = 0;
document.getElementById("dragbar").onmousedown = function (e) {
e.preventDefault();
document.getElementById("mousestatus").innerHTML = "mousedown" + i++;
window.onmousemove = function (e) {
document.getElementById("position").innerHTML = e.pageX + ', ' + e.pageY;
document.getElementById("sidebar").style.width = e.pageX + 2 + "px";
document.getElementById("main").style.left = e.pageX + 2 + "px";
};
console.log("leaving mouseDown");
};
window.onmouseup = function (e) {
document.getElementById("clickevent").innerHTML = 'in another mouseUp event' + i++;
window.onmousemove = null;
};
So here is the same fiddle with pure JS.
EDIT: As #BenjaminGruenbaum pointed out, overriding the on* properties on a DOM element is not the same as specifying a new event handler.
Overriding properties like onmouseup, onload, onclick on DOM elements is the "old" way, and therefore it was supported in even the stone age of JS. My code above was written like that.
Nowadays the standard way of adding and removing event handlers are addEventListener and removeEventListener. They are not supported in old IE (but this can be worked around).
It let's you attach unlimited number of listeners to the same event and they will not interfere with each other.
So the same functionality can be achieved by:
var i = 0;
function dragBarMouseDown(e) {
e.preventDefault();
document.getElementById("mousestatus").innerHTML = "mousedown" + i++;
window.addEventListener("mousemove", windowMouseMove, false);
console.log("leaving mouseDown");
}
function windowMouseMove(e) {
document.getElementById("position").innerHTML = e.pageX + ', ' + e.pageY;
document.getElementById("sidebar").style.width = e.pageX + 2 + "px";
document.getElementById("main").style.left = e.pageX + 2 + "px";
}
function windowMouseUp(e) {
document.getElementById("clickevent").innerHTML = 'in another mouseUp event' + i++;
window.removeEventListener("mousemove", windowMouseMove, false);
}
document.getElementById("dragbar").addEventListener("mousedown", dragBarMouseDown, false);
window.addEventListener("mouseup", windowMouseUp, false);
Fiddle.
Note that in this case my functions are not anonymous, so a self executing function for scoping would make sense here, if you are not already in function scope.
Here is a horizontal version of #SoonDead's pure and simple answer with a bottom shelf and a horizontal divider.
The result should look like this:
fiddle here
var i = 0;
function dragBarMouseDown(e) {
e.preventDefault();
document.getElementById("mousestatus").innerHTML = "mousedown" + i++;
window.addEventListener("mousemove", windowMouseMove, false);
console.log("leaving mouseDown");
}
function windowMouseMove(e) {
document.getElementById("position").innerHTML = e.pageX + ', ' + e.pageY;
//document.getElementById("main").style.height = e.pageY + 2 + "px";
document.getElementById("dragbar").style.top = e.pageY + 2 + "px";
document.getElementById("bottomshelf").style.top = e.pageY + 17 + "px";
}
function windowMouseUp(e) {
document.getElementById("clickevent").innerHTML = 'in another mouseUp event' + i++;
window.removeEventListener("mousemove", windowMouseMove, false);
}
document.getElementById("dragbar").addEventListener("mousedown", dragBarMouseDown, false);
window.addEventListener("mouseup", windowMouseUp, false);
body, html {
width:100%;
height:100%;
padding:0;
margin:0;
}
#header {
background-color: wheat;
width:100%;
height: 50px;
}
#main {
background-color: BurlyWood;
float: top;
position: absolute;
top:50px;
width:100%;
bottom: 38px;
overflow-y: hidden;
}
#dragbar {
background-color:grey;
width:100%;
float: top;
top:120px;
bottom:0px;
height: 15px;
cursor: row-resize;
position:absolute;
}
#bottomshelf {
background-color: IndianRed;
width:100%;
float: top;
position: absolute;
top:135px;
bottom: 38px;
}
#footer {
background-color: PaleGoldenRod;
width:100%;
height: 38px;
bottom:0;
position:absolute;
}
<div id="header">header <span id="mousestatus"></span>
<span id="clickevent"></span>
</div>
<div id="main">main area:
The bottom shelf will slide over this.
</div>
<div id="dragbar">drag me up or down</div>
<div id="bottomshelf">
<span id="position"></span>
bottom shelf</div>
<div id="footer">footer</div>
I don't have enough reputation to add comment to "SoonDead"s solutions, so I have to do this. :-( The solutions are great and worked out for me, except for IE8
1) The line
e.preventDefault();
has two issues for IE8
the argument "e"vent is not defined.
preventDefault method is not defined for e
So the above line is replaced with:
e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue=false;
The above stopped the errors (and I stopped here since I don't really care about IE8 but do not want error boxes popping up for the hapless user). So yes, in my app IE8 users cannot resize.
However, I did chase it down a little, and found these issues:
Code flow did not enter the onmousemove function
The e.pageX will have to be replaced by e.clientX or e.screenX (depending on your case) since I could not see pageX as a property in the IE8 debugger.
Here are some options discussed on SO.
My personal recommendation would be jQuery Resizable.
As BenjaminGruenbaum said in a comment, jQuery is JavaScript. If you don't want to load the full jQuery library, you'll need to find which parts of the jQuery library you need and pull out the source JavaScript to use. It's certainly doable.

Animating an Image to Position of Mouse Click

I am attempting to use JQuery to animate an image to the point where I click my mouse on a div.
The div of the html has an id of "stage" and the image has an id of "player". I have successfully gotten the header to update when the user clicks on the stage, but once I add in the other JQuery to have the image move to my mouseclick on the stage, neither works.
Perhaps its something obvious since I'm new at JQuery but hopefully someone can spot my error.
Here's my code for the JQuery:
$(document).ready(function(){
//alert('It works');
$('#stage').click(function() {
$('#header').html('Image is moving!');
});
$('#stage').click(function(e){
$('#player').animate({
top: e.pageY + 'px';
left: e.pageX + 'px';
}, 800);
});
});
In summary, when someone clicks in the stage div the header above it should change, and the image should move to where the person clicked on the stage.
Two things:
$('#player').animate({
top: e.pageY + 'px';
left: e.pageX + 'px';
}, 800);
Has syntax errors. It should be:
$('#player').animate({
top: e.pageY,
left: e.pageX
}, 800);
Notice I left off 'px' since it isn't necessary.
You can see it working here: http://jsfiddle.net/VBzUw/

Categories

Resources