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):
- Add a
(window:scroll)
listener to your<div>
.
<div
class="wrapper"
(mouseenter)="enter()"
(mousemove)="move($event)"
(window:scroll)="onScroll($event)"
(mouseleave)="leave()"
>
- 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;
- Hold the last known "move" page offset:
lastMovePageOffset = {
x: undefined,
y: undefined,
};
...
// inside your move() function
this.lastMovePageOffset.y = window.pageYOffset;
- 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
Efficient Way to Place Orphaned Element(S) at Top/Beginning Using CSS Flexbox
What Is The Limit of Character to Use in Alt="Text" According to Wcag 2.0
Turn Off Alt Tags on Links with CSS
Can The CSS: Part Pseudo-Selector Be Used to Style Nested Web Components
Left/Right Transparent Cut Out Arrow
CSS Background to Stretch to Window Bottom
CSS: What Does The Question Mark at The End of CSS Do
Netbeans CSS Not Hinting All Properties
Why Does a Rect Require Width and Height Attribute in Firefox
Fullwidth and Multiple Columns Using Flexbox
Lesscss - Ie Gradient Filter with Variables and Lighten
Why Is Themeprovider (Material UI) Not Working for Me Here
My Less Math Operations Aren't Working in My Media Query Definitions