On my site I have a menu that has certain functionalities and animation:
Now these functions are working great, however the problem is that they can be all activated by clicking/hovering around the menu and above it, and not only on the elements. Can it be fixed so that all the functions(without changing them) are activated just by clicking on an element in the menu?
JSFIDDLE: https://jsfiddle.net/atkumqpk/16/
HTML of the menu:
<div id="menu" class="menu">
<ul class="headlines">
<li id="item1">
<button>aaaaaaaa</button>
</li>
<li id="item2">
<button>bbbbbbb</button>
</li>
</ul>
</div>
Select the Elements product that you want to activate from the screen below. Sign in using your Adobe ID and password. Click Activate now in the Welcome screen. Enter the serial number in the next screen and click Next. Your Elements product launches successfully. Can't find your serial number?
I've used a <figure>, but you can use any element you like. Just add tabindex="-1" to make it focusable, if it isn't already. You can place the menu anywhere you want in the HTML, as long as you're able to target it with a CSS selector. Just try not to put a button in a button as that's invalid HTML, although technically it will still work.
This makes the element focusable, so that it can open the menu on click. Note that if the clickable element is a <button> or other interactive content (i.e. any focusable element), then you don't even need this! I've used a <figure>, but you can use any element you like.
No JS trickery involved. You can attach event listeners to the menu items, e.g. using onclick or document.addEventListener and they'll work as usual. You may also just use <a> tags instead of buttons, depending on your use case. Naturally the menu can be opened only by elements that can receive focus, such as buttons and anchors.
I also did an update to your Fiddle:
updated Fiddle
My solution was to remove your click-event-handler for the <LI>
elements and replaced it with click- and hover-events for the buttons:
Only two minimal changes to your css are needed.
The advantage of this solition (instead of relying on .headlines:hover-selector) is that your buttons can have different sizes and spaces between them. The area used to trigger your hover styles will always be the button-area and not the size of the surrounding <li>
// Removed Code
/*
var $li = $('.headlines li').click(function () {
var state = !$(this).hasClass('active');
$(this).parent().toggleClass('active', state);
$li.removeClass('active');
$(this).toggleClass('active', state);
});
*/
// Added Code
var $headlines = $('.headlines');
var $headlinesLi = $('.headlines li');
$('.headlines button').each(function() { //iterate over every 'button' in '.headlines':
var $thisButton = $(this); // save (cache) the current jQuery-Button-Object
var $parentLi=$thisButton.parent(); // save (cache) the parent <LI>
var state = false; // set initial button-state to false
$thisButton.click(function(){ // click-handler for the current Button:
state = !state; // invert 'state'
$headlinesLi.removeClass('active'); // remove .active-class on every <LI>
$parentLi.toggleClass('active',state); // set/remove .active-class on buttons parent <LI> as indicated by 'state'
$headlines.toggleClass('active',state); // set/remove .active-class on .headlines indicated by 'state'
});
$thisButton.hover( //hover-handler for the current Button:
function () { // routines for mouse-enter like events:
$parentLi.addClass('hover'); // add .hover-class to buttons parent <LI>
$headlines.addClass('hover'); // add .hover-class to .headlines
},
function () { // routines for mouse-leave like events:
$parentLi.removeClass('hover'); // remove .hover-class to buttons parent <LI>
$headlines.removeClass('hover'); // remove .hover-class to .headlines
}
);
});
This adds and removes .hover
classes on .headlines
and your buttons parent <li>
elements.
In your CSS you only need to switch from from :hover
pseudo-selektor to .hover
class in the selection qualifier.
So switch from:
.headlines:hover li, .headlines.active li {
/* PARENT HOVER */
...
.headlines li:hover, .headlines li.active {
/* SINGLE HOVER */
...
to
.headlines.hover li, .headlines.active li {
/* PARENT HOVER */
...
.headlines li.hover, .headlines li.active {
/* SINGLE HOVER */
...
Voila.
Simply try to add event handlers to buttons directly and not <li>
elements:
$(window).load(function () {
...
function AddEventHandlers()
{
var btns = $('button'); // all buttons (set and use id or class
// if you've other buttons on this page)
for (int i = 0;i < btns .length; i++) {
btns[i].click(function() {
// your logic here;
});
};
};
AddEventHandlers();
...
});
Check this fiddle, it looks like the problem was in your css:
.menu li {
position: relative;
top: 180px;
left: 0px;
}
because of this rule, your li items was shifted down, but hovering in css triggered on .headlines (ul element), which position remains 180px higher, than it's child elements, so you get changing opacity when mouse higher than your menu items. And your ul element width was 100%, its children li elements width was the same (excluding margins), so your opacity also changes, when mouse was from left or right side of your actual text of menu.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With