Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get the destroy() method of a jQuery UI plugin to work (+conflicting jQuery plugins)

Background/General Problem

I'm trying to fix a friend's website in which two jQuery plugins he added aren't playing nice. Basically, one (foundation - a grid layout with tabs) isn't playing nice with the second (RoyalSlider - an image slider) because the latter needs to "see" the slider material while the former hides inactive tabs. The page in question has three tabs, each with one of these RoyalSliders on them.

The original code initialized the slider for each of the three tabs right away in some jQuery on the main page. I've been trying to fix it by initializing only the active tab and then, when a tab is clicked, inserting code to delete the previous slider instance and create a new one for the new tab.

Specific Problem

The $(currentLocation).royalSlider('destroy') line that I added isn't doing anything, and I can't figure out what I'm doing wrong. Right now, the sliders are initializing for the first time correctly, but when I go back to any tab, a second slider appears inside of the first, making me think that the delete function is not working; its size is smaller and the animation is different than what the slider is supposed to be set to (bounce maybe?). The number never goes more than two.

Code

Here are some snippets of the code that I'm working on. I've only included small parts out of respect for the developers (although it's easy to check the source code). First is some of RoyalSlider.js, just to demonstrate the structure and destroy method (I haven't changed it at all, and it's in the format of a pretty standard jQuery UI plugin):

RoyalSlider.js:

(function($) {
     function RoyalSlider(element, options){ /* Make a slideshow, basically */ }
     RoyalSlider.prototype = {
          ... /* methods */
          destroy:function(){
               this._stopSlideshow();
               this._dragContainer.unbind(this._downEvent);
               $(document).unbind(this._moveEvent).unbind(this._upEvent);
               $(window).unbind(this._resizeEvent);
               if(this.settings.keyboardNavEnabled) {
                    $(document).unbind("keydown.rs");
               }
               this.slider.remove();

               delete this.slider;
          }
          ... /* _internal methods; all above are defined */
     }; /* RoyalSlider.prototype end */
     
     $.fn.royalSlider = function(options) { /* basically return a new RoyalSlider */ };
     $.fn.royalSlider.defaults = { /* whole lot of defaults */ };
     $.fn.royalSlider.settings = {};
})(jQuery);

Next, app.js, which switches the tabs. The tabs are an unordered list, and clicking on them directs you to http://domain.com/pagename#tabtwo (etc.)

app.js

jQuery(document).ready(function ($) {
     function activateTab($tab) {
          var $activeTab = $tab.closest('dl').find('a.active'),
          contentLocation = $tab.attr("href") + 'Tab';

          prevLocation = $activeTab.attr("href") + 'Tab'; /* I added this */

          // Make Tab Active
      $activeTab.removeClass('active');
      $tab.addClass('active');
    
      //Delete and Add Slider

      $(prevLocation).royalSlider('destroy');  /* Doesn't Work, but doesn't break - it doesn't seem to have any effect.  */

      $mySlider = $(contentLocation).royalSlider({  /* I also added this, and it seems to work */
           captionShowEffects:"moveleft",
           directionNavAutoHide: true,
           imageScaleMode:"fit",
           imageAlignCenter:true,
           blockLinksOnDrag:true,   
      });

      //Show Tab Content
      $(contentLocation).closest('.tabs-content').children('li').hide();
      $(contentLocation).css('display', 'block');

     }
     /* More functions that aren't relevant for this */
}

Last, the jQuery in the HTML document itself:

product-design.html

<html><head> ...
<script>
var $mySlider;
$(document).ready(function() {
    if ( window.location.hash ) { initialLocation = window.location.hash + 'Tab'; }
    else { initialLocation = '#taboneTab'; }
    
    $mySlider = $( initialLocation ).royalSlider({
        captionShowEffects:"moveleft",
        directionNavAutoHide: true,
        imageScaleMode:"fit",
        imageAlignCenter:true,
        blockLinksOnDrag:true,  
    });
    
    $(".royalSlider").css({ display: 'inline-block', overflow: 'hidden' });  
});
</script>
</head><body>
...
<!-- Body goes here -->
...
  <dl class="contained tabs">
    <dd><a href="#tabone" class="active">TabOne</a></dd>
    <dd><a href="#tabtwo" class="inactivetest">TabTwo</a></dd>
    <dd><a href="#tabthree" class="inactivetest">TabThree</a></dd>
  </dl>
  <ul class="tabs-content">
    <li class="active" id="taboneTab">
      ...
      <div id="tabone" class="royalSlider default"> 
        <!-- Container of slides(images) -->
        <ul class="royalSlidesContainer">
          <!-- Slides -->
          <li class="royalSlide">
            <div class="orbitcontent" style="">
              <h3>Content One</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
            </div>
          </li>
          <li class="royalSlide"> <img class="royalImage" src="" alt="Beauty Shot" width="765" height="600"/>
            <div class="royalCaption">
              <h4 class="royalCaptionItem" data-show-effect="movetop">Constructed Prototype</h4>
            </div>
          </li>
        </ul>
      </div>
      
    <!--TAB TWOOOOOOOOOOOO-->
    <li id="tabtwoTab">
    ...
    <!--TAB THREEEEEEEEEEE-->
    <li id="tabthreeTab">
    ...
    <!-- Close all of the tags -->

I'm really sorry about all of the text and the lack of full code, but does anyone have any suggestions? I've tried $mySlider.destroy(), $mySlider.royalSlider('destroy'), $(pastLocation).destroy(), $(pastLocation).royalSlider('destroy'), $(pastLocation).royalSlider.prototype('destroy'), setting $('.royalslider).css('display','block') right before deleting it, and anything else I could come up with; all of those either did nothing (I was watching the variable royalSlider while stepping through it in Firebug) or broke the webpage. I'm a novice at jQuery, so it's entirely possible the answer's very simple and I'm just missing it.

Any help would be greatly appreciated!

Let me know if there's other information needed.

like image 226
Lee Avatar asked Nov 13 '22 03:11

Lee


1 Answers

Most jQuery plugins store the new instance of their object within jQuery data. I took a peak at what I think is the royal slider code - http://dimsemenov.com/plugins/royal-slider/ - and I think that you could destroy it by directly referencing the royalSlider object.

First you're going want to check and see if the element you're trying to call destroy on actually has a royalSlider instance.

console.log($(prevLocation).data('royalSlider'));

Assuming the line above returns an object, you should then be able to access the destroy method directly. If it doesn't return an object, then either you're calling destroy on the wrong element, or something else is blowing away the stored instance.

$(prevLocation).data('royalSlider').destroy();

I tested this at the royalSlider website by typing the following into my console

$('#homeSlider').data('royalSlider').destroy();
like image 125
callmehiphop Avatar answered Nov 16 '22 03:11

callmehiphop