I am developing my first firefox extension so I created a menu-button element and menu items.
Exactly like the FireBug button, I would like an event to be triggered when clicking on the main button, but also when clicking on a menu item. The problem is that when I click on the arrow next to the main button to display the menu items the main event is triggered. So my question is:
How do I differentiate the main button (the menu-button) and the arrow displaying the menu?
Here is my code generating the button:
function addToolbarButton() {
var document = mediator.getMostRecentWindow('navigator:browser').document;
var navBar = document.getElementById('nav-bar');
if (!navBar) {
return;
};
//main button
var btn = document.createElement('toolbarbutton');
btn.setAttribute('id', 'reportButton');
btn.setAttribute('type', 'menu-button');
btn.setAttribute('class', 'toolbarbutton-1');
btn.setAttribute('image', data.url('img/BookmarkKitchen.png'));
btn.setAttribute('orient', 'horizontal');
btn.setAttribute('label', 'Report');
btn.addEventListener('click', function() {
console.log("this=" + this.id);
event.stopPropagation();
}
, false);
//menu popup
var menupopup = document.createElement('menupopup');
menupopup.setAttribute('id', 'menupopup');
menupopup.addEventListener('click', function(event) {
console.log("this=" + this.id);
event.stopPropagation();
}
, false);
//menu items
var menuitem1 = document.createElement('menuitem');
menuitem1.setAttribute('id', 'menuitem1');
menuitem1.setAttribute('label', 'Test1');
menuitem1.setAttribute('class', 'menuitem-iconic');
menuitem1.addEventListener('click', function(event) {
console.log("this=" + this.id);
event.stopPropagation();
}
, false);
menupopup.appendChild(menuitem1);
btn.appendChild(menupopup);
navBar.appendChild(btn);
}
When I click on the main button, the console will write "this=reportButton". This is normal but when I click on the arrow next to the main button, the console will also write "this=reportButton". That means if I want to access the menu, the main event will be triggered. The only way I found to prevent this, is to press the button on the arrow, wait for the menu to show up and release it on a menu Item. This is not very user friendly and Firebug doesn't have this problem...
I hope I was clear enough. Thanks for answering this :)
Don't use the click event - in XUL it really means a mouse click. So if the user triggers a button by other means (e.g. keyboard), the click event will not be triggered. You should use the command event instead - and it has the additional advantage that it won't fire if the dropdown arrow is clicked.
Related
I have this code for toggling menus on my site. It will open a menu on click, close others open when you click another and close them all if you click outside.
The issue is, I'm now using this for my search bar to appear too, but if you click inside the search box it vanishes - woops. Would it be possible to amend the hiding code to detect if the user wasn't clicking inside a specific area of the code?
// navbar toggle menu
$(document).on('click', ".toggle-nav > a", function(event) {
event.preventDefault();
event.stopPropagation();
var $toggle = $(this).closest('.toggle-nav').children('.toggle-content');
if ($toggle.hasClass('toggle-active'))
{
$($toggle).removeClass('toggle-active');
}
else
{
$(".toggle-content").removeClass('toggle-active');
$($toggle).addClass('toggle-active');
}
});
// hide the toggle-nav if you click outside of it
$(document).on("click", function ()
{
$(".toggle-content").removeClass('toggle-active');
});
Instead of using click, this uses mouseup. If the target is, for example #search-bar, it won't remove toggle-active from toggle-content elements.
$(document).mouseup(function(e) {
if (!$(e.target).is('#search-bar')) {
$(".toggle-content").removeClass('toggle-active');
}
});
You can see it in action with this jsFiddle.
Hopefully this helps.
I have an autocomplete dropdown that appears when a user starts typing in a textbox (I'm using jquery mobile but I don't think that's important to my problem). I want to be able to hide the whole dropdown list when a user clicks anywhere on the page. However, I don't want to hide the dropdown when a user actually clicks on the dropdown itself.
Is there a way I could catch the click event in order to know what was clicked?
Here's my blur function:
//hide autocomplete when dropdown is not clicked
$("#search-div input").blur(function () {
$("#autocomplete-list").hide();
});
I was thinking of somehow putting an if statement in my blur function. Here's my pseudo code:
if( dropdown clicked)
{
run code to take text from dropdown and place in textbox
}
else
{
hide dropdown
}
Would it be possible to know whether my dropdown is clicked or something else is clicked while in my blur function? When I debug my javascript I'm only seeing an event that's related to the textbox doing the blur()
Edit:
Here is a function I'm using to handle when the dropdown is clicked:
$( document).on( "click", "#autocomplete-list li", function() {
var selectedItem = event.target.innerHTML;
$(this).parent().parent().find('input').val(selectedItem);
$('#autocomplete-list').hide();
runSearchQuery();
});
You can listen for any click, not just a blur, and then check what the clicked element was. e.currentTarget gives you what was clicked.
var clickHandler = function(e) {
if ($(e.currentTarget).hasClass('dropdown')) {
// do nothing
} else {
// Make sure you unregister your event every
// time the dropdown is hidden.
$(window).off('click', clickHandler);
// hide
}
}
// When the dropdown comes down, register an event on the whole page.
$(window).on('click', clickHandler);
I have a simple button that toggles a menu onclick
If the menu is expanded/visible I hide it when clicking anywhere on the page (a part from the menu itself).
var menuBtn = $(".btn-menu"),
menuContainer = $(".menu"),
menuChildren = $(".menu").find("*");
menuBtn.on("click", function() {
menuContainer.toggle();
});
$(window).mouseup(function(e){
if(!menuContainer.is(e.target) && !menuChildren.is(e.target)){
menuContainer.hide();
}
});
When applying that function on mouseup, my toggle function no longer works. Menu will always stay open if clicking multiple times on the button (whereas it should hide & show).
jsfiddle here
Any idea how I could fix this?
mouseup event was fired before click.
try this
$(window).mouseup(function(e){
if(!menuContainer.is(e.target) && !menuChildren.is(e.target) && !menuBtn.is(e.target)){
menuContainer.hide();
}
});
fiddle js
I am using JQuery to make a 'Read More' button. When someone clicks onthe button a popup appears. This popup is actually a hidden div that appears. My problem is that while I click the button I want the div to appear from the button and when I click the cross mark on the popup it sould go back to the same button where it originated from but the result that I am getting is, when I click on the button the div appears from it whereas when I click cross it goes to the 'read more' button which I clicked the first. Please help me fix this. I guess there is a small glitch in my code. I have it on fiddle http://jsfiddle.net/shivkumarganesh/qLEbD/
Check this fiddle: http://jsfiddle.net/6uLF7/
The problem was with the local scope of the variables that store the target left and top offsets.
CHANGES
Added 2 declarations at the top:
var readMoreInfoTop = 0;
var readMoreInfoLeft = 0;
Removed var keyword from the top and left assignments inside the click handler
readMoreInfoTop = readMoreOffset.top + 10;
readMoreInfoLeft = readMoreOffset.left + 10;
Each time you open a button, you are adding another listener to the close button. You could unbind the close listener before rebinding it eg. http://jsfiddle.net/qLEbD/54/
or better yet...
bind the close listener once (outside the button click function) and store the left position on button click eg.
//doc ready...
function() {
var leftPosition;
$('.button').click(function() {
//animate popup to open
leftPosition = $(this).offset.left;
});
$('#close').click(function() {
//animate popup to close using leftPosition
});
}();
I have a div which opens when I click a menu button, I am trying to close it if the user clicks anywhere after it is open. The issue I am having is that with my code the show div and the close div when a user clicks I guess are firing at the same time for some reason. The code for the click event is below. How can I make it so they do not fire at the same time and when I open the div that does not fire the click function. Thanks!
//if user clicks and menu is open then hide menu div
$(document).click(function() {
if($("menu").hasClass("menu_closed") == false ) {
//will hide the menu div
closeMenu();
}
}
I think what you want actually is to stop propagation in the other click handler, something like:
$("your_menu_selector").bind("click", function(e){
//your code to open the menu
e.stopPropagation();
return false;
})
You might want to consider adding the event handler to close the menu in the handler that opens the menu. Have it execute only once using the one method. In the handler that opens the menu, simply check to see if it is open already and do a no-op if it is.
$('.openButton').click( function() {
var $menu = $('#menu').
if ($menu.hasClass('menu_closed')) {
$menu.removeClass('menu_closed').addClass('menu_open');
$(document).one( function() {
$menu.removeClass('menu_open').addClass('menu_closed');
});
}
});