accordion.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /**
  2. * Accordion-folding functionality.
  3. *
  4. * Markup with the appropriate classes will be automatically hidden,
  5. * with one section opening at a time when its title is clicked.
  6. * Use the following markup structure for accordion behavior:
  7. *
  8. * <div class="accordion-container">
  9. * <div class="accordion-section open">
  10. * <h3 class="accordion-section-title"></h3>
  11. * <div class="accordion-section-content">
  12. * </div>
  13. * </div>
  14. * <div class="accordion-section">
  15. * <h3 class="accordion-section-title"></h3>
  16. * <div class="accordion-section-content">
  17. * </div>
  18. * </div>
  19. * <div class="accordion-section">
  20. * <h3 class="accordion-section-title"></h3>
  21. * <div class="accordion-section-content">
  22. * </div>
  23. * </div>
  24. * </div>
  25. *
  26. * Note that any appropriate tags may be used, as long as the above classes are present.
  27. *
  28. * @since 3.6.0
  29. * @output wp-admin/js/accordion.js
  30. */
  31. ( function( $ ){
  32. $( function () {
  33. // Expand/Collapse accordion sections on click.
  34. $( '.accordion-container' ).on( 'click keydown', '.accordion-section-title', function( e ) {
  35. if ( e.type === 'keydown' && 13 !== e.which ) { // "Return" key.
  36. return;
  37. }
  38. e.preventDefault(); // Keep this AFTER the key filter above.
  39. accordionSwitch( $( this ) );
  40. });
  41. });
  42. /**
  43. * Close the current accordion section and open a new one.
  44. *
  45. * @param {Object} el Title element of the accordion section to toggle.
  46. * @since 3.6.0
  47. */
  48. function accordionSwitch ( el ) {
  49. var section = el.closest( '.accordion-section' ),
  50. sectionToggleControl = section.find( '[aria-expanded]' ).first(),
  51. container = section.closest( '.accordion-container' ),
  52. siblings = container.find( '.open' ),
  53. siblingsToggleControl = siblings.find( '[aria-expanded]' ).first(),
  54. content = section.find( '.accordion-section-content' );
  55. // This section has no content and cannot be expanded.
  56. if ( section.hasClass( 'cannot-expand' ) ) {
  57. return;
  58. }
  59. // Add a class to the container to let us know something is happening inside.
  60. // This helps in cases such as hiding a scrollbar while animations are executing.
  61. container.addClass( 'opening' );
  62. if ( section.hasClass( 'open' ) ) {
  63. section.toggleClass( 'open' );
  64. content.toggle( true ).slideToggle( 150 );
  65. } else {
  66. siblingsToggleControl.attr( 'aria-expanded', 'false' );
  67. siblings.removeClass( 'open' );
  68. siblings.find( '.accordion-section-content' ).show().slideUp( 150 );
  69. content.toggle( false ).slideToggle( 150 );
  70. section.toggleClass( 'open' );
  71. }
  72. // We have to wait for the animations to finish.
  73. setTimeout(function(){
  74. container.removeClass( 'opening' );
  75. }, 150);
  76. // If there's an element with an aria-expanded attribute, assume it's a toggle control and toggle the aria-expanded value.
  77. if ( sectionToggleControl ) {
  78. sectionToggleControl.attr( 'aria-expanded', String( sectionToggleControl.attr( 'aria-expanded' ) === 'false' ) );
  79. }
  80. }
  81. })(jQuery);