Javascript Jquery - Dont close if child element is clicked - javascript

Ok i have a script that closes all my divs unless those divs have this class name. The following script works fine:
window.onclick = function(ev){
if((ev.target.className !== 'ddHeader') && (ev.target.className !== 'ddSubmenu')&&
(ev.target.className !== 'ddContainer')&& (ev.target.className !== 'ddItem')){
delay_close_sub();
}
};
So now i need to do the same thing with a child element. I would like to just add it to the above code similar to this:
window.onclick = function(ev){
if((ev.target.className !== 'ddHeader') && (ev.target.className !== 'ddSubmenu')&&
(ev.target.className !== 'ddContainer')&& (ev.target.className !== 'ddItem') &&
ev.target.element !== 'ddHeader > input){
delay_close_sub();
}
};
I added: ev.target.element !== 'ddHeader > input') to the end but it does not work. How would i make this work? I want to make sure that when the input field inside the ddHeader div is click it doesn't trigger the "delay_close_sub() function.
Thanks for any help.

You can use JQuery in a much more efficient compact way:
$(window).click(function(ev){
if(!$(ev.target).is('.ddHeader,.ddSubmenu,.ddContainer,.ddItem,.ddHeader > input'))
delay_close_sub();
});
Which means if the event target doesn't match any of the comma-separated selectors, close your thing.

Use getElementsByTagName:
ev.target.element.getElementsByTagName('input').length == 0

Related

jQuery separate dblclick events inside and outside of a div element

