I’ve been struggling to solve this for days now. There is a slider with clickable items at the bottom of the page. I’ve made the slider draggable. But the issue is that when the dragging stops the click action also happens on the item on which mousedown event happened. I’ve tried to adding ‘pointer-vents: none’ to the inner item after dragging starts, but in this case draggint doesn’t work at all. Any ideas on how can I solve this problem?
https://duolutions-wondrous-site.webflow.io/straudo-branding-naming
Read-Only link of webflow: https://preview.webflow.com/preview/duolutions-wondrous-site?utm_medium=preview_link&utm_source=designer&utm_content=duolutions-wondrous-site&preview=9e5312190b70be978f65b8da04fbcefc&pageId=6377be41955fe23fb7c4bf33&workflow=preview
<script>
let isDown = false;
let startX;
let scrollLeft;
const slider = document.querySelector('.items');
const end = () => {
isDown = false;
slider.classList.remove('active');
}
const start = (e) => {
isDown = true;
slider.classList.add('active');
startX = e.pageX || e.touches[0].pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
}
const move = (e) => {
if(!isDown) return;
e.preventDefault();
const x = e.pageX || e.touches[0].pageX - slider.offsetLeft;
const dist = (x - startX);
slider.scrollLeft = scrollLeft - dist;
}
(() => {
slider.addEventListener('mousedown', start);
slider.addEventListener('touchstart', start);
slider.addEventListener('mousemove', move);
slider.addEventListener('touchmove', move);
slider.addEventListener('mouseleave', end);
slider.addEventListener('mouseup', end);
slider.addEventListener('touchend', end);
})();
</script>
There is no link to a working sandbox, so I can't be sure it will help, but I've noticed you didn't use Event.stopPropagation(). This should stop the propagation of the current event. You can read more about it here
Related
I have a div block containing the steps of one of my benefits that I made scrollable vertically by holding with the mouse ( Draggable Div )
I would like to add a smooth effect and not just a scroll that stops instantly when we stop the scroll.
What should I add to my code below?
Thank you and happy holidays! 🎅🏻🎄
const container = document.querySelector('.process-steps');
let startY;
let startX;
let scrollLeft;
let scrollTop;
let isDown;
container.addEventListener('mousedown',e => mouseIsDown(e));
container.addEventListener('mouseup',e => mouseUp(e))
container.addEventListener('mouseleave',e=>mouseLeave(e));
container.addEventListener('mousemove',e=>mouseMove(e));
function mouseIsDown(e){
isDown = true;
startY = e.pageY - container.offsetTop;
startX = e.pageX - container.offsetLeft;
scrollLeft = container.scrollLeft;
scrollTop = container.scrollTop;
}
function mouseUp(e){
isDown = false;
}
function mouseLeave(e){
isDown = false;
}
function mouseMove(e){
if(isDown){
e.preventDefault();
//Move vertcally
const y = e.pageY - container.offsetTop;
const walkY = y - startY;
container.scrollTop = scrollTop - walkY;
}
}
</script>
So I have a horizontal scrolling feature which works great in JS but only for one section with the classname, any other section that shares the same classname it doesn't replicate the same effects for. How can I make it so it works for every section that has the class name. You can see it in action on my website here where the quick links scrolls fine when you click but the other horizontally scrolling sections dont. Thank you - https://tutoryou.uixweb.dev/
const slider = document.querySelector('.scroller-div');
let mouseDown = false;
let startX, scrollLeft;
let startDragging = function (e) {
mouseDown = true;
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
};
let stopDragging = function (event) {
mouseDown = false;
};
slider.addEventListener('mousemove', (e) => {
e.preventDefault();
if(!mouseDown) { return; }
const x = e.pageX - slider.offsetLeft;
const scroll = x - startX;
slider.scrollLeft = scrollLeft - scroll;
});
// Add the event listeners
slider.addEventListener('mousedown', startDragging, false);
slider.addEventListener('mouseup', stopDragging, false);
slider.addEventListener('mouseleave', stopDragging, false);
for smooth scrolling (no jump effect) you have to create variables inside forEach()
const sliders = document.querySelectorAll('.scroller-div');
sliders.forEach(slider=>{
let startX, scrollLeft;
let startDragging = function(e) {
mouseDown = true;
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
};
let stopDragging = function(event) {
mouseDown = false;
};
slider.addEventListener('mousemove', (e)=>{
e.preventDefault();
if (!mouseDown) {
return;
}
const x = e.pageX - slider.offsetLeft;
const scroll = x - startX;
slider.scrollLeft = scrollLeft - scroll;
}
);
// Add the event listeners
slider.addEventListener('mousedown', startDragging, false);
slider.addEventListener('mouseup', stopDragging, false);
slider.addEventListener('mouseleave', stopDragging, false);
}
);
First change this:
const slider = document.querySelector('.scroller-div');
To this:
const sliders = document.querySelectorAll('.scroller-div');
querySelector will stop after finding the first element matching your selector while querySelectorAll will return a list of all the elements matching your selector.
Once you do that, you will need to loop through all the sliders and add the event listener to each one. So your code becomes wrapped in a forEach loop:
sliders.forEach(slider => {
let mouseDown = false;
let startX, scrollLeft;
let startDragging = function (e) {
mouseDown = true;
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
};
let stopDragging = function (event) {
mouseDown = false;
};
slider.addEventListener('mousemove', (e) => {
e.preventDefault();
if(!mouseDown) { return; }
const x = e.pageX - slider.offsetLeft;
const scroll = x - startX;
slider.scrollLeft = scrollLeft - scroll;
});
// Add the event listeners
slider.addEventListener('mousedown', startDragging, false);
slider.addEventListener('mouseup', stopDragging, false);
slider.addEventListener('mouseleave', stopDragging, false);
});
I have the href attribute(another page) on my home page. another page's on-load function works fine if I click on it. in case if I do with (control + left click on the link), or (right-click -> open in new tab), on-load function not fired if it was not my active or current tab. if I switch into that particular tab immediately, it works fine as usual. my question is, will it not work if it is not our current tab. any alternative solution for it. thanks
window.onload = swipe();
function swipe() {
if (window.outerWidth > 1024) {
var slider = document.getElementsByClassName("cards")[0];
var isDown = false;
var startX;
var scrollLeft;
slider.addEventListener('mousedown', function (e) {
isDown = true;
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
e.preventDefault();
});
slider.addEventListener('mouseleave', function () {
isDown = false;
});
slider.addEventListener('mouseup', function () {
isDown = false;
});
slider.addEventListener('mousemove', function (e) {
if (!isDown) return;
e.preventDefault();
var x = e.pageX - slider.offsetLeft;
var walk = (x - startX) * 3;
slider.scrollLeft = scrollLeft - walk;
});
}
var swipe_sec = document.getElementsByClassName("cards")[0];
function calc_prog(winScroll, width) {
var scrolled = ((winScroll) / width) * 100;
document.getElementById("t_art_prog").style.width = scrolled + "%";
}
var winScroll = swipe_sec.clientWidth;
var width = swipe_sec.scrollWidth - swipe_sec.clientWidth;
calc_prog(winScroll, width);
swipe_sec.addEventListener("scroll", function () {
var winScroll = swipe_sec.scrollLeft + swipe_sec.clientWidth;
var width = swipe_sec.scrollWidth;
calc_prog(winScroll, width);
});
}
The problem is not with window.onload, it is with if (window.outerWidth > 1024), window.outerWidth will be 0 when you open in a new tab.
Two solutions I can think of -
Use window.visualViewport.width instead of window.outerWidth
Try using focus event like this -
window.addEventListener('focus', function(){
...
});
Note - Focus event will be triggered every time when you switch to the tab, you have to control it to execute only once.
Two things I need are that you could choose the speed of the scroll when dragging and upon release it would still move a bit, not stop instantly.
codepen: https://codepen.io/rKaiser/pen/qGomdR
I can set the speed close enough. Reasonable to add some momentum? or perhaps there is a more fitting plugin to use here? Thanks.
const slider = document.querySelector('.container');
let isDown = false;
let startX;
let scrollLeft;
slider.addEventListener('mousedown', (e) => {
isDown = true;
slider.classList.add('active');
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', () => {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mousemove', (e) => {
if(!isDown) return;
e.preventDefault();
const x = e.pageX - slider.offsetLeft;
const walk = (x - startX) * 0.3; //scroll-speed
slider.scrollLeft = scrollLeft - walk;
});
You need to increase scrollLeft with certain amount with every frame, after mouseup, till speed becomes 0. Something like=>
slider.addEventListener('mouseup', () => {
isDown = false;
slider.classList.remove('active');
speed = (-scrollLeft+slider.scrollLeft)/(new Date()-t)*500; //t is time of mouse down start
const draw=()=>{
if(speed>0){
slider.scrollLeft = slider.scrollLeft + speed--; //increase by certain amount
}else{
momentum=false;
}
requestAnimationFrame(draw);
}
momentum=true;
draw();
});
slider.addEventListener('mousemove', (e) => {
if(!isDown && !momentum){
return;
}..
I'm working on a component that moves a parts diagram around in a container. Right now everything works great on the first mousemove, but on the second the positioning styles are getting reset to zero.
I re-wrote the code outside of Vue and also made a codepen for your viewing.
Codepen: https://codepen.io/paytonburd/pen/WKqEjo
Code:
let diagram = document.getElementById('diagram')
let diagramImg = document.getElementById('diagram-image')
let startX;
let startY;
let walkX;
let walkY;
let dragging = false;
diagram.addEventListener('mousedown', (e) => {
dragging = true;
startX = e.pageX - diagram.offsetLeft;
startY = e.pageY - diagram.offsetTop;
})
diagram.addEventListener('mousemove', (e) => {
if (!dragging) return;
e.preventDefault();
let x = e.pageX - diagram.offsetLeft;
let y = e.pageY - diagram.offsetTop;
walkX = x - startX
walkY = y - startY
console.log(walkX, walkY)
diagramImg.style.top = walkY + 'px'
diagramImg.style.left = walkX + 'px'
})
diagram.addEventListener('mouseleave', () => {
dragging = false;
})
diagram.addEventListener('mouseup', () => {
dragging = false;
})
When you mouse down, you always set the startX and startY relative to the position of the diagram, which is always at 0, 0 and never moves.
I think what you want is to instead set them to relative to the current position of the diagram image instead:
let diagram = document.getElementById('diagram')
let diagramImg = document.getElementById('diagram-image')
let startX;
let startY;
let walkX;
let walkY;
let dragging = false;
diagram.addEventListener('mousedown', (e) => {
dragging = true;
//This is where it went wrong
startX = e.pageX - diagramImg.offsetLeft;
startY = e.pageY - diagramImg.offsetTop;
})
diagram.addEventListener('mousemove', (e) => {
if (!dragging) return;
e.preventDefault();
let x = e.pageX - diagram.offsetLeft;
let y = e.pageY - diagram.offsetTop;
walkX = x - startX
walkY = y - startY
console.log(walkX, walkY)
diagramImg.style.top = walkY + 'px'
diagramImg.style.left = walkX + 'px'
})
diagram.addEventListener('mouseleave', () => {
dragging = false;
})
diagram.addEventListener('mouseup', () => {
dragging = false;
})
https://codepen.io/anon/pen/yqdzyq?editors=1111