Jquery set div at mouse position - javascript

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.

Related

Get element within clicked pixel?

I'm not sure where to start on this, I've already Googled for a few days trying to find out how to get the element that is within a selected/clicked pixel on the page. I came across this function from a co-worker but I have no idea what it does:
function onclick(e){
var x = e.clientX,
y = e.clientY;
$("*").filter(function(){
position.left > x && position.left + width < x;
/*same for height*/;
});
}
Put simply, I need to be able to click a pixel and get the div/element that is within that pixel. It's not as simple for my app as just saying div .class for example because elements overlap one another with opacity and z-index.
The code as shown in the question won't work because variables position, width are not defined, however its basic idea is correct — loop through all the elements and compare the coordinates of a click to each element's box.
Wanted to try it myself. Moved the working demo here instead of a snippet.
Clicking wherever in the document will log the clicked element.
$(document).click(function(e) {
console.log(e.target);
});
.box {
width: 50px;
height: 50px;
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='box'></div>
You could use document.elementFromPoint(x, y); if you want to get an element by x and y coords.
See here for docs.
function onclick(e){
var x = e.clientX,
y = e.clientY,
el = document.elementFromPoint(x, y);
}
Fiddle here

How to avoid the mouseover event from the parent element when the mouse is exiting both parent and child if the parent has a border

Edit: What I want is for the nested div to not be moved when the mouse leaves both it and the parent div. I'm pretty sure it is currently moving because the border somehow extends the parent further out than the nested div. I'd like to keep the border.
Like someone once said, a demo is worth a 1000 words.
I have a div nested in a div
<div class='parent'>
<div>Check me out</div>
</div>
That has some styling
.parent {
width: 100%;
border: 1px solid black;
}
.parent div {
display: inline-block;
position: relative
}
And some accompanying Javascript
var navBar = document.querySelector('div.parent');
var navItems = navBar.querySelector('div');
var moveNav = false;
var overItems = false;
navBar.addEventListener('mouseout', function() { moveNav = false; });
navItems.addEventListener('mouseover', function() { overItems = true; });
navItems.addEventListener('mouseout', function() { overItems = false; });
navBar.addEventListener('mouseover', function() { moveNav = !overItems && true; });
navBar.addEventListener('mousemove', moveToMouse);
function moveToMouse(e) {
if(!moveNav)
return;
navItems.style.left = (e.offsetX - Math.floor((e.offsetX+navItems.offsetWidth)/navBar.offsetWidth) * (e.offsetX + navItems.offsetWidth - navBar.offsetWidth + 10)) + 'px'
}
The purpose is to keep some part of the child div under the mouse while the mouse is inside the .parent div.*
What I'd like to know is how to make the child div not be moved as the mouse exits the .parent div?
In other words, I want it to act like it does in this fiddle. The difference between the fiddles is that the first has a border around .parent and the second is borderless.
And of course, I've noticed that child div jerks around instead of moving smoothly. Suggestions as to how to avoid that are welcome but not expected.
*if there's some better way to accomplish that, please do point it out**
**don't say "use jQuery"
In the example of the div with border, I used mouseenter event instead of mouseover and it seems to be working the way you want it.
navBar.addEventListener('mouseenter', moveToMouse);

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).

Scroll event background change

I am trying to add a scroll event which will change the background of a div which also acts as the window background (it has 100% width and height). This is as far as I get. I am not so good at jquery. I have seen tutorials with click event listeners. but applying the same concept , like, returning scroll event as false, gets me nowhere. also I saw a tutorial on SO where the person suggest use of array. but I get pretty confused using arrays (mostly due to syntax).
I know about plugins like waypoints.js and skrollr.js which can be used but I need to change around 50-60 (for the illusion of a video being played when scrolled) ... but it wont be feasible.
here is the code im using:-
*
{
border: 2px solid black;
}
#frame
{
background: url('1.jpg') no-repeat;
height: 1000px;
width: 100%;
}
</style>
<script>
$(function(){
for ( i=0; i = $.scrolltop; i++)
{
$("#frame").attr('src', ''+i+'.jpg');
}
});
</script>
<body>
<div id="frame"></div>
</body>
Inside your for loop, you are setting the src attribute of #frame but it is a div not an img.
So, instead of this:
$("#frame").attr('src', ''+i+'.jpg');
Try this:
$("#frame").css('background-image', 'url(' + i + '.jpg)');
To bind a scroll event to a target element with jQuery:
$('#target').scroll(function() {
//do stuff here
});
To bind a scroll event to the window with jQuery:
$(window).scroll(function () {
//do stuff here
});
Here is the documentation for jQuery .scroll().
UPDATE:
If I understand right, here is a working demo on jsFiddle of what you want to achieve.
CSS:
html, body {
min-height: 1200px; /* for testing the scroll bar */
}
div#frame {
display: block;
position: fixed; /* Set this to fixed to lock that element on the position */
width: 300px;
height: 300px;
z-index: -1; /* Keep the bg frame at the bottom of other elements. */
}
Javascript:
$(document).ready(function() {
switchImage();
});
$(window).scroll(function () {
switchImage();
});
//using images from dummyimages.com for demonstration (300px by 300px)
var images = ["http://dummyimage.com/300x300/000000/fff",
"http://dummyimage.com/300x300/ffcc00/000",
"http://dummyimage.com/300x300/ff0000/000",
"http://dummyimage.com/300x300/ff00cc/000",
"http://dummyimage.com/300x300/ccff00/000"
];
//Gets a valid index from the image array using the scroll-y value as a factor.
function switchImage()
{
var sTop = $(window).scrollTop();
var index = sTop > 0 ? $(document).height() / sTop : 0;
index = Math.round(index) % images.length;
//console.log(index);
$("#frame").css('background-image', 'url(' + images[index] + ')');
}
HTML:
<div id="frame"></div>
Further Suggestions:
I suggest you change the background-image of the body, instead of the div. But, if you have to use a div for this; then you better add a resize event-istener to the window and set/update the height of that div with every resize. The reason is; height:100% does not work as expected in any browser.
I've done this before myself and if I were you I wouldn't use the image as a background, instead use a normal "img" tag prepend it to the top of your page use some css to ensure it stays in the back under all of the other elements. This way you could manipulate the size of the image to fit screen width better. I ran into a lot of issues trying to get the background to size correctly.
Html markup:
<body>
<img src="1.jpg" id="img" />
</body>
Script code:
$(function(){
var topPage = 0, count = 0;
$(window).scroll( function() {
topPage = $(document).scrollTop();
if(topPage > 200) {
// function goes here
$('img').attr('src', ++count +'.jpg');
}
});
});
I'm not totally sure if this is what you're trying to do but basically, when the window is scrolled, you assign the value of the distance to the top of the page, then you can run an if statement to see if you are a certain point. After that just simply change run the function you would like to run.
If you want to supply a range you want the image to change from do something like this, so what will happen is this will allow you to run a function only between the specificied range between 200 and 400 which is the distance from the top of the page.
$(function(){
var topPage = 0, count = 0;
$(window).scroll( function() {
topPage = $(document).scrollTop();
if(topPage > 200 && topPage < 400) {
// function goes here
$('#img').attr('src', ++count +'.jpg');
}
});
});