I'm developing a local site for content creation, and I'd like to use javascript's double click functionality.
I'd like to rotate through full screen background images when the user double clicks outside of the divs with names/ids bigwrapper or bigwrapper2. When the user clicks #bigwrapper or #bigwrapper2, I'd like it to .toggle(); each one to hide/show one or the other.
Here's my updated code (thanks lordvlad):
$(function() {
$( "#bigwrapper" ).draggable();
$( "#bigwrapper2" ).draggable();
var SacramentoBG = ['nightcap.jpg','Tower_Bridge_Sacramento_edit.jpg'],
counter =0;
$('html').dblclick(function (event) {
if (event.target.id != "bigwrapper" && event.target.id != "bigwrapper2") {
counter = (counter+1) % SacramentoBG.length;
$('html').css('background-image', "url("+SacramentoBG[counter]+")");
} else {
$("#bigwrapper").toggle();
$("#bigwrapper2").toggle();
}
});
});
UPDATE: The solution below to add 'event' inside the function partially helped, as the backgrounds rotate properly, however the #bigwrappers aren't toggling as intended (the else condition). See: http://artfuladvection.com/project/NOAA/ndfdGraph/bloom.php Ideas?
Thanks!
that's because the dblclick function doesn't know about the event variable. try this
$('html').dblclick(function (event) {
The complete answer that worked for me was that I needed to stop excluding specific classnames/ids and instead exclude entire element tags. Alternatively, I could just use if (event.target.TagName == 'BODY') {}
$('body').dblclick(function (event) {
if (event.target.tagName != 'DIV' && event.target.tagName != 'IMG' && event.target.tagName != 'TABLE' && event.target.tagName != 'HR' && event.target.tagName != 'SMALL' ) {
counter = (counter+1) % SacramentoBG.length;
$('html').css('background-image', "url("+SacramentoBG[counter]+")");
} else {
$("#bigwrapper").toggle();
$("#bigwrapper2").toggle();
}
});

Finding the specific Tag a

My HTML is:
<a id="showSlotsByLocation_" href="#" style="color:blue;" onclick="confirmAppt('28/05/2013','364301');">14.00 - 14.15</a>
<a id="showSlotsByLocation_" href="#" style="color:blue;" onclick="confirmAppt('28/05/2013','364303');">14.15 - 14.30</a>
Id name are same on all links. This is the main difficulty.
I want to click second link my javascript code are configure web browser is
if (location.pathname == "/abc")
{
//alert('location found') this is ok found;
var el = document.getElementsByTagName("a");
for (var i=0;i<el.length;i++)
{
if (el.id == 'showSlotsByLocation_' && el.innerText.isEqual('14.15 - 14.30') && el.outerHTML.contains("confirmAppt('28/05/2013'"))
{
alert('link found') \\this condition not match;
el.onclick();
}
}
}
What do i do to match the condition?
You can't have two element with the same ID, IDs are unique.
When you will have changed the IDs, you'll can access them simply using document.getElementById('idOfYourElement')
EDIT:
First of all, you need to declare a "current" variable that takes the current element in the loop, you can't use el.id because el is a collection of HTMLElements! I'm sorry I didn't noticed it before.
So you need this(define the variable inside the for loop, just before the if statement):
var current = el[i];
Now that you have defined it, change this whole line with the code below.
if (el.id == 'showSlotsByLocation_' && el.innerText.isEqual('14.15 - 14.30') && el.outerHTML.contains("confirmAppt('28/05/2013'"))
I think this is the code that stops you. There are no functions called isEqual and contains in JS.
if (current.id == 'showSlotsByLocation_' && current.textContent === '14.15 - 14.30' && current.outerHTML.indexOf("confirmAppt('28/05/2013'") !== -1)
One last thing: innerText isn't a valid cross browser property, use textContent instead.
MDN Reference
Updated JS code
if (location.pathname == "/abc")
{
var el = document.getElementsByTagName("a");
for (var i=0;i<el.length;i++)
{
var current = el[i];
if (current.id == 'showSlotsByLocation_' && current.textContent === '14.15 - 14.30')//I'm not sure about this one, in case you want it just remove the comment and the last parenthesis && current.outerHTML.indexOf("confirmAppt('28/05/2013'") !== -1)
{
alert('link found');
current.click();
}
}
}

Incorrect array value

I have an array (spliced to size 2) that keeps track of what user click (first, last). first and last elements are unique.
I am trying to load content based on what user clicked. The weird thing that is happening is that I don't see the updated array unless I do 2 console.logs. If 1 log is done the array doesn't get updated. I'm guessing this has something to do with array execution/manipulation time.
The way I debug is to a click handler to document and click to see the array value. Any suggestions or tips?
I never had this issue before. Thanks.
var clicksInfo = [];
$('#a, #b, #c').on('click', function(e){
// array: add, splice
if(jQuery.inArray($(this).attr('id'), clicksInfo) == -1){
clicksInfo.push($(this).attr('id'));
if(clicksInfo.length == 2){
// might do something
}else if(clicksInfo.length == 3){
clicksInfo.splice(0,1);
}
}else{
clicksInfo.splice(0,1);
clicksInfo.push($(this).attr('id'));
}
if($(this).attr('id') == 'a'){
// do stuff.
}else if($(this).attr('id') == 'b'){
// do stuff.
}else if($(this).attr('id') == 'c'){
// do stuff.
}
});
$(document).on('click', function(){
console.log('clicksInfo', clicksInfo);
// console.log('clicksInfo', clicksInfo);
});
Strings are strings, arrays are arrays, even in a console.log, so when doing :
console.log('clicksInfo', clicksInfo);
thats a string, a comma, and then an array ?
try doing:
console.log('clicksInfo : '+ clicksInfo);
to show the string representation, or to show the array as an object, don't mix it with other strangeness:
console.log(clicksInfo);
The problem you are facing is that events that occur are not guaranteed to execute in a specific order. Either click handler could be executed first, though in most browsers your handler for #a, #b, #c would be executed first.
While you could try to use setTimeout to wait long enough to synchronize your data, your code is quite likely to break.
If you want to handle a click in both cases, my recommendation would be to remove the handler for #a, #b, and #c. Use the document click handler only, pass in the event declaration, and then check the ID of the clicked element in your handler to invoke the first code. You are then guaranteed to have updated data before your second block of code runs. Something like this:
var clicksInfo = [];
$(document).on('click', function(e){
if (e.target.id === "a" || e.target.id === "b" || e.target.id === "c") {
// array: add, splice
if (jQuery.inArray(e.target.id, clicksInfo) == -1){
clicksInfo.push(e.target.id);
if(clicksInfo.length == 2){
// might do something
} else if(clicksInfo.length == 3){
clicksInfo.splice(0,1);
}
} else {
clicksInfo.splice(0,1);
clicksInfo.push(e.target.id);
}
if(e.target.id === 'a'){
// do stuff.
}else if(e.target.id === 'b'){
// do stuff.
}else if(e.target.id === 'c'){
// do stuff.
}
}
console.log('clicksInfo', clicksInfo);
});
JSFiddle here.

Load a Javascript function when typing something certain up until a space

For example:
When someone types # it will ready the function.
On Twitter for example, shows something when someone types #USERNAME then after the space, they don't show anything.
Here an javascript example:
document.getElementById('test').onkeyup = function(oEvent) {
if (typeof oEvent == 'undefined') oEvent = window.event; // IE<9 fix
if (oEvent.keyCode != 32) return; // stop if character is not the space
if (/#USERNAME /.test(this.value)) { // check if #-template is available
this.value = this.value.replace(/#USERNAME /g, 'Dirk '); // replace it
}
}
Also see this jsfiddle.
=== UPDATE ===
Here an jQuery alternative:
$('#test').keyup(function(oEvent) { // set (keyup) event handler
if (oEvent.keyCode != 32) return; // stop if character is not the space
if (/#USERNAME /.test($(this).val())) { // check if #-template is available
$(this).val($(this).val().replace(/#USERNAME /g, 'Dirk ')); // replace it
}
});
Also see this jsfiddle.
Perhaps you can try an onkeypress event on pressing the spacebar.

How can I disabling backspace key press on all browsers?

I'm trying to disable the backspace button on an order page in all cases except when a textarea or text input is an active element to prevent users from accidentally backing out of an order. I have it working fine in most browsers, but in IE (testing in IE9, both regular and compatibility mode) it still allows the user to hit the backspace and go to the previous page.
Here's the code:
$(document).keypress(function(e){
var activeNodeName=document.activeElement.nodeName;
var activeElType=document.activeElement.type;
if (e.keyCode==8 && activeNodeName != 'INPUT' && activeNodeName != 'TEXTAREA'){
return false;
} else {
if (e.keyCode==8 && activeNodeName=='INPUT' && activeElType != 'TEXT' && activeElType != 'text'){
return false;
}
}
});
Any advice on what I'm doing wrong here?
Thanks!
I think you're overcomplicating that. Rather than checking for an active element, find the event target instead. This should give you the information you need. It's also better to use keydown rather than keypress when there is no visible character. Finally, it's better to use e.preventDefault() for better granularity.
$(document).keydown(function(e) {
var nodeName = e.target.nodeName.toLowerCase();
if (e.which === 8) {
if ((nodeName === 'input' && e.target.type === 'text') ||
nodeName === 'textarea') {
// do nothing
} else {
e.preventDefault();
}
}
});
NB I could have done this the other way round, rather than an empty if block and all the code going in the else block, but I think this is more readable.
Instead of keypress, try the keydown function, it will fire before the actual browser based hook. Also, putting in a preventDefault() function will assist in this. IE :
$(document).keydown(function(e){
e.preventDefault();
alert(e.keyCode);
});
Hope this helps.
The most Simple thing you can do is add the following one line in the very first script of you page at very first line
window.history.forward(1);
Most examples seem to be for the JQuery framework - Here an example for ExtJS
(I've been getting a lot of downvotes for this recently as the question now has JQuery tag on it, which it didn't previously. I can remove the answer if you like as isn't for JQuery but it's proven to help others not using that framework).
To use this add this code block to your code base, I recommend adding it inside the applications init function().
/**
* This disables the backspace key in all browsers by listening for it on the keydown press and completely
* preventing any actions if it is not which the event fired from is one of the extjs nodes that it should affect
*/
Ext.EventManager.on(window, 'keydown', function(e, t) {
var nodeName = e.target.nodeName.toLowerCase();
if (e.getKey() == e.BACKSPACE) {
if ((nodeName === 'input' && e.target.type === 'text') ||
nodeName === 'textarea') {
// do nothing
} else {
e.preventDefault();
}
}
});
Use e.which instead of e.keyCode; jQuery normalizes this value across browsers.
http://api.jquery.com/keydown/
To determine which key was pressed,
examine the event object that is
passed to the handler function. While
browsers use differing properties to
store this information, jQuery
normalizes the .which property so you
can reliably use it to retrieve the
key code.
Then, use e.preventDefault(); to prevent the default behaviour of moving to the previous page.
<html>
<head>
<script type="text/javascript">
function stopKey(evt) {
var evt = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if ((evt.keyCode == 8) && (node.type!="text")) {return false;}
}
document.onkeypress = stopKey;
</script>
</head>
<body onkeydown="return stopKey()">
<form>
<input type="TEXTAREA" name="var1" >
<input type="TEXT" name="var2" >
</form>
</body>
</html
I had to add the onDownKey attribute to the body in order to get editing keys to go to the functions.
$(document).keydown(function(e) {
var elid = $(document.activeElement).is('input');
if (e.keyCode === 8 && !elid) {
return false;
}
});
Hope this might help you
Seems like the "backspace" will also act as "navigation back" if you have selected radio buttons, check-boxes and body of document as well. Really annoying for forms - especially when using post. All the form could be lost with one slip of the "backspace" key -_- ...
Honestly... who's idea was it to allow the "backspace as a navigational "back" button!!! really bad idea in my opinion.
I disable the "backspace" default on anything that is not a text area or text field - like this:
$(document).keydown(function(e){
console.log(e.keyCode+"\n");
var typeName = e.target.type;//typeName should end up being things like 'text', 'textarea', 'radio', 'undefined' etc.
console.log(typeName+"\n");
// Prevent Backspace as navigation backbutton
if(e.keyCode == 8 && typeName != "text" && typeName != "textarea"){
console.log("Prevent Backbutton as Navigation Back"+typeName+"\n");
e.preventDefault();
}
//
})
Not sure where else one would want the normal behavior of a back-button other than in these two areas.
document.onkeydown = KeyPress;
function KeyPress(e) {
if (!e.metaKey){
e.preventDefault();
}
}

Categories