Angular 2 - Jquery | Adding Styles (Top/Left) with a Mouse Position

Angular 2 - Jquery | Adding styles (top/left) with a mouse position

[style.left.px]="xPos" [style.top.px]="yPos"

Angular: following mouse position on scroll

According to this answer, we cannot get mouse current position on scroll we can just get how much it scrolled relative to last position.

For your problem, this can be realized as follows (here is your updated stackblitz):

  1. Add a (window:scroll) listener to your <div>.
<div
class="wrapper"
(mouseenter)="enter()"
(mousemove)="move($event)"
(window:scroll)="onScroll($event)"
(mouseleave)="leave()"
>

  1. Hold the last position, e.g.:
lastPosition = {
x: undefined,
y: undefined,
};

...

// inside your move() function
this.lastPosition.x = e.pageX;
this.lastPosition.y = e.pageY;

  1. Hold the last known "move" page offset:
lastMovePageOffset = {
x: undefined,
y: undefined,
};

...

// inside your move() function
this.lastMovePageOffset.y = window.pageYOffset;

  1. Use the difference of the current scroll position and the last known page "move" page offset to calculate the new position:
onScroll(e: any) {
if (this.lastPosition.y !== undefined) {
let pageOffsetY = 0;
if (this.lastMovePageOffset.y !== undefined) {
pageOffsetY = window.pageYOffset - this.lastMovePageOffset.y;
}
this.tooltip.style.top = this.lastPosition.y + pageOffsetY + 'px';
}
}

This can be handled similarly with the x-Position. The solution works as soon as the cursor is moved once before scrolling (caused by the general problem described in the first sentence).

Good luck!

How do I position a div relative to the mouse pointer using jQuery?

var mouseX;
var mouseY;
$(document).mousemove( function(e) {
mouseX = e.pageX;
mouseY = e.pageY;
});
$(".classForHoverEffect").mouseover(function(){
$('#DivToShow').css({'top':mouseY,'left':mouseX}).fadeIn('slow');
});

the function above will make the DIV appear over the link wherever that may be on the page. It will fade in slowly when the link is hovered. You could also use .hover() instead. From there the DIV will stay, so if you would like the DIV to disappear when the mouse moves away, then,

$(".classForHoverEffect").mouseout(function(){
$('#DivToShow').fadeOut('slow');
});

If you DIV is already positioned, you can simply use

$('.classForHoverEffect').hover(function(){
$('#DivToShow').fadeIn('slow');
});

Also, keep in mind, your DIV style needs to be set to display:none; in order for it to fadeIn or show.

AngularJS: Have element follow the cursor

JSFiddle

HTML - added the $event parameter to the showPopover function

<p ng-mouseenter="showPopover($event)" ng-mouseleave="showPopover()">Square 1</p>
<p ng-mouseenter="showPopover($event)" ng-mouseleave="showPopover()">Square 2</p>
<p ng-mouseenter="showPopover($event)" ng-mouseleave="showPopover()">Square 3</p>

and with ng-style you can change the position Source

<div class="pop-availability" ng-show="popover"
ng-style="{left:field.left,
top:field.top}" >

JavaScript

//Method to show popover
$scope.showPopover = function(mouseEvent) {
if (!mouseEvent)
{
mouseEvent = window.event;
}
$scope.field.left = mouseEvent.pageX + 'px';
$scope.field.top = mouseEvent.pageY+ 'px';
return $scope.popover = !$scope.popover;
};

CSS Changes - added position:absolute

.pop-availability {
border-radius: 8px;
box-shadow: 0 0 10px 0 #969696;
display: inline-block;
min-width: 375px;
position:absolute;
}

How do I get the offset().top value of an element without using jQuery?

use getBoundingClientRect if $el is the actual DOM object:

var top = $el.getBoundingClientRect().top;

JSFiddle

Fiddle will show that this will get the same value that jquery's offset top will give you

Edit: as mentioned in comments this does not account for scrolled content, below is the code that jQuery uses

https://github.com/jquery/jquery/blob/master/src/offset.js (5/13/2015)

offset: function( options ) {
//...

var docElem, win, rect, doc,
elem = this[ 0 ];

if ( !elem ) {
return;
}

rect = elem.getBoundingClientRect();

// Make sure element is not hidden (display: none) or disconnected
if ( rect.width || rect.height || elem.getClientRects().length ) {
doc = elem.ownerDocument;
win = getWindow( doc );
docElem = doc.documentElement;

return {
top: rect.top + win.pageYOffset - docElem.clientTop,
left: rect.left + win.pageXOffset - docElem.clientLeft
};
}
}

Find mouse position relative to element

For people using JQuery:

Sometimes, when you have nested elements, one of them with the event attached to it, it can be confusing to understand what your browser sees as the parent. Here, you can specify which parent.

You take the mouse position, and then subtract it from the parent element's offset position.

var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;

If you're trying to get the mouse position on a page inside a scrolling pane:

var x = (evt.pageX - $('#element').offset().left) + self.frame.scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + self.frame.scrollTop();

Or the position relative to the page:

var x = (evt.pageX - $('#element').offset().left) + $(window).scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();

Note the following performance optimisation:

var offset = $('#element').offset();
// Then refer to
var x = evt.pageX - offset.left;

In this way, JQuery does not have to look up #element for each line.

Update

There is a newer, JavaScript-only version in an answer by @anytimecoder -- see also browser support for getBoundingClientRect().

Angular 5 Scroll to top on every Route click

There are some solutions, make sure to check them all :)


Option1:

The router outlet will emit the activate event any time a new component is being instantiated, so we could use (activate) to scroll (for example) to the top:

app.component.html

<router-outlet (activate)="onActivate($event)"></router-outlet>

app.component.ts

onActivate(event) {
// window.scroll(0,0);

window.scroll({
top: 0,
left: 0,
behavior: 'smooth'
});

//or document.body.scrollTop = 0;
//or document.querySelector('body').scrollTo(0,0)
...
}

As the smooth scroll is not implemented well in Safari, use, for exemple, this solution for a smooth scroll:

onActivate(event) {
let scrollToTop = window.setInterval(() => {
let pos = window.pageYOffset;
if (pos > 0) {
window.scrollTo(0, pos - 20); // how far to scroll on each step
} else {
window.clearInterval(scrollToTop);
}
}, 16);
}

If you wish to be selective, say not every component should trigger the scrolling, you can check it in an if statement like this:

onActivate(e) {
if (e.constructor.name)==="login"{ // for example
window.scroll(0,0);
}
}

Option2:

Since Angular6.1, we can also use { scrollPositionRestoration: 'enabled' } on eagerly loaded modules and it will be applied to all routes:

RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })

It will also do the smooth scrolling, already. However this has the inconvenient for doing it on every routing.


Option3:

An other solution is to do the top scrolling on router animation. Add this in every transition where you want to scroll to the top:

query(':enter, :leave', style({ position: 'fixed' }), { optional: true }) 


Related Topics



Leave a reply



Submit