I'm currently writing a website for a movie making company, which shows their different movies in full-screen.
I put each video in a list, and wrote a function that takes the user to the next video everytime a mousewheel event is triggered. The problem is that when the user is mousewheeling with a trackpad, it triggers multiple events at once, so I figured, I just had to set an interval between each triggering, depending on a variable "animating" that would be either true or false.
So here's my code :
let animating = false
$(window).bind('mousewheel', function (event) {
if (event.originalEvent.wheelDelta >= 0 && actuallyPlaying === false && animating === false) {
animating = true;
goToPreviousVideo();
setInterval(function () {
animating = false
}, 2000)
}
else {
if (actuallyPlaying === false && animating === false) {
animating = true;
goToNextVideo();
setInterval(function () {
animating = false
}, 2000)
};
}
});
And this piece of code works fine, but only for a few video "swipes". I noticed that after two or three times, this function stops working, and many events get triggered at the same time, which results in skipping all the videos and going from the top of the page straight to the bottom.
Do you guys have any idea why this isn't working ?
I'm also adding the code of goToNextVideo() and goToPreviousVideo() in case the problem is with them :
let i = 1 //
const goToNextVideo = function () {
if (i === 4) { // because I've got 4 videos
return;
} else {
$('html, body').animate({
scrollTop: $(`.video-${i + 1}`).offset().top
}, 500);
$(`.video-${i + 1}`).get(0).play();
i += 1
$(`.video-${i - 1}`).get(0).pause();
}
};
const goToPreviousVideo = function () {
if (i === 1) {
return
} else {
$('html, body').animate({
scrollTop: $(`.video-${i - 1}`).offset().top
}, 500);
$(`.video-${i}`).get(0).pause();
i -= 1
$(`.video-${i}`).get(0).play();
}
};
Thanks for your help !
Wish you all a great day
its seems your error is coming from the fact you dont clear the setInterval,
let animating = -1;
$(window).bind('mousewheel', function (event) {
if (event.originalEvent.wheelDelta >= 0 && actuallyPlaying === false && animating < 0) {
animating = setInterval(function () {
clearInterval(animating);
animating = -1;
}, 2000)
goToPreviousVideo();
}
else {
if (actuallyPlaying === false && animating < 0) {
animating = setInterval(function () {
clearInterval(animating);
animating = -1;
}, 2000)
goToNextVideo();
}
}
});
I am not able to understand where the problem is lying but
I have a cleaner and better approach to doing this Please tell if it works
var lastVideoChangeAnimation = Date.now()-2001;
$(window).bind('mousewheel', function (event) {
if (event.originalEvent.wheelDelta >= 0 && actuallyPlaying === false && Date.now()-lastAlertTime>2000) {
lastVideoChangeAnimation = Date.now();
goToPreviousVideo();
}
else if (actuallyPlaying === false && Date.now()-lastAlertTime>2000) {
lastVideoChangeAnimation = Date.now();
goToNextVideo();
};
});
THERE CAN ALSO BE A PROBLEM THAT THERE OCCURS SOME SORT OF ERROR AND YOUR CODE STOPS EXECUTING.
SO JUST CHECK IF THE CONSOLE IS GIVING SOME ERROR WITH POINTING TOWARDS THE FILE WHERE THESE TWO CODES ARE SAVED.
Also please tell in the comment that did it worked
Related
As the title says - I'm looking to add some auto-scrolling on a specific webpage but the script that I have at the moment stops it completely from scrolling, which doesn't look visually appealing during presentations IMHO.
Is there a possibility to slow down instead of harshly stopping the auto-scrolling of the webpage on a specific keystroke?
This is the JS that I tried.
let scrollerID;
let paused = true;
let speed = 2; // 1 - Fast | 2 - Medium | 3 - Slow
let interval = speed * 5;
function startScroll(){
let id = setInterval(function() {
window.scrollBy(0, 2);
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
// Reached end of page
stopScroll();
}
}, interval);
return id;
}
function stopScroll() {
clearInterval(scrollerID);
}
document.body.addEventListener('keypress', function (event)
{
if (event.which == 13 || event.keyCode == 13) {
// It's the 'Enter' key
if(paused == true) {
scrollerID = startScroll();
paused = false;
}
else {
stopScroll();
paused = true;
}
}
}, true);
Thanks in advance!
I have a custom script which advances a small icon upon wheel scroll. It works well but it's not advancing the element as quickly as I would like. I'd like to increase the distance that the element (pill) moves per wheel scroll. How can I alter the code to facilitate this? Thanks for any insight. Code:
function wheel(e) {
var modelContentWrapper = $('.model-content-wrapper');
var howModelWorks_steps = $('#howModelWorks_steps');
var currentIndex = $('.model-content.active', modelContentWrapper).index();
var $pill = $('.step_' + (currentIndex + 1) + ' > a.clickable-icon');
var $li = $('ul.steps li');
var $pillStep = ($li.width()) / wheelSpeed;
direction = 'right';
if ((e.wheelDelta && e.wheelDelta >= 0) || (e.detail && e.detail < 0)) {
wheelValue++;
if ((firstElement && parseInt($pill.css('margin-left')) > initialIconLeft) || (!firstElement)) {
$pill.css('margin-left', (parseInt($pill.css('margin-left')) - $pillStep) + 'rem');
}
if (wheelValue >= wheelSpeed) {
wheelValue = wheelValue - wheelSpeed;
forceModelBackward();
}
//direction = 'left';
}
else {
wheelValue--;
//direction = 'right';
if (!lastElement) {
$pill.css('margin-left', (parseInt($pill.css('margin-left')) + $pillStep) + 'rem');
}
if (Math.abs(wheelValue) == wheelSpeed) {
wheelValue = wheelValue + wheelSpeed;
forceModelForward();
}
}
//if (wheelValue > (wheelSpeed * 5) || wheelValue < (wheelSpeed * -5)) {
if (stepsCounter == 1 || stepsCounter == 4) {
enableScroll();
}
preventDefault(e);
}
Try adding the follow to your event listener..
capture: true,
passive: true
Passive Event Listeners allow you to attach un-cancelable handlers to events, letting browsers optimize around your event listeners. The browser can then, for example, keep scrolling at native speed without waiting for your event handlers to finish executing.
Usage
Probably what is used mostly:
// Really, if you're using wheel, you should instead be using the 'scroll' event,
// as it's passive by default.
document.addEventListener('wheel', (evt) => {
// ... do stuff with evt
}, true)
You’ll need to replace it with this:
document.addEventListener('wheel', (evt) => {
// ... do stuff with evt
}, {
capture: true,
passive: true
})
Copied information from alligator dot io
So my problem is this,
I was wondering if there was a way to detect if a user right clicks and left clicks simultaneously and commit an action if doing so in jQuery. It seems like the code can only detect one right click or one left click at a time in mouse events.
UPDATE
Thanks for the answers, I decided ultimately that feature would be too funky to have for users when I was trying to implement it. Hopefully these answers will be able to help other people too.
You can create variables to hold the state of each mouse button individually and use that to determine whether both buttons are down:
window.isLeftMouseDown = false;
window.isRightMouseDown = false;
$(document).on('mousedown', function(e) {
if (e.which == 1)
window.isLeftMouseDown = true;
else if (e.which == 3)
window.isRightMouseDown = true;
if (window.isLeftMouseDown && window.isRightMouseDown) {
console.log('both down');
}
});
$(document).on('mouseup', function(e) {
if (e.which == 1)
window.isLeftMouseDown = false;
else if (e.which == 3)
window.isRightMouseDown = false;
});
https://jsfiddle.net/2j151tpt/
Something like this. It uses ES2015.
let left = false;
document.addEventListener('mousedown', e => {
if (e.button === 0) {
left = true;
} else if (e.button === 2 && left) {
fireYourFunctionForTwoButtons();
}
})
document.addEventListener('mouseup', e => {
if (e.button === 0) {
left = false;
}
});
My proposal is based on the elapsed time in milliseconds between the two consecutive clicks:
$(function () {
$('#btn').data('last-left-click', 0).on('mousedown contextmenu', function (e) {
var nowTime = Date.now();
if (e.which == 1) {
$(this).data('last-left-click', nowTime);
}
if (e.which == 3) {
// if less then 300 milliseconds....
if ((nowTime - $(this).data('last-left-click')) < 300) {
console.log('Both left and right clicked in sequence in less then 300 milliseconds!');
}
$(this).data('last-left-click', 0);
}
});
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<button id="btn">Click Me</button>
I have a timer that starts counting up when the page is loaded. I want it to stop when the user scrolls to the bottom of the page. Here is the jQuery I've written:
function timerTick(time, stop)
{
if(stop == false)
{
setInterval(function ()
{
time += 1;
var displayTime = time/10;
if(displayTime % 1 != 0)
{
$('.time').text(displayTime.toString());
}
else
{
$('.time').text(displayTime.toString() + ".0");
}
}, 100);
}
else //behavior is the same if i remove the else block
{
return;
}
}
$(document).ready(function () {
var time = 0;
var stop = false;
timerTick(time, stop);
//check if we're at the bottom
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
stop = true;
}
});
});
The timer counts up perfectly, the problem is I can't get it to stop. If I replace the stop = true; line with alert('abc');, the alert shows up when the user reaches the bottom. So all of the pieces are working, just for some reason setting stop to true doesn't stop the timerTick function from going into the if(stop == false) block.
Can someone tell me what I'm doing wrong?
Edit: I made a jsFiddle.
You have to clear interval as soos as user reach the end of page. Otherwise it will continue executing.
Try:
var intervalId;
function timerTick(time, stop)
{
if(stop == false)
{
intervalId=setInterval(function () //Set the interval in a var
{
time += 1;
var displayTime = time/10;
if(displayTime % 1 != 0)
{
$('.time').text(displayTime.toString());
}
else
{
$('.time').text(displayTime.toString() + ".0");
}
}, 100);
}
else //behavior is the same if i remove the else block
{
return;
}
}
$(document).ready(function () {
var time = 0;
var stop = false;
timerTick(time, stop);
//check if we're at the bottom
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
stop = true;
clearInterval(intervalId);//HERE clear the interval
}
});
});
DEMO
to determine bottom of the page you could try this
if(window.innerHeight + document.body.scrollTop >= document.body.offsetHeight) {
stop = true;
}
Update:
you need to make your variable stop global, declare it outside of documnet.ready function.
setInterval function returns number that you can later pass into clearInterval to stop the timer.
Declare
var Timeout=0;
check
if(stop == false)
inside the setInterval function
like
Timeout=setInterval(function ()
{
if(stop == false)
{
time += 1;
var displayTime = time/10;
if(displayTime % 1 != 0)
{
$('.time').text(displayTime.toString());
}
else
{
$('.time').text(displayTime.toString() + ".0");
}
}
else
{
clearInterval(Timeout);
}
}, 100);
Anywhy can i detect when user push up when scroll top less than 0 ? (Like facebook app reload)
This is my code idea so far :
window.onscroll = function (e) {
scrollTop = hasOffset ? window.pageYOffset : docBody.scrollTop;
detect_pushUp(scrollTop);
};
var push_up_check = true;
function detect_pushUp(scrollPosition) {
if(scrollPosition === 0 && !push_up_check) {
push_up_check = true;
} else if(scrollPosition === 0 && push_up_check) {
location.reload(true);
} else {
push_up_check = false;
}
}
This is working ok, But any better idea? to detect something like this?