I'm using jquery mobile's panel feature to create a slide out menu for my mobile app but the number of links in the panel excedes the page length. I also have an event listener in place to prevent scrolling, but it interferes with scrolling to the other links. So what I wanted was to enable the event listen only when the panel was closed and remove it when it was opened. So I came up with this.
$('#panel.ui-panel-closed').addEventListener('touchmove', function(e) {
e.preventDefault(); }, false);
So when ever the #panel has a class of ui-panel-closed, the event listen is in placed. But whats ended up happening is that I have to open and close the panel first before it is effected by the javascript. Any ideas on how to get it to work on load. It is wrapped around a on document ready statement.
Try it like this:
Add it into
$(document).on("pageinit", function() {
$(document).on("touchmove", "#panel.ui-panel-closed", function(e) {
e.preventDefault();
});
});
Related
I've been trying to figure out why opening accordions on this page causes the page to scroll to the top. The accordions are using Bootstrap 3.
I've determined that the code causing it is a click event listener in https://www.parkinson.ca/wp-content/plugins/cornerstone/assets/js/site/cs.6f62d0f.js. Removing this listener from Chrome DevTools solves the issue. Somewhere along the way, code is called within this file that causes the page to scroll to the top.
However, I'm trying not to delve into a plugin's code and, instead, prevent that event listener from firing by creating my own event listener:
document.body.addEventListener("click", (function(e) {
var isAccordion = e.target.getAttribute('data-toggle') == 'collapse';
if (isAccordion) {
var accordionHref = e.target.getAttribute('href');
$(accordionHref).collapse('toggle');
e.stopImmediatePropagation();
}
}));
Unfortunately, I found that, immediately after this code is executed, jQuery creates a TransitionEvent since the accordion CSS classes change, which is eventually picked up by the JS file above, causing the scrolling to happen anyway.
How do I fix this?
I'm trying to add a long click to a sortable group of responsive bootstrap buttons. The only way the longclick function seems to trigger is if I put it on the #list_content container. However, then $this doesn't refer to the actual button div (.sm-col-4) that triggered the event.
$('#list_content').mayTriggerLongClicks().on('longClick', function() {
alert("long_click=" + JSON.stringify($(this)));
});
Hoping that someone has some ideas on how I can get the colid that triggered the event, and as well to prevent the long-press from triggering when the user is moving the button.
https://jsfiddle.net/7yhkp9eo/3/
Edit for answer #1.
Thanks for the response. Interesting, that works in the fiddle but not in my app. When I set the selector to:
$('#list_content')
I see the longClick event listener on the button as div#list_content.ui-sortable for both click and mousedown. When I set the selector to
$('a.btn')
there is no event listener for click or mousedown according to chrome developer tools. I also have this code in the main $(document).ready() section in my app.
$(document).on('mousedown', function (e) {
if($(e.target).hasClass('popover-content')) {
fp_popover_close = false;
} else
fp_popover_close = true;
});
Which I need to get a slider control in a popover to work properly. I see that event on the button with $('a.btn') but not the long click.
About the colid and the trigger of the event, in your fiddle this is working for me...
$('a.btn').mayTriggerLongClicks().on('longClick', function() {
var colId = $(this).parent('div').attr('colid');
alert(colId);
});
While I didn't solve this through the right selector at the sortable stage, I was able to add the long click event when the button was originally created by the application and then it only fires if sortable is active.
I'm struggling to disable default taphold browser event. Nothing that I have found on Google provided any help. I have only Android 4.4.4 mobile and Chrome dev tools for testing. I tried CSS fixes, such as webkit-touch-callout and others, but apparently they don't work for Android, also they don't work in Chrome dev tools.
I also tried detecting right click, (e.button==2), it doesn't work.
I came up with a solution, but it solves one problem and creates another. I just want to have a custom action for 'long press' event for selected anchors and I don't want the default pop up to appear (open in a new tab, copy link address, etc.)
This is what I did:
var timer;
var tap;
$("body").on("touchstart", my_selector, function(e) {
e.preventDefault();
timer = setTimeout(function() {
alert('taphold!');
tap=false;
},500);
});
$("body").on("touchend", my_selector, function() {
if(tap) alert('tap');
else tap=true;
clearTimeout(timer);
});
It successfully disables the default taphold event and context menu doesn't appear. However it also disables useful events, such as swipe. The links are in a vertical menu and the menu is higher than the screen, so a user has to scroll it. If he tries to scroll, starting on an anchor, it won't scroll, it will alert 'tap!'
Any ideas how could I disable taphold default or how could I fix this code so it disables only tap events and leave default swipe events enabled?
Edit: Now I thought about setting a timeout, if the pointer is in the same place for lets say 100ms, then prevent default action. However e.preventDefault(); doesn't work inside setTimeout callback.
So now I'm just asking about the simplest example. Can I prevent default actions after certain amount of time has passed (while the touch is still there).
And this is my whole problem in a fiddle. http://jsfiddle.net/56Szw/593/
This is not my code, I got this from http://www.gianlucaguarini.com/blog/detecting-the-tap-event-on-a-mobile-touch-device-using-javascript/
Notice that while swiping the box up and down, scrolling doesn't work.
I got the solution. It was so simple! I had no idea there's an oncontextmenu event. This solves everything:
$("body").on("contextmenu", my_selector, function() { return false; });
For an <img> I had to use event.preventDefault() instead of return false.
document.querySelector('img').addEventListener('contextmenu', (event) => {
event.preventDefault();
}
I'm trying to get the event for a mousewheel scroll right before it happens so that I can stop the scroll and do some stuff and then give back control to the user.
Currently I have the following code to cancel out the scroll. However the scroll happens once and then control is taken away from the user. I'd like to make sure the scroll does not happen, do some other stuff instead, and then give control back afterwards.
$('body').on({ 'mousewheel': function(e) {
e.preventDefault();
e.stopPropagation();
}});
How can I do this?
You can use the onwheel event.
window.onwheel = function(){
alert('your magic here');
return false;
}
Are you able to debug and see if the event is being fired in the first scroll?
Is your code inside a $(document).ready( function?
If you are using jquery-mousewheel plug-in, you will be able to call this only if you are attaching it after the plug-in is ready and declared before your script (might be on your page header).
<div id="menuContainer"></div>
<div id="menuItemTemplate" class="menuItem">
<div class="menuItemTitle"></div>
<div class="menuItemImage"><img src="resources/BlackRightChevron.png"/></div>
</div>
The menuContainer div is dynamically appended with clones of the menuItemTemplate. The current click event:
menuContainer.addEventListener('click',menuContainer_click,false);
does not fire when menuContainer overflows in the y-axis.
So I implemented some code found else where on stackoverflow.
Which makes it scrollable but the click events do not run (probably because of the preventDefault()s). Without them I figure every event would be registered as a click instead of a possible move.
Oh, I'm using jQuery mobile and it's UI as well.
Is there any solution to my problem?
The changes I made as per the suggestion:
var scrollStartPosY=0;
document.getElementById(element).addEventListener("touchstart", function(event) {
scrollStartPosY=this.scrollTop+event.touches[0].pageY;
event.preventDefault();
},false);
document.getElementById(element).addEventListener("touchmove", function(event) {
this.scrollTop=scrollStartPosY-event.touches[0].pageY;
event.preventDefault();
move = true;
},false);
document.getElementById(element).addEventListener("touchend", function(event) {
if(move)
move = false;
else
menuContainer_Click(event);
},false);
I'm sure the preventDefaults are wiping out your click. In any case you're using click/mousedown/touchstart to scroll exclusively.
What I think you should do is register a touchend event to trigger whatever you intend to have the current click event do. You may want to verify whether there has been a scroll in the meantime and if so, ignore the touchend. That would differentiate between the two separate intentions of scrolling and clicking.
Decided that iScroll was just an easier solution. Though having difficulty with only one div not scrolling completely to the "bottom".