Detecting the position of an element in the DOM being moved - javascript

I have been trying to find a working example of this but I think I am missing something very basic. I have a function to move the position of an element that is relative, I want to stop the element moving once the left element goes past 300px. I am using this code to move the element:
function tele_right(){
$(".tele-wrapper").animate({"left": "+=15px"}, 25);
}
I wanted to use something like this code to do something once in the DOM the left position hits 300:
if($('.tele-wrapper').css('left') == '300px') {
console.log('yay');
}
Any help would be much appreciated.

you can simply achieve this using offset() and a setTimeout: DEMO
function tele_right(){
var left=$(".tele-wrapper").offset().left;
if(left<300){
$(".tele-wrapper").animate({"left": "+=15px"}, 25);
setTimeout(tele_right,25);
}
else{
alert('passed 300 pixels');
}
}
tele_right();

If I was you, I'd just set the left property of your element to 0, then would do the animation all the way to 300px and define its duration to the desired value as follows:
$(document).ready(function() {
$(".tele-wrapper").animate({"left": "300px"}, 1000);
// 1000ms = 1 second, set this to whatever you like
});
.tele-wrapper {
position:relative;
left:0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tele-wrapper">tele-wrapper</div>

Related

How to change the cursor on an image on mouse move

In an Angular 7 application, I'm trying to implement left and right arrows for an image slideshow. If the mouse is hovered on the left half of the image, it should show a left arrow, and a right arrow on the right half. Clicking the image then will take the user to either the next or previous image in the array of images. Something like this: https://wells-demo.squarespace.com/human-nature-wells/uml9t64gkm48jijkt8y6slmtd0jush
<img src="url" (click)="navigate()">
I tried to set up something with #HostListener, but can't quite figure out how to progress.
urls = [url1, url2, url3, ....url10];
currIndex = 2;
url = urls[currIndex];
#HostListener('mousemove', ['$event'])
onMouseMove(event: MouseEvent) {
//console.log(event.pageX);
//console.log(this.el.nativeElement.offsetLeft);
//not completely sure what to do here...
}
navigate() {
if (leftHalf) { //how to figure this out?
prevImage();
} else {
nextImage();
}
nextImage() {
this.url = this.urls[this.currIndex + 1];
}
prevImage() {
this.url = this.urls[this.currIndex - 1]
}
1) How do I change the mouse cursor to a left arrow based on the position?
2) How to detect if left half or right half was clicked on?
Appreciate any help I can get on this!
Make use of offsetWidth of the element and offsetX of the mousemove event.
if(event.offsetX > element.offsetWidth / 2) {
// right half
} else {
// left half
}
To change the pointer's you have to make use of add/remove class using the cursor property. Refer this https://css-tricks.com/using-css-cursors/
check out the below code for adding arrows as per your requirement
.left_div{
cursor:w-resize;
float:left
}
.right_div{
cursor:n-resize;
float:right
}
<div class="left_div">this is left div</div>
<div class="right_div">this is right div</div>

returning the position of an element continuously

I have an object which is animated and falling from the top of the window to the bottom of the window. this works fine, but I would like to return the position of the element continuously.
At the moment I have this code
var pos = function() {
console.debug(jQuery('.element').position());
}
jQuery(window).on('mousemove', pos);
Which returns the position of the class "element" when the mouse is moving, I have also tried the event handler "live" but it is not working.
Is there any event handler I can use which will continuously return the position of them elemnt?
Thank you
Use .animate()'s step callback to track whatever you want, from position to timing:
var $test = $("span");
$("#element").animate({ top: 300 }, {
duration: 5000,
step: function(now, fx) {
$test.text( now );
}
});
#element{
position:absolute;
top: 0;
background:red;
width:40px;
height:40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span></span> px
<div id="element"></div>
http://api.jquery.com/animate/
A small suggestion, if you don't want to lose your fingers writing jQuery all over the place....
jQuery(function( $ ){ // DOM ready and jQuery $ alias secured
// Free to use $ as you usually would
});
You could use setInterval to execute a function at given interval.
setInterval(function () {
// do something here
}, 1000); // each 1 sec, starts after 1s

