I want to know when the user starts the navigation to a new page by clicking in a link located inside my Flickity slider. I have attached the jQuery click event on the links, but when the user slides and click at the same time, the click event on the <a> is triggered but the navigation to the link adress does not occur.
Demo : http://codepen.io/anon/pen/GoapaY
. To reproduce the issue : click down on the link, then slide, then release your click : the event is triggered but the navigation to example.com have not occured.
Which event/trick can I use to know when the user actually navigate to the link adress ?
Answer obtained with this issue opened on Flickity's GitHub :
This is the intended behavior. This allows users to slide the gallery using any element on the page, links, buttons, etc. It lets click events propagate. There's additional logic so that static clicks do trigger a click on the element, and allow links to go through if no sliding occurred.
Flickity's staticClick event might be what you're looking for.
This solves the issue for me:
$el.on('dragStart.flickity', () => $el.find('.slide').css('pointer-events', 'none'));
$el.on('dragEnd.flickity', () => $el.find('.slide').css('pointer-events', 'all'));
I just disable pointer events on dragStart and reinstate them on dragEnd.
Ali Klein's solution worked for me.
I'm not using jQuery so here is the code I'm using
const carousel = document.querySelector('.carousel')
const flkty = new Flickity(carousel, {
// ...options
on: {
'dragStart': () => {
carousel.style.pointerEvents = 'none'
},
'dragEnd': () => {
carousel.style.pointerEvents = 'all'
}
}
})
Related
I have been doing research on this for days and finally have decided to ask this on here. I am using react and material-ui's ClickAwayListener component. The idea is that I have a button, which toggles the this.state.showGridPopup to the opposite of whatever it is currently is. So if the user was to click it once, the grid popup should show, click it again, the popup should disappear. There is an handleShowGrid handler attached to the button that does this:
handleShowGrid = (event) => {
const { widgetButtonEl } = this.state;
const element = widgetButtonEl === null ? event.currentTarget : null;
console.log('In handleShowGrid!!!!!');
this.setState({
showWidget: !this.state.showWidget,
widgetButtonEl: element
});
}
All this works well. And toggles the popup to show when we click on the button attached to the handler.
<ButtonBase onClick={this.handleShowGrid}>Open Swap</ButtonBase>
The issue is when I add Material-UI's ClickAwayListener. The reason for adding this is to close the grid when a user clicks outside the grid. Here is the ClickAwayListener below:
<ClickAwayListener onClickAway={this.handleCloseWidget}>
<SurveyGrid />
</ClickAwayListener>
And the handleCloseWidget handler:
handleCloseGrid = (e) => {
console.log('In handleCloseWidget!!!!!');
this.setState({
showWidget: !this.state.showWidget,
widgetButtonEl: null
});
}
So now clicking outside grid is fine and closes the Grid. However, now, clicking on the button that should toggle the Grid being show (this.state.showWidget), causes the handleCloseGrid to fire. And then afterwards the handleShowGrid would fire. Is there anyway to not have the handleCloseGrid handler to fire? It seems like an issue with propagation and event bubbling. Have tried different things like e.stopPropagation() but to no avail.
I am using the TabView component from PrimeVue (Vue 3), and I want to stop the tab change if any changes are made by the user, the problem is that I don't know how. I've already tried passing the event and using preventDefault and stopPropagation but seems that it doesn't work and click event is still happening.
The procedure should be:
If any changes are made, user press the tab and a dialog appears.
If user clicks 'No', I should prevent the tab change and stop the click event
Here is the demo of what I'm trying to archive, should be simple https://codesandbox.io/s/aged-wave-yzl1k?file=/src/App.vue:0-1753
If a flag is true I want to show a confirm dialog and prevent the tab change if user dismiss it.
The component that I'm using for the TabView: https://primefaces.org/primevue/showcase/#/tabview
Thanks in advance,
From the docs it looks like that internally the component will first switch tabs and then emit "tab-click", which explains the issue you're seeing. The exception is if the tab is disabled, in which case it won't change tabs but will emit "tab-click".
It took a bit to figure out, but there is a way to get the functionality you need with only a small adjustment. It requires a change in your main.js as well as in your App.vue file.
// main.js
/*
* Put this after you import TabView.
* This will prevent automatic tab switching but still emits
* the event to your application.
*/
TabView.methods.onTabClick = function(event, i) {
this.$emit('tab-click', {
originalEvent: event,
index: i
});
}
// App.vue
const onTabClick = (event) => {
if (changes.value) {
confirm.require({
message:
"Are you sure that you want to leave this tab? You'll lose your changes",
icon: "fal fa-exclamation-triangle",
acceptLabel: "Yes",
rejectIcon: "No",
accept: () => {
alert("here we should allow tab change");
activeIndex.value = event.index; // manually set activeIndex
},
reject: () => {
alert("stop tab change");
},
});
}
};
These changes modify what the onTabClick library method to only emit the event, without automatically switching. Then in your app you can check the index property of the event to determine what should be set to active.
I have a MDC Menu component, where I would like to setup a click or select event listener for list items. I have tried with various events like 'click', 'select', 'selectionchange', 'selectstart', but none of them worked. In documentation it says that MDCMenu:selected
Used to indicate when an element has been selected. This event also includes the item selected and the list index of that item.
I have tried to listen to that event as well, but nothing has worked:
menu.listen("MDCMenu:selected", e => console.log(e));
You can see the sandbox here.
How should the event listener be setup for MDC menu component?
Update
Since after I was informed in the comments that for other users the code is actually working. I went to test it myself with other browsers, and in safari and firefox it was working fine on my mac machine, but in Chrome I still have a problem. I have the chrome version 83.0.4103.61. I have updated the codesandbox with suggestions from the comments, but I can now see that if press few times select options, that it starts to work very randomly all of a sudden in all of the browsers.
It appears that the inconsistency is due to a race condition. Clicking on the menu causes the focus to leave the input which causes the menu to close. And the menu closing causes focus to move back to the input making it open again.
The issue is that the menu often closes before the menu has a chance to send out the selected event.
You need to either prevent the menu from closing on focusout or set a generous timeout before closing the menu.
input.listen("focusout", () => {
setTimeout(() => {
menu.open = false;
// The timer might need to be fiddled with. Needs to not be too big or too small.
}, 120);
});
https://codesandbox.io/s/new-brook-o7k1j?file=/src/index.js
Here's another option without the timing issues of setTimeout. It uses timeouts of 0 to mimic setInterval in order to re-order the timing of events instead by pushing them to the end of the event queue. This should be safer and less prone to the race condition issue from before.
let menuFocused = false;
input.listen("focusin", () => {
if (!menuFocused) menu.open = true;
});
input.listen("click", () => {
menu.open = true;
});
menu.listen("focusin", () => {
menuFocused = true;
});
menu.listen("focusout", () => {
// This interval is to help make sure that input.focusIn doesn't re-open the menu
setTimeout(() => {
menuFocused = false;
}, 0);
});
input.listen("focusout", () => {
setTimeout(() => {
if (!menuFocused) menu.open = false;
}, 0);
});
https://codesandbox.io/s/proud-hooks-c9qi5?file=/src/index.js
I have a dropdown that is controlled via state.
Clicking on a button toggles it on. Clicking outside toggles it off.
The dropdown contains Links within my application, however, when the dropdown is being toggled off, route transition is prevented.
If autohide is disabled, routing works fine, however, it is desired to also hide the dropdown on route transition.
Please explain to me what is going on
Also please help me fix it
class App extends React.Component {
state = {
isNavShown: false
}
showNav = () => this.setState({isNavShown: true})
hideNav = event => {
// ... some more logic ...
// don't hide if autoHide is disabled
if (autoHide.checked === false) return
this.setState({isNavShown: false})
}
componentDidMount() {
document.addEventListener('mousedown', this.hideNav)
}
// ...
}
I have also tried wrapping the setState in setTimeout, but to no avail.
Here is the full jsfiddle https://jsfiddle.net/nimareq/1kh47uey/
So the issue is that your hideNav function is hiding the nav if the user clicks anywhere outside of show navigation button and the checkbox you built. However, if the user clicks on the nav itself it will be hidden before you have a chance to navigate the user.
Essentially, the browser will detect the click event listener you made on the document before it bubbles down to the anchor tag click. By the time it gets there the anchor tag is gone. (I hope that makes sense lol)
Anyways you can easily solve it by adding the following to your hideNav function:
if(nav.contains(event.target)) return;
Also don't forget to add the id="nav" on your navbar or whatever else you want to call it. This way the navbar won't disappear when u click on the navbar. It will still disappear if you click off the navbar.
Im working with jquery mobile right now. And when the user clicks on the box, it will show an additional one. But when the user forced return on browser (or the backbutton), on that moment, the second box should hide, instead of going back the the prev page.
I've managed to achiev almost what I wanted with the popstate:
window.onpopstate = function(event) {
if($('div').is(':visible') {
closeFunction();
event.stopImmediatePropagation();
}
}
But it still changes the URL.
For example, if i has a nav like this:
index > home > internal(with box)
And then i pressed the back button
index > home
Will still trigger the url change, but not the page change.
I've tried with pagebeforechange, but with the same result.
Any ideas?
the popstate event is not cancellable.
referred doc
Specification: HTML5
Interface: PopStateEvent
Bubbles: Yes
Cancelable: No
Target: defaultView
Default Action: None