it's ok no problems i found solution by using pointerDown pointerUp
embla.on('pointerDown', (eventName) => {
console.log('function happen');
});
embla.on('pointerDown', (eventName) => {
console.log('function happen');
});
here is code for all who search for it too.
import { setupPrevNextBtns, disablePrevNextBtns } from "./prevAndNextButtons";
import { setupDotBtns, generateDotBtns, selectDotBtn } from "./dotButtons";
let time = 200;
let t = setTimeout(test, time);
function test() {
console.log('embla timeout started');
}
function disablePointerEvents() {
let elemArr = document.querySelectorAll('.drop-link');
for(let i = 0; i < elemArr.length; i++) {
elemArr[i].classList.add('disabled');
}
}
function enablePointerEvents() {
let elemArr = document.querySelectorAll('.drop-link');
for(let i = 0; i < elemArr.length; i++) {
elemArr[i].classList.remove('disabled');
}
}
const setupEmblaCarousel = (emblaNode, options) => {
const viewPort = emblaNode.querySelector(".embla__viewport");
const prevBtn = emblaNode.querySelector(".embla__button--prev");
const nextBtn = emblaNode.querySelector(".embla__button--next");
const dots = emblaNode.querySelector(".embla__dots");
const embla = EmblaCarousel(viewPort, options);
const dotsArray = generateDotBtns(dots, embla);
const setSelectedDotBtn = selectDotBtn(dotsArray, embla);
const disablePrevAndNextBtns = disablePrevNextBtns(prevBtn, nextBtn, embla);
setupPrevNextBtns(prevBtn, nextBtn, embla);
setupDotBtns(dotsArray, embla);
embla.on("select", setSelectedDotBtn);
embla.on("select", disablePrevAndNextBtns);
embla.on("init", setSelectedDotBtn);
embla.on("init", disablePrevAndNextBtns);
embla.on('pointerDown', (eventName) => {
clearTimeout(t);
t = setTimeout(disablePointerEvents, time);
});
embla.on('pointerUp', (eventName) => {
clearTimeout(t);
t = setTimeout(enablePointerEvents, time);
});
};
const options = { loop: false };
const emblaNodes = [].slice.call(document.querySelectorAll(".embla"));
const emblaCarousels = emblaNodes.map(emblaNode =>
setupEmblaCarousel(emblaNode, options)
);
sorry about that!
if you know better way to do it please tell me!
best reggards from Vlad!
Hello @vladtabachuk,
Thank you for your question. Maybe this could a simpler approach:
import { setupPrevNextBtns, disablePrevNextBtns } from "./prevAndNextButtons";
import { setupDotBtns, generateDotBtns, selectDotBtn } from "./dotButtons";
const setupEmblaCarousel = (emblaNode, options) => {
const viewPort = emblaNode.querySelector(".embla__viewport");
const prevBtn = emblaNode.querySelector(".embla__button--prev");
const nextBtn = emblaNode.querySelector(".embla__button--next");
const dots = emblaNode.querySelector(".embla__dots");
const embla = EmblaCarousel(viewPort, options);
const dotsArray = generateDotBtns(dots, embla);
const setSelectedDotBtn = selectDotBtn(dotsArray, embla);
const disablePrevAndNextBtns = disablePrevNextBtns(prevBtn, nextBtn, embla);
// Store drop links in an array
const dropLinks = [].slice.call(emblaNode.querySelectorAll('.drop-link'));
setupPrevNextBtns(prevBtn, nextBtn, embla);
setupDotBtns(dotsArray, embla);
embla.on("select", setSelectedDotBtn);
embla.on("select", disablePrevAndNextBtns);
embla.on("init", setSelectedDotBtn);
embla.on("init", disablePrevAndNextBtns);
// Prevent default on click if embla doesn't allow click
dropLinks.forEach(dropLink => {
dropLink.addEventListener('click', (event) => {
if (!embla.clickAllowed()) event.preventDefault();
}, false);
});
};
const options = { loop: false };
const emblaNodes = [].slice.call(document.querySelectorAll(".embla"));
const emblaCarousels = emblaNodes.map(emblaNode =>
setupEmblaCarousel(emblaNode, options)
);
Give it a try and let me know if it helps.
Best,
David
Thank you so much for answer! I will try it and tell you my resoults
it does not work for me, may be i use wrong api version i think its v2.5.2 because, probably, version that supports embla.clickAllowed() is v2.7.2? can you please tell me where can i get embla-carousel.umd.js of latest version? for vanilla js usage of course, because i cant real find it, i used api from that multiple carousels example on code sandbox/
you can check my portfolio website and inspect elements may be it help www.tabachuk.vip , to make dropdown always visible just rightclick on it > context menu will appear this freaze it from hiding when you move pointer outside it. i have uploaded on server your version of code. im using your embla carousel plugin on dropdown menu when hover on "袚邪谢械褉械褟" "袩邪薪芯褉邪屑褘" if translate this words in english it sounds like "Gallery" "Panoramas"
If you're using a script tag, try including this, it should give you the latest version:
<script src="https://unpkg.com/embla-carousel@latest/embla-carousel.umd.js"></script>
If you're using a module bundler install the latest version like so:
npm install embla-carousel@latest --save
Cool! i'll try, im using this kind of tag <script src='/static/js/libs/embla/embla-carousel.umd.js'></script> but even with this tag it doesnt want to work for me) <script src="https://unpkg.com/embla-carousel@latest/embla-carousel.umd.js"></script>
Still not working, may be i'll try to use display:block for a.drop-link <= this is also not working
how can i implement pointer-events: none for a.droplink while carousel is moving? because it aslo have data-link attribute that listening my another script, and this changes route, im using custom vanilla js routing system
i can try something like this to do
if carousel move and i click on link it should add classname to a.drop-link => dropLink.classList.add('disabled'); and after 100 ms for example dropLink.classList.remove('disabled'); what do you think? at least its going to work better than my previous version))
cant realy do it because pointer-events: none; disables all events and it happens after i click; so for now im going to use my old version. If i disable events after click and after 100 ms enable pointer-events: auto it doesnt do whai i expected, its just disabling events after rout changes, but if i use mousedown event carousel does not moving at that moment, so it useless for me, its not to easy task for me) I need to think more about it, but any way thank you so much sir for explaining me how embla.clickAllowed() works, if i'll get some positive resoults i'll tell you about it here. I have little idea may be check embla.clickAllowed() after some timeout like 100-200 ms after mousedown over a.drop-link
Hi @vladtabachuk,
embla.clickAllowed() has been stable for a long time now. Please create a CodeSandbox with your setup that demonstrates the issue. It鈥檚 hard for me to guess what could be wrong when I don鈥檛 have the whole picture. That will enable me to debug your code instead of guessing what could be wrong 馃檪.
Kindly
David
its hard to setup my routing system on codeSendbox sorry sir, all i want to say that its using this event to trigger click on links that have data-link attributes as you can see <a class='drop-link' href="/gallery/interior" data-link> im not using node js for it all to work, it's all on cheap php hosting, it's just my custom vanilla routing system for making my website dynamic and fancy for user experience.
dropLinks.forEach(dropLink => {
dropLink.addEventListener('click', (event) => {
if (!embla.clickAllowed()) event.preventDefault();
}, false);
});
};
so if you do this code it's actualy not distributed on this event while clicking on links. I sure it could be ok for most of embla users, but not for me, but any way i came up with some good resoults so next attempts to optimize code it's just experements that i am interesting in.. I dont advise you to waste time on this. Im doing good so far, and I very glad to use your lib, it's amazing! It's working prefect! easy css styling and js scripting..
window.addEventListener("popstate", router);
document.addEventListener("DOMContentLoaded", () => {
document.body.addEventListener("click", e => {
if (e.target.matches("[data-link]")) {
e.preventDefault();
if (e.target.href == undefined) {
navigateTo(e.target.parentNode.href);
} else {
navigateTo(e.target.href);
}
}
});
router();
});
so as i understand i better use that first version of my embla index,js code thai I came to. It works the best of all i tryed.
Sorry about it, sir i realy cant setup my routing system on codeSendbox, it's just not working there because its custom made with vanilla js, no react no libraries. I did it as experiment. But i'll keep going and posting here my resoults may be it will help someone
import { setupPrevNextBtns, disablePrevNextBtns } from "./prevAndNextButtons.js";
import { setupDotBtns, generateDotBtns, selectDotBtn } from "./dotButtons.js";
let time = 210;
let t = setTimeout( ()=>{}, time);
const setupEmblaCarousel = (emblaNode, options) => {
const viewPort = emblaNode.querySelector(".embla__viewport");
const prevBtn = emblaNode.querySelector(".embla__button--prev");
const nextBtn = emblaNode.querySelector(".embla__button--next");
const dots = emblaNode.querySelector(".embla__dots");
const embla = EmblaCarousel(viewPort, options);
const dotsArray = generateDotBtns(dots, embla);
const setSelectedDotBtn = selectDotBtn(dotsArray, embla);
const disablePrevAndNextBtns = disablePrevNextBtns(prevBtn, nextBtn, embla);
const dropLinks = [].slice.call(emblaNode.querySelectorAll('.drop-link'));
setupPrevNextBtns(prevBtn, nextBtn, embla);
setupDotBtns(dotsArray, embla);
embla.on("select", setSelectedDotBtn);
embla.on("select", disablePrevAndNextBtns);
embla.on("init", setSelectedDotBtn);
embla.on("init", disablePrevAndNextBtns);
document.body.addEventListener('mouseup', ()=> {
dropLinks.forEach(el => {
if(el.classList.contains('disabled')) {
el.classList.remove('disabled');
}
});
});
dropLinks.forEach(el => {
el.addEventListener('mousedown', () => {
clearTimeout(t);
t = setTimeout( ()=>{
el.classList.add('disabled');;
}, time);
});
});
};
const options = { loop: false };
const emblaNodes = [].slice.call(document.querySelectorAll(".embla"));
const emblaCarousels = emblaNodes.map(emblaNode =>
setupEmblaCarousel(emblaNode, options)
);
So this what i came up for now, it works ok
Hi @vladtabachuk,
This piece of code you shared is causing the issue and also the reason why my suggestion isn鈥檛 working for you:
document.body.addEventListener("click", e => {
if (e.target.matches("[data-link]")) {
e.preventDefault();
if (e.target.href == undefined) {
navigateTo(e.target.parentNode.href);
} else {
navigateTo(e.target.href);
}
}
});
I didn鈥檛 have any knowledge of this code until you shared it right now so it was impossible for me to know why you were experiencing issues.
Because what you鈥檙e doing here is programmatically navigating when a user clicks on a link. You can鈥檛 run this script on link click if embla.clickAllowed() returns false, otherwise it will navigate regardless of what Embla says.
I hope that makes sense.
Best,
David
I dont think that it's your issue, it's my problem that i use such system in my project, but i like it because it looks like react but using vanilla js :)
Yes, You exactly right i programaticly navigating pages, if you want i can send you simplified version of this routing system, maybe you want to explore it, its very simple, but i suggest you not to waste time on my problem, im doing good so far, thank you for feedback you realy NICE GUY, you can write me message on email and i'll send you archive simplified version of this routing system [email protected] so you can rework it or may be learn something from it for your special purposes.
Best reggards, Vlad
Most helpful comment
Hi @vladtabachuk,
embla.clickAllowed()has been stable for a long time now. Please create a CodeSandbox with your setup that demonstrates the issue. It鈥檚 hard for me to guess what could be wrong when I don鈥檛 have the whole picture. That will enable me to debug your code instead of guessing what could be wrong 馃檪.Kindly
David