Stop element from being fixed once scrolled past value

I have a fixed .widget element that remains visible at all times. Currently however, it scrolls over the footer area. My goal is to stop the widget before it hits the footer.
CSS
.widget {
position:fixed;
height:450px;
width:300px;
}
footer {
height:450px;
width:100%;
}
My route I'm taking is currently:
jQuery
var $bodyheight = $('body').height();
var $footerheight = $('footer').height();
var $widgetheight = $('.game_widget').height();
var $pageheight = $bodyheight - $footerheight - $widgetheight;
$(window).on('scroll', function() {
console.log($(this).scrollTop())
});
My next step would be to loop through to see if scrollTop > $pageheight then update some CSS.
Is this the best way of going about this? Is there a cleaner/simpler way to achieve the same result?
I have managed to solve this quite simply. Inside the scroll function I set 2 variables, one for the position of the fixed element, the other for the position of the footer. These return the exact value from how far the top of the element is from the top of the page. For the fixed element I need to know the distance to the bottom of this element so I also include the height.
var $fixedpos = $(".game_widget").offset().top + $('.game_widget').height();
var $footerpos = $("footer").offset().top - 25; // 25 accounts for margin
Using a simple if/else the CSS is updated to display none/initial depending on whether $fixedpos > $footerpos (i.e. the fixed element is overlapping the footer).
if ($fixedpos > $footerpos) {
$('.game_widget').css('display','none');
} else {
$('.game_widget').css('display','initial');
}
This works, however there is a 'flicking' effect as the fixed element overlaps the footer. This is due to the function executing extremely rapidly. The solution to the flicker is to use this simple 'throttling' plugin that adds a short delay (of your choice) between each execution of a function - http://benalman.com/projects/jquery-throttle-debounce-plugin/
You then just need to bind the on scroll function to the throttle:
function scrolling() {
console.log($(".game_widget").offset().top + $('.game_widget').height());
console.log($("footer").offset().top - 25);
var $fixedpos = $(".game_widget").offset().top + $('.game_widget').height();
var $footerpos = $("footer").offset().top - 25;
if ($fixedpos > $footerpos) {
$('.game_widget').css('display', 'none');
} else {
$('.game_widget').css('display', 'initial');
}
};
$(window).on('scroll', $.throttle(250, scrolling)); // 250ms between executing the function
});
This 250ms delay stops the function from executing so rapidly that the flickering effect occurs.
Hope this helps others trying to solve this problem.

How to adjust a Greensock.js tween based on browser scroll y position rather than by the time?

