0

I am using a simple jquery plugin to achieve a dropdown on hover effect in Bootstrap 3. It works perfectly on desktop as well as mobile (reverts to original bootstrap dropdown behavior) but when the user resizes the browser window on a desktop the hover still functions. I am trying to disable it all together after the collapse of my navbar which is at 768px.

I am using the following plugin: https://github.com/CWSpear/bootstrap-hover-dropdown

I ended up using the following solution:

$(function () {
  if ($(window).width() > 768) {
    $('.dropdown-toggle').dropdownHover();
  }
});

But I can't get it to work perfectly, right now if you refresh the page at 768px or lower the plugin doesn't fire (dropdown works on mouse click) but if you scale down from anything bigger it continues to fire. I am just a little bit out of my league if anyone can help out.

dsamardjiev
  • 400
  • 1
  • 11
  • 32

3 Answers3

1

Your function will only run once on dom ready: http://learn.jquery.com/using-jquery-core/document-ready/

The simplest solution would be to check for this condition after a window resize

$(function () {
  var $window = $(window),
      $toggle = $('.dropdown-toggle'),
      isActive = false;

  function onResize() {
      if (!isActive && $window.width() > 768) {
        $toggle.dropdownHover();
        isActive = true;
      } else {
        // stop the dropdown
        isActive = false;
      }
  }

  $window.resize(onResize);
  // call once on start up
  onResize();
});
alexreardon
  • 606
  • 5
  • 12
  • Ok, this seems to work when you are scaling up from 768, but when you load the page above 768 the plugin no longer fires, I believe I am still missing something. – dsamardjiev Aug 14 '14 at 23:29
  • Updated the example to fire once on start up – alexreardon Aug 15 '14 at 00:08
  • This seems to be the closest I got, but now when you are scaling down from past 768, it continues to fire to whereas I need it to be disable when. It works perfectly when scaling up need it to do the same when scaling down and between the two, I am trying to kind of merge your answer and Michaels it seems you both are on the right track – dsamardjiev Aug 15 '14 at 00:19
  • updated. You need to stop the dropdown if the size is under 768 ``// stop the dropdown`` – alexreardon Aug 15 '14 at 00:22
  • Okay, I am trying to figure out how to do this last part but how would do it if the plugin does not have a destroy method? – dsamardjiev Aug 15 '14 at 00:31
  • It looks like the plugin doesn't support an unbind feature. These resources might be useful: http://stackoverflow.com/questions/3205920/jquery-remove-plugin-from-element && http://ub4.underblob.com/remove-jquery-plugin-instance/ – alexreardon Aug 15 '14 at 01:49
  • I'm going to look into to this more tomorrow and update, thank you! Too much of a headache for one day. – dsamardjiev Aug 15 '14 at 05:28
0

Perhaps this can help: jQuery on window resize

If I'm understanding this correctly, the jQuery example on that page is attaching a "listener" to the window, and it executes when the window is resized. I believe your issue is that your function only runs once- that is why it works if the page is already at the minimum size or smaller.

Modifying the code from the linked example slightly:

$(window).on('resize', function(){
    var win = $(this); //this = window
    if (win.width() > 768) { 
        $('.dropdown-toggle').dropdownHover(); 
    }
});

Edit: Actually, you might want to disable the dropdown menu if you're below 768, instead of enabling it when you're above it. Check the width on page load, and add the resize listener. That solves your issue of it not working when you load the page bigger than 768. I would reply to your comment on the other answer but I don't have enough rep yet.

// Pseudocode
if (window width < 768) {
   Disable dropdown menu
}

// Semi-pseudocode
$(window).on('resize', function(){
    var win = $(this); //this = window
    if (win.width() < 768) { 
        // Disable dropdown menu 
    }
});
Community
  • 1
  • 1
  • I got the same result as the answer @alexreardon provided. I need the dropdown to work on hover at anything above 768px but when the browser is sized back and fourth between that point it needs to disable and re enable accordingly, I am trying to do what you suggested with your edit now. EDIT: Yes I think it would be better to disable it when you're below 768, it seems I went in the total opposite direction? – dsamardjiev Aug 14 '14 at 23:43
  • Check out my additional edit, I added some code. I think that its better have it enabled by "default", then disable it as necessary. You could even add another listener to re-enable it. – Michael Slevin Aug 14 '14 at 23:52
  • Ok I believe I am getting the idea, but how would I "disable" it? Someone mentioned a destroy option but I cannot find anything like that in the github of the plugin. Really new to JS my apologies Michael! – dsamardjiev Aug 15 '14 at 00:05
  • jQuery isn't my strongest subject, but you'd essentially want to change the behavior of the button when you hover over it. Possibly write a `destroy()` function that removes the `data-hover` attribute from the button? You'd call it in the same way, `$('.dropdown-toggle').destroy()` – Michael Slevin Aug 15 '14 at 00:29
  • Ah definitely a little advanced for me, you helped a lot thank you Michael. – dsamardjiev Aug 15 '14 at 00:39
0

Your initialization code is execute just once, right after the page has loaded. When you resize the browser, the page is not reloaded, so it does not get executed again.

Method 1: You can listen for the resize event on the browser window and adapt your layout depending on the new width. It might look like this:

var dropDownsActive = false;
var handleDropDowns = function() {
    if ($(window).width() > 768 && !dropDownsActive) {
        $('.dropdown-toggle').dropdownHover();
        dropDownsActive = true;
    } else if($(window).width() <= 768 && dropDownsActive) {
        // TODO: destroy/reset the dropdowns here, if possible
        dropDownsActive = false;
    }
}

jQuery(window).resize(handleDropDowns);
jQuery(window).ready(handleDropDowns);

One problem remains: If you go back to a narrow window, the dropdowns have already been initialized and probably won't go away. You have to find a way to destroy the plugin (if it supports it) or you could try to replace the dropdown-Elements with the original HTML.

Method 2: You can also do it brute force and reload your entire page on resize:

var previousWindowWidth = $(window).width();
jQuery(window).resize(function() {
    if ($(window).width() > 768 && previousWindowWidth <= 768 || $(window).width() <= 768 && previousWindowWidth > 768) {
        window.location.reload();
    }
    previousWindowWidth = $(window).width();
});

But that might have some unwanted side effects like input data or other dynamic state being lost and of course page flicker.

janwschaefer
  • 609
  • 3
  • 6