In my jQuery based code I use a button click event handler.
The problem described on title here occurs sometimes - approximately after 20 successfull clicks on the button. When it occurs, then I have to move mouse pointer out of the button area and move it again back over the button in order click event to be handled.
What could cause this strange behaviour?
Here is the event handler:
function advice() {
rebuildCacheBtnElem.bind("click", function (event) {
event.stopImmediatePropagation();
event.preventDefault();
switch (configBtnAction) {
case CONFIG_ACTION_REBUILD:
rebuildCacheBtnElem.text("Cancel");
configState = CONFIG_STATE_BUSY;
goNextConfigStep(configPages, configBtnAction, CONFIG_ACTION_FINISH);
worker(0, 0);
break;
case CONFIG_ACTION_FINISH:
if (configState == CONFIG_STATE_FINISHED_SUCCESS) {
treeId.populateTree();
}
else if (configState == CONFIG_STATE_BUSY) {
sendCommand({ cancel: cancelGUID }, function (data) {
resetGUI();
});
}
else {
resetGUI();
}
break;
}
window.console.log(configBtnAction);
});
}
Related
Works with mouse click.
key code does not trigger video stop.
keycode after added focus() works but it can cause some problems.
I want keycode and mouse click to work all the time. Independently of each other, it will click on the button when I press the "space" button and when I click the mouse, it will click on the button.
let testKey = document.querySelector(".switch-btn");
["click", "keypress"].forEach(ev => {
testKey.addEventListener(ev, function(e) {
if(ev == "click") {
console.log("click");
if(!testKey.classList.contains("slide")) {
testKey.classList.add("slide");
} else {
}
}
if(e.keyCode === 32) {
console.log("click, space");
}
});
});
<button class="switch-btn">
<span>
Play
</span>
<span>
pause
</span>
<span class="switch"></span>
</button>
The keypress event is deprecated and no longer recommended (See Document: keypress event documentation). Instead you can use the keydown event.
If your intention is to handle the click and keydown events separately then you should check the detail property for the click event handler. If the button is clicked the property will have a value of 1. (See UIEvent.detail documentation)
Unless the user focuses on the button using the tab key, the keydown event is not going to fire your handler. Adding a handler at the container or document level can overcome this. In the code below I have added such a handler and called the stopPropagation method within the handler on the button to prevent the event bubbling up to the document level.
let testKey = document.querySelector(".switch-btn");
document.addEventListener('keydown', function(e) {
if(e.keyCode === 32) {
console.log("document: space pressed");
doTheClassListThing();
}
});
["click", "keydown"].forEach(ev => {
testKey.addEventListener(ev, function(e) {
if(ev == "click" & e.detail == 1) {
console.log("click");
doTheClassListThing();
}
if(e.keyCode === 32) {
e.stopPropagation();
console.log("Button: space keydown");
doTheClassListThing();
}
});
});
function doTheClassListThing() {
console.log('doTheClassListThing() executed');
if(!testKey.classList.contains("slide")) {
testKey.classList.add("slide");
} else {
}
}
<button class="switch-btn">
<span>
Play
</span>
<span>
pause
</span>
<span class="switch"></span>
</button>
I'm not sure I understand the question, but the reason the key doesn't register initially is because the button isn't focused. You could try calling testKey.focus() to ensure it's initially focused.
I do not recommend this approach--forcing focus on the button could create accessibility issues and interfere with other element interactions, but here's a snippet just to demonstrate how focusing the button resolves the issue.
I agree with Terry's comment below, that attaching event handlers on body would be less fraught.
let testKey = document.querySelector(".switch-btn");
testKey.focus();
["click", "keypress"].forEach(ev => {
testKey.addEventListener(ev, function(e) {
if(ev == "click") {
console.log("click");
if(!testKey.classList.contains("slide")) {
testKey.classList.add("slide");
} else {
}
}
if(e.keyCode === 32) {
console.log("click, space");
}
testKey.focus();
});
});
<button class="switch-btn">
<span>
Play
</span>
<span>
pause
</span>
<span class="switch"></span>
</button>
This is a complete revision of my initial question, all unnecessary resources and references were deleted
I am tying the same event listener to 2 different elements: a button and Enter key, and it looks like the following:
var funcelement = function(){
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click');
}
})
What I am trying to do is to prevent propagation of the enter key press if focus is on the submit button(#buttonID) by using preventDefault().
So I tried various combinations to make it work. The following is the latest result on my attempts
$('#inputID').keyup(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})
After I enter a text into an input box and press Enter key, a confirmation window with yes/cancel buttons pops up with focus on yes button. Once I press Enter again, another window confirming that changes were made pops up with Ok button focused on it. Once I press Enter again, everything I need is being made.
However, there is one problem: after the last step is done, I am going back to the if (!hasfocus) line.
How do I prevent that from happening? Once the stuff I need is done - I don't want to go into that line again.
You can pass a parameter to into the function and stop the propagation there like so:
var funcelement = function(event, wasTriggeredByEnterKey){
if (wasTriggeredByEnterKey && $('#buttonID').is(':focus')) {
event.stopPropagation;
}
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click', [true]);
}
}
)
UPDATE
In order to answer your revised issue, you should use the "keydown" event rather than "keyup" when working with alerts. This is because alerts close with the "keydown" event but then you are still triggering the "keyup" event when you release the enter key. Simply change the one word like this:
$('#inputID').keydown(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})
on clicking the outside the window the mousemove event has to be stopped`,i have detected the click outside the window on mouseleave,but how to prevent the default even?in Javascript
onTextContainerMouseLeave: function (e) {
if (this.curDown == true) {
var value;
$(window).on('mouseup', function (e) {
this.curDown = false;
e.preventDefault();
e.stopPropagation();
return false;
});
}
},
Put a condition inside your on-click that is true if the mouse was inside the control (which you already have according to what is written). If the condition is true then go on with the on-click events. Otherwise nothing happens.
$(window).on('mouseup', function (e) {
if (yourconditionhere) {
//Execute your code here --
}
});
I have a <ul> element that opens a bootbox when it's clicked. Double clicking this element triggers the onclick in JQuery twice
$("#email-list").on("click", ".list-group-item", function (e) {
bootbox.confirm("Send a forgotten password email to " + email + "?", function (result) {...}}
I tried using 'e.preventDefault()'
$(document).ready(function () {
$("#email-list").dblclick(function (e) {
e.preventDefault();
});
});
I even tried disabling clicking on the element but both failed. The bootbox still appears twice.
$("#email-list").bind('click', function () { return false; });
//...do stuff
$("#email-list").unbind('click');
Anyone has a suggestion?
Another solution can be to add:
bootbox.hideAll();
to hide any other bootboxes right before showing the bootbox like so:
bootbox.hideAll();
bootbox.confirm("Some Message " , function (result){/*do stuff*/}
Try this:
$("#email-list").on("click", ".list-group-item", function (e) {
if(!$('#myModal').is(':visible')){
$('#myModal').modal('show');
}
e.preventDefault();
}
Use the click event, then you can replace
e.preventDefault();
with
e.stopPropagation();
or
return false;
I figured the best way to do this is to separate the two events; onclick and dbclick, I used something like this, I hope it will save someone some time:
var DELAY = 700, clicks = 0, timer = null;
$(function () {
$("#email-list").on("click", ".list-group-item", function (e) {
clicks++; //count clicks
if (clicks == 1) {
//do stuff
clicks = 0; //after action performed, reset counter
}, DELAY);
} else {
clearTimeout(timer); //prevent single-click action
clicks = 0; //after action performed, reset counter
return false;
}
})
.on("dblclick", function (e) {
e.preventDefault(); //cancel system double-click event
});
}
My website is responsive and for narrow views the navigation switches to an icon that shows the nav on click. To close the navigation panel you can click the icon again or anywhere outside of the nav modal. This is the JS to manage clicks outside of the nav modal:
$(document).mousedown(function(e) {
var clicked = $(e.target);
if (clicked.is("#navigation") || clicked.parents().is("#navigation") || clicked.is("#hamburger-nav-link")) {
return;
} else {
$("#hamburger-nav-link").removeClass("hamburger-nav-active");
$("#navigation").removeClass("mobile-nav");
}
});
On mobile devices (well, my iPhone) when you tap the icon it closes the nav modal, but when you tap outside the nav modal nothing happens.
I tried implementing code from this SO question to map touch events to click events:
JavaScript mapping touch events to mouse events
However this didn't work for me.
I pasted the code below the $(document).mousedown() function and it's all within a generic jQuery function. I've pasted the code below so you can see the whole thing. This file is called at the end of every page before the closing tag.
Any help is greatly appreciated, thanks!
$(function() {
// Mobile nav
$("#hamburger-nav-link").click(function() {
if ($("#navigation").hasClass("mobile-nav")) {
$(this).removeClass("hamburger-nav-active");
$("#navigation").removeClass("mobile-nav");
}
else {
$(this).addClass("hamburger-nav-active");
$("#navigation").addClass("mobile-nav");
}
return false;
});
// Close modal if click event is outside of it
$(document).mousedown(function(e) {
var clicked = $(e.target);
if (clicked.is("#navigation") || clicked.parents().is("#navigation") || clicked.is("#hamburger-nav-link")) {
return;
} else {
$("#hamburger-nav-link").removeClass("hamburger-nav-active");
$("#navigation").removeClass("mobile-nav");
}
});
function touchHandler(event)
{
var touches = event.changedTouches,
first = touches[0],
type = "";
switch(event.type)
{
case "touchstart": type = "mousedown"; break;
case "touchmove": type="mousemove"; break;
case "touchend": type="mouseup"; break;
default: return;
}
//initMouseEvent(type, canBubble, cancelable, view, clickCount,
// screenX, screenY, clientX, clientY, ctrlKey,
// altKey, shiftKey, metaKey, button, relatedTarget);
var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);
first.target.dispatchEvent(simulatedEvent);
event.preventDefault();
}
function init()
{
document.addEventListener("touchstart", touchHandler, true);
document.addEventListener("touchmove", touchHandler, true);
document.addEventListener("touchend", touchHandler, true);
document.addEventListener("touchcancel", touchHandler, true);
}
});
Got it to work by simply binding the click and touchend event to the document. And then referencing the original hide/show function when the icon is clicked. HOWEVER, this introduced another problem of where clicking on the icon sometimes will double fire and you get weird behavior. Like closing and then reopening. I'm going to address this separately though. So, here's the answer:
The two functions touchHandler(event) and init() and the $(document).mousedown(function(e) { ... }); function and $("#hamburger-nav-link").click(function() { ... }); function are replaced with the following:
var navModalView = function() {
if ($("#navigation").hasClass("mobile-nav")) {
$("#hamburger-nav-link").removeClass("hamburger-nav-active");
$("#navigation").removeClass("mobile-nav");
}
else {
$("#hamburger-nav-link").addClass("hamburger-nav-active");
$("#navigation").addClass("mobile-nav");
}
return false;
}
$(document).bind("click touchend", function(e) {
var targetEl = $(e.target);
if (targetEl.is("#navigation") || targetEl.parents().is("#navigation")) {
return;
}
else if (targetEl.is("#hamburger-nav-link")) {
navModalView();
event.preventDefault();
}
else {
$("#hamburger-nav-link").removeClass("hamburger-nav-active");
$("#navigation").removeClass("mobile-nav");
}
});
I'm using this for my web project.
may be this will work for mobile.
try once :)
//GET ALL CLICK EVENT
$('html').click(function() {
popmenu();
});
//Popupmenu Hide Function
function popmenu(){
var popmenuVisible = $(".popmenuclass").is("visible").toString();
if (popmenuVisible=="true") {
$(".popmenuclass").hide();
}
}
//IF you click on popupmenu then disable popmenu closing
$(".popmenuclass").click(function(event){ event.stopPropagation();});