How would I go about adjusting the time manually based on the scroll position? What might that look like? To basically 'scroll' the tween? So that the tween reacts to the scrolling mouse's Y position rather than just trigger and execute based on a preset time?
IMHO, here is what you'll need to do:
You will need TimelineMax for sequencing your animations. Place
your animations in TimelineMax as you like them to be.
You'll need to figure out the maximum scroll position your window can scroll up to, beforehand. (This can also be re-calculated on browser resize as well but I haven't taken this into account in my example below). You can figure out with the
help of this answer. Also read the comments on that answer.
Upon scroll, you'll need to convert the current scroll position of
your window object into percentage that is: var currentScrollProgress=window.scrollY/maxScroll; such that your currentScrollProgress should always be between 0 and 1.
TimelineMax has a progress() method which takes values ranging
from 0 and 1 where 0 being the initial state of the animations
and 1 being the final state. Feed this currentScrollProgress
into it and you're done.
OR, you can tween the timeline itself that is: TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease});.
Code used in my example is as follows:
HTML:
<div> </div>
<div> </div>
...
CSS:
html, body { margin: 0; padding: 0; }
div { width: 100%; height: 60px; margin: 2px 0; }
div:nth-child(odd) { background: #cc0; }
div:nth-child(even) { background: #0cc; }
JavaScript:
/*global TweenMax, TimelineMax,Power2*/
var myDIVs=document.querySelectorAll('div'),numDIVs=myDIVs.length;
var timeline=new TimelineMax({paused:true}),duration=.4,ease=Power2.easeOut,staggerFactor=.1,scrollTweenDuration=.4;
var scrollTimeout=null,scrollTimeoutDelay=20,currentScrollProgress=0;
var maxScroll=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight)-window.innerHeight; //see [https://stackoverflow.com/a/17698713/3344111]
function init(){
initTimeline();
listenToScrollEvent();
onScroll();
}
function initTimeline(){
for(var i=0; i<numDIVs; i+=1){ timeline.fromTo(myDIVs[i],duration,{opacity:0},{opacity:1,ease:ease},i*staggerFactor); }
}
function listenToScrollEvent(){
(window.addEventListener)?window.addEventListener('scroll',debounceScroll,false):window.attachEvent('onscroll',debounceScroll);
}
function debounceScroll(){
clearTimeout(scrollTimeout);
scrollTimeout=setTimeout(onScroll,scrollTimeoutDelay);
}
function onScroll(){
currentScrollProgress=roundDecimal(window.scrollY/maxScroll,4);
//timeline.progress(currentScrollProgress); // either directly set the [progress] of the timeline which may produce a rather jumpy result
TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease}); // or tween the [timeline] itself to produce a transition from one state to another i.e. it looks smooth
}
function roundDecimal(value,place){ return Math.round(value*Math.pow(10,place))/Math.pow(10,place); }
//
init();
Here is the resulting jsFiddle. Hope it helps.
T
While Tahir's answer is correct and sufficient, there's a lot of unnecessary code to show the example.
A more concise snippet is:
var max_scroll = document.body.offsetHeight - window.innerHeight;
win.addEventListener('scroll', function(){
var scroll_perc = parseFloat(Math.min(window.pageYOffset / max_scroll, 1).toFixed(2));
TweenMax.to(tl, 0, {
progress: scroll_perc
});
});
var tl = new TimelineMax({paused: true});
// the rest of your timeline....

Jquery: How to prevent further animating to the left when style: left == 0 or 0px?

How would I prevent a div from scrolling further left when the style 'left' of that div reached '0' or '0px'? Right now I am using the animate custom effect to scroll a div left and right to display hidden overflows but when the div reaches '0' or '0px' on style: left, I want the user to be prevented from scrolling further left where there is no content, just empty space. I currently have the following code which doesn't seem to be working the way I want:
$(document).ready(function(){
if ($("#ajax-matched-results").css('left') == '0' || '0px') {
$("#scrollLeft-results").click(function() {
$(".matched-results-items").animate({"left": "0px"}, "slow");
});
$("#scrollRight-results").click(function() {
$(".matched-results-items").animate({"left": "-=547px"}, "slow");
});
} else {
$("#scrollLeft-results").click(function() {
$(".matched-results-items").animate({"left": "+=547px"}, "slow");
});
$("#scrollRight-results").click(function() {
$(".matched-results-items").animate({"left": "-=547px"}, "slow");
});
}
});
Thanks for any help!
first of all, shouldn't the if statement be INSIDE the click event? I don't see how this would execute at all, or at most once.
also, your first if statement will always be true. what you want is
if ($("#ajax-matched-results").css('left') == '0' || $("#ajax-matched-results").css('left') == '0px')
also, i'm not 100% sure that the "-=547px" and such will work as expected either. do you want to increment them by that value every time it is clicked, or do you want to set them to that value. I'm going to assume you want to increment it every time.
Here is more or less what you should have:
$(function(){
// this actually eliminates the need for the above if statement
// assuming you only have one thing you're going to animate
var position = 0;
// move object right 547px regardless of current position
$('#scrollRight-results').click(function(){
// animate regardless?
// unless you're setting right side bounds as well
position += 547;
$('id').animate({'left': position}, 'slow');
});
// move object left 547px if not already at 0
$('#scrollLeft-results').click(function(){
if (position != 0){
position -= 547;
$('id').animate({'left': position}, 'slow');
}
});
})
I can almost guarantee you that this code will break if you keep clicking the button because you are not checking the animation so it will keep going as long as it isnt. so you should do something like:
if($("selector").is(":animated")){
return false;
}

Categories