如何实现点击非抽屉区域关闭筛选抽屉?
Hey there! I see you're building a drawer component where clicking toolbar links opens and switches drawer content, and you're stuck on adding the "click outside to close" feature. Let's implement this in a way that plays nicely with your existing code.
The core idea is to leverage event bubbling and check if the click target belongs to your toolbar or drawer elements. Here's how to do it step by step:
1. Stop Toolbar Click Events from Bubbling
First, add event.stopPropagation() to your existing toolbar click handler. This prevents clicks on your links from triggering the document-wide click event we'll add next:
$('.filters-toolbar').on('click', 'a', function(event) { // Prevent event from reaching the document event.stopPropagation(); $('.current').not($(this).closest('li').addClass('current')).removeClass('current'); var $this = $(this); $('.filters-toolbar__drop-down-wrapper').fadeIn('slow'); $('body').addClass('filter-open'); // Fade out visible content and show the target var visibleElements = $('.filters-toolbar__drop-down:visible'); if (visibleElements.length <= 0) { $('.filters-toolbar__drop-down[id=' + $this.data('id') + ']').fadeIn('slow'); } else { visibleElements.fadeOut('slow', function() { $('.filters-toolbar__drop-down[id=' + $this.data('id') + ']').fadeIn('slow'); }); } });
2. Add Document Click Handler for Closing
Next, bind a click event to the document to detect clicks outside your toolbar and drawer. If the click isn't on those elements, we'll fade out the drawer and reset states:
$(document).on('click', function(event) { // Check if the click target is NOT inside toolbar or drawer if (!$(event.target).closest('.filters-toolbar__drop-down-wrapper, .filters-toolbar').length) { // Fade out drawer and its contents $('.filters-toolbar__drop-down-wrapper').fadeOut('slow'); $('.filters-toolbar__drop-down').fadeOut('slow'); // Reset body class and selected state $('body').removeClass('filter-open'); $('.current').removeClass('current'); } });
3. Optional: Handle Drawer Internal Clicks
The closest() check above already includes the drawer wrapper, so clicks inside the drawer content won't trigger the close logic—no extra code needed here!
Full Integrated Code
JavaScript
$(function() { $('.filters-toolbar__drop-down:gt(0)').hide(); $('.filters-toolbar__drop-down-wrapper').hide(); $('.filters-toolbar').on('click', 'a', function(event) { event.stopPropagation(); $('.current').not($(this).closest('li').addClass('current')).removeClass('current'); var $this = $(this); $('.filters-toolbar__drop-down-wrapper').fadeIn('slow'); $('body').addClass('filter-open'); var visibleElements = $('.filters-toolbar__drop-down:visible'); if (visibleElements.length <= 0) { $('.filters-toolbar__drop-down[id=' + $this.data('id') + ']').fadeIn('slow'); } else { visibleElements.fadeOut('slow', function() { $('.filters-toolbar__drop-down[id=' + $this.data('id') + ']').fadeIn('slow'); }); } }); $(document).on('click', function(event) { if (!$(event.target).closest('.filters-toolbar__drop-down-wrapper, .filters-toolbar').length) { $('.filters-toolbar__drop-down-wrapper').fadeOut('slow'); $('.filters-toolbar__drop-down').fadeOut('slow'); $('body').removeClass('filter-open'); $('.current').removeClass('current'); } }); });
CSS (Unchanged)
.filters-toolbar-wrapper { margin-bottom: 0; width: 100%; } .filters-toolbar__item { padding: 0 50px; display: inline-block; } .filters-toolbar__drop-down-wrapper { background-color: grey; border-bottom: 1px solid #000; position: relative; top: 0; left: 0; width: 100%; height: 200px; } .filters-toolbar__drop-down { display: none; }
HTML (Unchanged)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="filters-toolbar-wrapper"> <div class="filters-toolbar"> <div class="filters-toolbar__item"> <a href="#" data-id="filter1">Type</a> </div> <div class="filters-toolbar__item"> <a href="#" data-id="filter2">Color</a> </div> <div class="filters-toolbar__item"> <a href="#" data-id="filter3">Sorty by</a> </div> </div> </div> <div class="filters-toolbar__drop-down-wrapper"> <div id="filter1" class="filters-toolbar__drop-down by-type"> Type Dropdown </div> <div id="filter2" class="filters-toolbar__drop-down by-color"> Color Dropdown </div> <div id="filter3" class="filters-toolbar__drop-down sort-by"> Sort Dropdown </div> </div>
This approach works seamlessly with your existing code by:
- Preventing toolbar clicks from triggering the close logic
- Checking click targets to only close when outside the drawer/toolbar
- Resetting all states (body class, selected toolbar item) when closing
内容的提问来源于stack exchange,提问作者user2498890

