Detect Ctrl + click in event handler - javascript

I want to replace detecting a double-click with detecting Ctrl-click, but I do not know how to do so.
$(document).ready(function () {
$(document).dblclick(function (e) {
var target = (e && e.target) || (event && event.srcElement);
var tag = target.tagName.toLowerCase();
if (!(tag == 'input' || tag == 'textarea' || tag == 'img')) {
openIfSelected("dblclick");
}
});
});

You are looking for the jQuery .click() method and the MouseEvent.ctrlKey property.
You could do something like:
$(document).ready(function () {
$(document).click(function (e) {
if(e.ctrlKey){
var tag = e.target.tagName.toLowerCase();
if (!(tag == 'input' || tag == 'textarea' || tag == 'img')) {
openIfSelected("dblclick"); //Still pass "dblclick", but upon Ctrl-click
}
}
});
});
function openIfSelected(reason){
//This is now only called upon Ctrl-click, but the "reason" remains "dblclick".
console.log('Called "openIfSelected" with reason: ' + reason);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><kbd>Ctrl</kbd>-Click me</div>
Note:
You used the code:
var target = (e && e.target) || (event && event.srcElement);
This is strange as written. You were probably attempting to use window.event. However, this is not needed because you are using jQuery, which normalizes the event object that is passed to event handlers, specifically so you don't have to do things like this. In addition, the tags you are using declare this question as a Google Chrome extension issue. If that is the case, and you weren't using jQuery, then you would still not need to do this as you do not need to account for the use of the code in older browsers (e.g. IE).

I fixed like this. Big thanks Makyen.
$(document).ready(function () {
$(document).click(function (e) {
if(event.ctrlKey){
var target = event.srcElement;
var tag = target.tagName.toLowerCase();
if (!(tag == 'input' || tag == 'textarea' || tag == 'img')) {
openIfSelected("dblclick");
}
}
});
});

Related

Javascript Alternative for Detecting Select Value Which Doesn't Use Xpath in IE?

I had a working solution to grab the value of a select using Xpath. Found out IE doesn't support Xpath and it throws an "XpathResult is undefined" error!!! I'm using a TMS (DTM) so I have to inject my code into the web app. I can't touch the web app code. In researching this, I read that a library (https://github.com/google/wicked-good-xpath) could fix this but I don't have that option. If you go to https://apply.essexcredit.com/ on the first page, you'll see only one select "What type of loan are you interested in? ". I need to set an event listener on this element and grab the value being selected (RV or Boat etc). Is there any other approach I can use to attach an event listener to this and grab the value? Here is the current code I had that works when Xpath is supported:
function _dtmSetProductSel() {
window.addEventListener("click", function() {
var prodSel = document.evaluate("//form/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div[#class='option-selected']", document, null, XPathResult.ANY_TYPE, null).iterateNext();
if (prodSel) {
var currProd = prodSel.getAttribute("title");
if (currProd == "RV" || currProd == "Boat" || currProd == "Auto" || currProd == "Auto-IBG" || currProd == "Investment Line of Credit") {
sessionStorage.setItem("_dtmSelProd", currProd);
}
} else {
setTimeout(_dtmSetProductSel, 1000);
}
});
};
Check if you can use document.querySelector as shown below.
var prodSelCSS = document.querySelector("form div.option-selected")
function _dtmSetProductSel() {
window.addEventListener("click", function() {
var prodSel = document.getElementsByClassName("option-selected");
var tryAgain = true;
for(var i=0;i<prodSel.length;i++) {
var currProd = prodSel[i].getAttribute("title");
if(currProd && (currProd == "RV" || currProd == "Boat" || currProd == "Auto" || currProd == "Auto-IBG" || currProd == "Investment Line of Credit")) {
sessionStorage.setItem("_dtmSelProd", currProd);
tryAgain = false;
break;
}
}
if(tryAgain) {
setTimeout(_dtmSetProductSel, 1000);
}
});
};

Deleting Single Element From Same Function

For the following code:
document.getElementById('text_one').onkeypress = function (e) {
if (!e) e = window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == '13') {
text = document.getElementById('text_one').value;
if (text == "" || text === null || text.length > 50) {
$('#error_msg').show('slow');
document.getElementById('text_one').disabled = true;
document.getElementById('text_one').value = "";
return false;
} else {
$('#list').append('<li>' + text + '</li><br />');
document.getElementById('text_one').value = "";
}
}
};
How would one go about making a function that deletes the element which was clicked? I was thinking that you could somehow create a specific number that increases every time the function is run and use that number to create custom ID's but I'm not sure how to do that.
JS Fiddle: http://jsfiddle.net/2dd5L/ (The CSS is messed up for some reason)
Since you are using jQuery it's very simple (in pure JS also just 2 more lines of code):
$('#list').on('click', 'li', function() {
$(this).remove();
});
Demo: http://jsfiddle.net/2dd5L/1/

Do not scroll page down when spacebar is clicked?