Using jQuery .on() when selector element is obscured by another element

I'm trying to get my jQuery event callback to trigger correctly, but I can't seem to get around the fact the element I am interested in not receiving the event because of another element that covers it on the page. I can summarise it as follows (I've styled the elements so they show up in a jsfiddle):
<div id='mydiv'>
<div style="border: 1px solid; border-color: red; position: absolute; left: 0px; top: 0px; width: 200px; height: 200px; z-index: 100">Hello</div>
<canvas style="border: 1px solid; border-color: yellow; position: absolute; left: 50px; top: 50px; width: 150px; height: 150px"></canvas>
</div>​
With the segment above, if I try to listen to mouse clicks on the <canvas>, the event never gets called:
$('#mydiv').on('mousedown', 'canvas', this, function(ev) {
console.log(ev.target);
});
However, if I modify my event handler to listen to the <div> element instead, the callback is triggered as expected:
$('#mydiv').on('mousedown', 'div', this, function(ev) {
console.log(ev.target);
});
How can I coerce my <canvas> to receive events, whilst leaving the offending <div> block in the fore-front?
This should be the simplest solution, as already proposed:
http://jsfiddle.net/CUJ68/4/
$('canvas').on('mousedown', function(ev) {
console.log(ev.target);
});
$('ul').on('mousedown', function(ev){
$('canvas').mousedown();
});
if you need the original eventdata:
$('canvas').bind('mousedown', function(ev, parentEV) {
if(parentEV){
console.log(parentEV);
alert("Canvas INdirectly clicked!");
}else{
console.log(ev);
alert("Canvas directly clicked!");
}
});
$('ul').on('mousedown', function(ev){
$('canvas').trigger('mousedown', ev);
});
You can't. Objects on top get the click events. That's how the DOM works.
If you want to handle that click event, you will need to handle in the object that is on top or use bubbling and handle it in a parent object. You can handle it in the top object and "forward" it to the other object if you want by triggering a click on that other object or by just calling a click handler directly.
Or, you can move the canvas element above the ul by setting it's z-index to a higher value and it will then get the click event.
Or, you can make a new transparent canvas object that is on top that gets the event, leaving the other two objects where they are for the desired visual effect.
You can bind the element to the closest common parent, and check whether the X and Y coordinates of the mouse are within the range of the canvas.
In the example below, I have cached the dimensions (height and width) of the canvas, because I assume these to be constant. Move this inside the function if the dimensions are not constant.
I use the .offset() method to calculate the real X and Y coordinates of the <canvas>s top-left corner. I calculate the coordinates of the bottom-right corner by adding the values of outerWidth() and .outerHeight().
Basic demo: http://jsfiddle.net/75qbX/2/
var $canvas = $('canvas'), /* jQuery reference to the <canvas> */
$canvasWidth = $canvas.outerWidth(), /* assuming height and width to be constant */
$canvasHeight = $canvas.outerHeight();
function isCanvasClicked(x, y, target) {
if (target.tagName === 'CANVAS') return true;
var offset = $canvas.offset(),
left = offset.left,
top = offset.top;
return x >= left && x <= left + $canvasWidth &&
y >= top && y <= top + $canvasHeight;
}
$('#mydiv').on('mousedown', '*', this, function(ev) {
if (isCanvasClicked(ev.pageX, ev.pageY, ev.target)) {
$canvas.fadeOut().fadeIn();
}
});
Here you have a solution that consists in capture click event on above element, and triggering the event on the other: registering clicks on an element that is under another element

Categories

Resources