javascriptjqueryfunctionresizeslidetoggle

jQuery slidetoggle keeps toggling after window resize/ready combined


I want to add slidetoggle only when screen size is less than 768px. I also want this to work when user for some reason would resize the window manually.

I have come across a bug with jQuery where my dropdown menu will keep toggling after I resize the window. I've looked up this issue and tried adding return false; to click function and adding position: relative; overflow:hidden; to toggleable div(these should be a workaround according to some forums). No luck there. What causes this bug. I will include the whole function with the click function

//Call function on ready and window resize

$(document).ready(navigationMobile);
$(window).on('resize', navigationMobile);

function navigationMobile() {

  const windowWidth = $(window).width();

  if (windowWidth < 768) {

    //Remove href from main link and add it as a "all" link in menu

    $(".js-second-title").each(function () {
      const currentHref = $(this).attr('href');
      $(this).removeAttr('href');
      if ($(this).siblings('ul').find('.js-all-link').length === 0) {
        $(this).siblings('ul').prepend(`<li><a class="js-all-link" href="${currentHref}">All</a></li>`);
      }
    });

    //When clicked on main link open menu

    $(".js-second-title").click(function () {
      $(this).siblings('.js-menu').slideToggle();
      $(this).toggleClass('js-open');
    });

  } else {

    //Add href back to main link

    $('.js-second-title').each(function () {
      if ($(this).attr('href') === undefined) {
        const allHref = $(this).siblings('ul').find('.js-all-link').attr('href');
        $(this).attr('href', `${allHref}`);
        $(this).siblings('ul').find('.js-all-link').remove();
      }
    });

  }
}

Cheers!


Solution

  • I don't exactly know what is causing this bug. But I came up with this workaround.

      //Remove href from main link and add it as a "all" link in menu
    
        $(".js-second-title").each(function () {
          $(this).addClass('js-closed');
          const currentHref = $(this).attr('href');
          $(this).removeAttr('href');
          if ($(this).siblings('ul').find('.js-all-link').length === 0) {
            $(this).siblings('ul').prepend(`<li><a class="js-all-link" href="${currentHref}">All</a></li>`);
          }
        });
    
        //When clicked on main link open menu
    
        $(document).on("click", '.js-second-title.js-closed', function (e) {
          $(this).removeClass('js-closed');
          $(this).siblings('.js-menu').slideDown();
          $(this).addClass('js-open');
        });
    
        $(document).on("click", '.js-second-title.js-open', function (e) {
          $(this).siblings('.js-menu').slideUp();
          $(this).removeClass('js-open');
          $(this).addClass('js-closed');
        });
    

    So here I am basically extening SlideToggle function. Before I call slide functions on click I give each js-second-title classes an extra class .js-closed so the browser is aware that the menu is closed. After that I call slideDown function when I click on closed menu title and slideUp when I click on open menu title.

    I do not think that this is the best or most sematic solution so I would like to keep this topic open.