I am using jQuery to manage a keypress on my document and open a new window:
$(document).keypress(function(event){
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13') {
// Open a new window
}
});
The problem is I have a jQuery accordion that I want to stay CLOSED until a user explicitly clicks on it. I managed to get the accordion to not open on the 'enter' keypress, but if another window opens in a new tab and becomes active, the accordion opens.
Problem is I have no idea to find out what even is getting fired on the accordion that allows it to open.
Is there a way to nuke all events on an element and then just add back the one that you want (in my case the mouse down or click)? Or to report which events are being handled by that element so that I could just try to unbind that one?
Have you tried reading through the "active" portion in
http://api.jqueryui.com/accordion/#option-active ?
i.e Setting active to false will collapse all panels
I've found this scriptlet to be really helpful when trying to find out which events are attached to which dom elements. I might help you work out what's going on - Visual Event
Related
Background
Recently I plan to write my own js lib which mainly refer to Bootstrap v3. I stuck in some code, please help.
Problem
In Bootstrap v3 tab.js, I have no idea what's the effect about two segments below
Segment1:
// line 39 - 47
var hideEvent = $.Event('hide.bs.tab', {
relatedTarget: $this[0]
})
var showEvent = $.Event('show.bs.tab', {
relatedTarget: $previous[0]
})
$previous.trigger(hideEvent)
$this.trigger(showEvent)
Segment2:
// line 55 - 62
$previous.trigger({
type: 'hidden.bs.tab',
relatedTarget: $this[0]
})
$this.trigger({
type: 'shown.bs.tab',
relatedTarget: $previous[0]
})
My Try
Withdraw the single tab.js in my script and it works, which means two segmens above not rely on other widget/util (expect the transition effect)
I delete two segments in tab.js and it works still. I have no idea what's the purpose of these two segments?
I review the jQ API: $.Event & trigger, what i can got is two segments define some custom function and trigger.
Help
What's the purpose of these two segments? Thanks a lot.
Bootstrap has created a series of tools that it wants to make as extensible as possible. This means, that they want to allow the developer using their tools to "listen" to a number of "Events" and perform follow up actions.
The two listed in your question allow the developer to "hook" into either the "show" event or "hide" event. (There are actually 2 more provided by bootstrap ["shown" and "hidden"]). From the Documentation these events are fired when:
show.bs.tabThis event fires on tab show, but before the new tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.
shown.bs.tabThis event fires on tab show after a tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.
hide.bs.tabThis event fires when a new tab is to be shown (and thus the previous active tab is to be hidden). Use event.target and event.relatedTarget to target the current active tab and the new soon-to-be-active tab, respectively.
hidden.bs.tabThis event fires after a new tab is shown (and thus the previous active tab is hidden). Use event.target and event.relatedTarget to target the previous active tab and the new active tab, respectively.
An example of how this might be used could be the case of "When the user clicks on a tab, stop playing the youtube video in the previous tab by refreshing its src". The code for something like this could be
$('#myTabs').on('show.bs.tab', function(event){
// previous tab
if(event.relatedTarget){
var youtubeIframe = $(event.relatedTarget).find('iframe');
var src = youtubeIframe.attr('src');
youtubeIframe.attr('src', 'about:blank');
youtubeIframe.attr('src', src);
}
});
Alternatively, you could target the tab that was just "hidden". Rather than looking to the current tab and using its relatedTarget we would use the hide.bs.tab event and use event.target, like so:
$('#myTabs').on('hide.bs.tab', function(event){
// current tab
if(event.target){
var youtubeIframe = $(event.target).find('iframe');
var src = youtubeIframe.attr('src');
youtubeIframe.attr('src', 'about:blank');
youtubeIframe.attr('src', src);
}
});
NB: Im sure there are better ways to stop playing youtube videos. This is used as example code.
Anchor tag is opening in new window while we have clicked middle button of mouse. I want to disable this new window/tab. The belwo provided code is working in chrome.
$("a").on('click', function(e) {
if( e.which == 2 ) {
e.preventDefault();
}
});
Checked following links:
Triggering onclick event using middle click
Disable middle mouse button for modal dialog
According to some better is to change anchor tag to some other tabs, but I need the default behavior of anchor tab in left click, I need to disable middle and right clicks. Somebody help me to solve this.
Note: Many questions are asked regarding the same, but this exact issue is not yet asked.
This is not working in Firefox. I need to solve this issue in Firefox too.
fiddle
This is for blocking middle clicking entire document on firefox. You can check whatever element by e.target. Its need jQuery, but u could also use vanilla js
$(document).on('auxclick', function(e) {
if( e.button == 1 )
alert('Its blocked globally');
e.preventDefault();
return false;
}
})
Pure html solution, no javascript:
Click me
I'm having a pretty big problem trying to create navigation on my page. If the mouse enters an element then it selects it, then if you use arrow keys it will select the elements relative to the selected one. However this is an issue when the arrow keys cause the page to scroll, because (depending on the position of the mouse) it will select the appropriate element then instantly select the item the mouse is now over after the page moved (even if you didn't move the mouse).
Does anyone know how to fix this problem? I tried tinkering with it but none of my solutions seemed to work. Any help is appreciated, thank you.
It sounds like you should bind the "select when mouse enters" event on mousemove and unbind said event on mousestop. mousestop does not exist on its own, so you will have to create it somehow or use a plugin (there are at least a few out there such as https://github.com/richardscarrott/jquery-mousestop-event/ ). I think this would be the simplest solution, but your UI seems a little bizarre (you want the arrow key to scroll the page normally and "select" an element that's possibly larger than the scroll size?)
Not sure I completely understand, but you should be able to use a combination of the mousemove and keypress events:
$("#element").mousemove(function(e){
alert("mouse moved");
});
$("#element").keypress(function(e){
if (e.keyCode == 38 || e.keyCode == 40){ //up & down arrow keys
e.preventDefault();
}
});
Try returning false from the keyboard event handler where you check for arrow keys:
element.onkeypress = function(ev) {
// ...
return false;
}
This will prevent the "default behavior" that the browser has for the event, which is to scroll. This works also for links, for example: if you return false from a click event handler for a link, clicking the link will not automatically follow it.
Actually, there was (is still) a bug in jQuery: http://bugs.jqueryui.com/ticket/4511.
The reason for this behavior (from the bug description comments): "The dialog itself binds keydown event to itself for closing the dialog on ESC; in addition, the dialog overlay binds a keydown event to the document, without filtering to close only the active dialog."
I cannot come up with an idea of an acceptable workaround. Is there anyone who has had to deal with it yet?
Very simple - upon creating a modal dialog, run this:
$([document, window]).unbind('.dialog-overlay');
If you create more then one modal dialog, hitting ESC will close the top one only.
Then once you focus on the bottom dialog, hit ESC and it will close it as well.
Hope this helped!
P.S. jQuery UI developers should add an option when you want all dialogs close at once upon hitting ESC key or only the focused ones.
Easiest thing is I have added event.stopPropagation(); in close function before return self; in jquery.ui.dialog.js file. And I am done with problem of closing dialog boxes one by one on escape keydown. Let me know if anyone find any better solution.
EDITED:
this need to add because while clicking on close button event object is undefined.
if(typeof event != 'undefined'){
event.stopPropagation(); }
The root of the problem is that jQuery UI keydown event propagates through all dialogs. A fix in the original jQueryUI Dialog code would be to add event.stopPropagation() when topmost dialog was successfully closed and check event.isPropagationStopped() at the beginning of the same keydown event.
As a workaround I did, thanks for Jazzer, the following.
Set dialog option closeOnEscape to false
When dialog gets created, append:
//newDialog is dialog's content, e.g. var newDialog = $('my dialog content>');
newDialog.keydown(function(event) {
if (mydialogs.hasOpenDialogs() &&
event.keyCode &&
event.keyCode === $.ui.keyCode.ESCAPE) {
$(newDialog).dialog("close");
event.preventDefault();
event.stopPropagation();
}
});
when document is loaded do:
$(function(){
//allow for ESC to close only top dialog
$(document).bind('keydown', function(event) {
if (event.isPropagationStopped()) return true;
if (mydialogs.hasOpenDialogs() &&
event.keyCode &&
event.keyCode === $.ui.keyCode.ESCAPE) {
mydialogs.closeTopDialog();
event.preventDefault();
event.stopPropagation();
}
});
});
Event in (2) happens when user hits ESC while typing text in input box inside of the dialog.
Event in (3) happens when user hits ESC somewhere else.
mydialogs here is a wrapper around stack (array) of modal dialogs, where every new dialog adds itself via .push() and in .close() removes itself with .pop().
I have a pop up dialog that lets you write text and does stuff when you click a button. My code is below
This function works, i find the new object by looking at e.originalEvent.explicitOriginalTarget. However now i notice if i press tab this function will be called but e.originalEvent.explicitOriginalTarget will give me the same current object instead of the new object. So my dialog doesnt close if a user presses tab to leave. How do i find the correct new dom item?
$('#Area').focusout(function (e) {
if ($(e.originalEvent.explicitOriginalTarget).closest('#Area').size() == 0)
$('#Area').hide();
});
event.relatedTarget worked for me. It will give the other DOM element, within the event, if there is one.
An example would be, if you had 2 buttons controlling the same function, and didn't want their code to be executed if they were clicked consecutively. You could attach a focusout event handler and check for an ID, or a class name.
$(".buttons").on("focusout", function (event) {
if($(event.relatedTarget).prop("class").indexOf("buttons") === -1) {
//code to execute
}
});
Perhaps a better example would be the issue I had.
I created a custom drop down list, that has a button beside it. The drop down list can be opened and closed by either clicking on the list, or the button. It can also be closed be losing focus to either object.
This becomes a problem in the following scenario.
1) user opens drop down list by clicking the list object.
2) user closes drop down list by clicking the button.
What happens is the list opens, but when the user goes to close the list, the list loses focus, which closes it, but since they are clicking on the button, it opens back up. The focusout causes the two objects to cancel each other out, in this type of scenario.
By writing the focusout event, I can now set it to only trigger when the relatedTarget doesn't have the same class as the target that called the event.
$(".listControl").on("focusout", function (event) {
if($(event.relatedTarget).prop("class").indexOf("listControl") === -1) {
//Close the drop down list
}
});
http://api.jquery.com/event.relatedTarget/
Check out this question/answer How to select an element that has focus on it with jQuery
I think the reason why you don't get anything with $("*:focus"); in Firebug console is when you click the console, the element loses focus.
And if you want to tackle it with events, the opposite of focus() is blur().
Edit
Maybe you can even try a different approach. If your only concern is watching for tab key, you can use .keypress() event and watch for tab keycode which is 9.