As you may know some browsers have this default functionality to scroll page down when spacebar is clicked. I usually like this feature, but due to nature of my website I need to get rid of it.
I've been using
window.onkeydown = function(e) {
return !(e.keyCode == 32);
};
which eats all spacebar functionality and gets the job done, however if user is typing in a comment or a search query and they press spacebar no space is added in a text as this functionality has been eaten up.
So is there a way to disable just the scrolling part and leave all other functionality as it is?
window.onkeydown = function(e) {
return !(e.keyCode == 32 && (e.target.type != 'text' && e.target.type != 'textarea'));
};
Maybe try this:
window.onkeydown = function(e) {
if(e.keyCode == 32 && e.target.nodeName.toUpperCase() === "BODY") e.preventDefault();
};
Probably need to equalise for IE:
window.onkeydown = function(e) {
var evt = e || window.event;
var elem = evt.target || evt.srcElement;
if(e.keyCode == 32 && elem.nodeName.toUpperCase() === "BODY") {
evt.preventDefault();
return false;
}
};
(untested)
But you would need to attach an event to/within each iframe, using iframeref.contentWindow.
After the page and iframes have loaded you could loop through the frames[] collection.

Is there a way in Javascript to determine if no elements are in focus?

I'm building some hotkeys into a page of my HTML:
$(document).bind('keypress', function (e) {
var event = (e.keyCode ? e.keyCode : e.which);
if (event == LETTER_P) {
// go to another page
}
}
But the problem is that if they are entering text on the page (in a textbox element, etc) and hit the letter 'P', they are off to another page. I only want the redirection to happen if they are not in any elements.
document.activeElement is supported by all major browsers these days. If no element is in focus then activeElement will return the document body, so:
if (document.activeElement === document.body) {
// Nothing is in focus
}
You can try something like this:
$(document).bind('keypress', function (e) {
var event = (e.keyCode ? e.keyCode : e.which);
if (event == LETTER_P && document.activeElement.tagName == "input") {
// go to another page
}
}
My addition to your code doesn't require any library.
if ( $('input:focus, select:focus').length){
// there is a focused element which would respond to a keypress
}
You can use the :focus selector in jQuery.
if ( $( "input:focus, textarea:focus" ).length ) {
// there is a focused element
}

Javascript event handler on body but not on input

I have the following event handler
document.addEventListener('keydown', handleBodyKeyDown, false);
HOW DO i prevent it from occurring when inside a input box
Within your handleBodyKeyDown function, check if
event.target.tagName.toUpperCase() == 'INPUT'
(or 'TEXTAREA').
Note: For older versions of IE, use event.srcElement.tagName.
Like so:
document.addEventListener('keydown', handleBodyKeyDown, false);
function handleBodyKeyDown(event)
{
var e = event || window.event,
target = e.target || e.srcElement;
if (target.tagName.toUpperCase() == 'INPUT') return;
// Now continue with your function
}
P.S. Why are you using addEventListener if you have jQuery on the page? In jQuery, all of this gets sorted out for you:
$(document).on('keydown', ':not(input)', function(e)
{
// Your code goes here...
});
In your handleBodyKeyDown method, check to see if the event originated on an input element:
function handleBodyKeyDown(event) {
if (event.target.tagName.toUpperCase() === 'INPUT') {
return; // do nothing
}
// do the rest of your code
}
Note that the toUpperCase call is necessary because the conditions that determine the case of the tagName property are quite complicated and sometimes all but uncontrollable.
See event.target at MDN.
If you are using jQuery you can try this which uses is() method to test the target element is input then do nothing.
function handleBodyKeyDown(event) {
if ($(event.target).is("input")) {
return;
}
else{
//Do your stuff here
}
}
This worked for me:
const fromInput = event => event.srcElement instanceof HTMLInputElement;
function handleBodyKeyDown(event) {
if(fromInput(event))
return;
// do your magic here
}
You could do something like:
handleBodyKeyDown = function(e) {
var e = e || window.event
if (e.target.tagName != "INPUT") {
// handle this since it isn't input
}
}
Sometimes (as to me) it is better not to prevent it to occur, but to ignore in the event cases, when it occured in the input. It's looks like this is also your case as well.
Just inspect evt.target || evt.srcElement property (modern frameworks do this normalization work for you, so, most probably this will be called target) whether it's input or not. If not, just ignore.
QuirksMode tells you how to get an event's target. You can check that it is not an input:
function doSomething(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
if( targ.tagName != "INPUT" ) {
//Perform your action here
}
}
Your question is tagged jQuery, in which case you can just test event.target as the framework normalizes this for you.
$(document).bind("keydown", function (event) {
if(event.target.tagName != "INPUT") {
//Do something
}
});
HandleBodyKeyDown function will be invoked in any case. You can not prevent its call on the method of recording as you indicated. You can only add a logic for checking if this an 'input' and return. Additionaly (if needed) you can prevent it from bubble up:
function handleBodyKeyDown(ev) {
ev=ev||event;
var sender=ev.target||ev.srcElement;
if(sender.tagName.toLowerCase()==="input") {
if(ev.stopPropagation)ev.stopPropagation();
else ev.cancelBubble=true; // for IE8 or less
return true; // do not prevent event from default action
}
// your code for global keydown
}
If you're using Prototype (which you have tagged but you also have two other frameworks tagged) then the event can be registered and filtered in one like this:
document.on('keydown', ':not(input)', handleBodyKeyDown);

Categories

Resources