Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Twitter Bootstrap Transition Conflict prototypejs

I created a fiddle for Collapse feature of Twitter Bootstrap using the markup from the demos on your page that works: http://jsfiddle.net/Rymd7/1/

Then once, I add in a reference to prototypejs collapse functionality stops working on each accordian group after clicking through it a couple of times. http://jsfiddle.net/p5SAy/1/ I'm not sure what the issue is or how to correct it.

Is this a bootstrap issue or is there a way to get around this and have these two js libraries exist on the same page?

I have tried jQuery noConflict with no success, but any help is appreciated. If you can send me back a working fiddle that would be great...or any insight.

Thanks. -John

like image 908
user1718100 Avatar asked Dec 03 '22 01:12

user1718100


1 Answers

You are using jQuery and Prototype simultaneously without jQuery.noConflict(). After

<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.js'></script>
<script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/prototype/1.7.0/prototype.js"></script>

this line was causing javascript error:

$(window).load(function(){

Revised fiddle: http://fiddle.jshell.net/ymbsr/5/ - open http://fiddle.jshell.net/ymbsr/5/show/ in different browsers.

P.S.

After removing jQuery/Prototype conflict I can see that ih Chrome 21 and Opera 12.02 accordion transition never ends (in bootstrap-collapse.js Collapse.transition initiates transition but complete() is never called). Further invocations of Collapse.show()/hide() on the same element are exiting after if (this.transitioning) return.

In Firefox 15.0.1 accordion works fine.

P.P.S.

This strange behavior is a consequence of two features:

  1. this.$element.trigger('hide') (in Collapse#transition()) tries to invoke $element.hide() if method hide() is present in element - that's by design:

    Note: For both plain objects and DOM objects, if a triggered event name matches the name of a property on the object, jQuery will attempt to invoke the property as a method if no event handler calls event.preventDefault(). If this behavior is not desired, use .triggerHandler() instead.

    With Prototype in each browser supporting HTML element prototype extensions $element will definitely have hide() method, which actually hides element via setting element.style.display = 'none'.

  2. In current versions of Chrome and Opera transition end event (one of webkitTransitionEnd, oTransitionEnd, otransitionend) will not fire if element is hidden (has display: none style). Firefox ends its transition more successfully, but also may not fire event under some circumstances:

    Note: The "transitionend" event doesn't fire if the transition is aborted because the animating property's value is changed before the transition is completed.

How to fix it:

  1. File a bug for bootstrap-collapse.js - it shouldn't rely only on transition end event

  2. File a bug for bootstrap-collapse.js - its hide event intersects with other frameworks (at least with Prototype, but any other framework extending element prototypes may be affected).

  3. Temporarily patch Collapse#transition() from bootstrap-collapse.js as in http://fiddle.jshell.net/ymbsr/7/ - either disable event triggering or change event names.

    jQuery.fn.collapse.Constructor.prototype.transition = function (method, startEvent, completeEvent) {
      var that = this
        , complete = function () {
            if (startEvent.type == 'show') that.reset();
            that.transitioning = 0;
            that.$element.trigger(completeEvent);
          }
      //this.$element.trigger(startEvent);
      //if (startEvent.isDefaultPrevented()) return;
      this.transitioning = 1;
      this.$element[method]('in');
      (jQuery.support.transition && this.$element.hasClass('collapse')) ?
          this.$element.one(jQuery.support.transition.end, complete) :
          complete();
    };
    
like image 118
Victor Avatar answered Dec 11 '22 15:12

Victor