I\'m using Splitter.js in a project.
The code is from http://methvin.com/splitter/ The specific JS is at http://methvin.com/splitter/splitter.js
There's an updated fork of jQuery.splitter that works with jQuery 1.8 (also 1.9 if you restore jQuery.browser
) at https://github.com/e1ven/jQuery-Splitter.
I ran into the same problem in the process of upgrading a site to jQuery 1.8. After a bit of debugging and poking around in the code, it seems to me there were two issues: the resize event was getting triggered unnecessarily in a few places, and it was getting triggered on the splitter before the splitter's resize event handler had been setup. I switched the order of the last two chunks of code to make sure the splitter's resize event handler gets set up first and tidied up a few lines. It now looks like this:
// Resize event handler
splitter.bind("resize", function(e, size){
// Determine new width/height of splitter container
splitter._DF = splitter[0][opts.pxFixed] - splitter._PBF;
splitter._DA = splitter[0][opts.pxSplit] - splitter._PBA;
// Bail if splitter isn't visible or content isn't there yet
if ( splitter._DF <= 0 || splitter._DA <= 0 ) return;
// Re-divvy the adjustable dimension; maintain size of the preferred pane
resplit(!isNaN(size)? size : (!(opts.sizeRight||opts.sizeBottom)? A[0][opts.pxSplit] :
splitter._DA-B[0][opts.pxSplit]-bar._DA));
e.stopPropagation();
});
// Resize event propagation and splitter sizing
if ( opts.anchorToWindow ) {
// Account for margin or border on the splitter container and enforce min height
splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom");
splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20);
splitter._bottomOffset = opts.bottomOffset ? opts.bottomOffset : 0;
$(window).bind("resize", function(){
var top = splitter.offset().top;
var wh = $(window).height() - splitter._bottomOffset;
splitter.css("height", Math.max(wh-top-splitter._hadjust, splitter._hmin)+"px");
splitter.trigger("resize");
}).trigger("resize");
}
else if ( opts.resizeToWidth )
$(window).bind("resize", function(){
splitter.trigger("resize");
});
Also, make sure you remove
if ( !$.browser.msie ) panes.trigger("resize");
from the reSplit function. I've uploaded the whole thing to a GitHub repo if you want to see it all in one place.
I was experiencing this same issue. After looking around in the splitter.js file for a while, I came across this section of code:
// Resize event handler; triggered immediately to set initial position
splitter.bind("resize", function(e, size){
// Custom events bubble in jQuery 1.3; don't get into a Yo Dawg
if ( e.target != this ) return;
......
}).trigger("resize" , [initPos]);
The "yo dawg" reference was the dead giveaway :)
Sure enough, after debugging it in Chrome, there is excessive recursion in this particular event handler function. The developer who wrote it attempted to resolve the issue, but for some reason the newer version of the JQuery library does not work as expected, and the escape condition is never met. From what I can tell, this particular piece of code is only used during page load to set the initial position of the splitter. I found that the splitter was still usable aside from the stack overflow, and the only reason I noticed the problem was because my javascript code after initializing the splitter wasn't running. If you have time, see if you can find out why this part of the code isn't working and post a fix. If you're in a hurry and don't mind duct-tape, put a try catch around the line of code where you call the .splitter() function. It seems to work fine in both Chrome 19 and IE 9.
UI-Layout stays up-to-date and does "splitting" and alot more, and is fairly easy to use.
$('body').layout({ applyDemoStyles: true });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="http://layout.jquery-dev.net/lib/js/jquery.layout-latest.js"></script>
<div class="ui-layout-center">Center
<p><a href="http://layout.jquery-dev.com/demos.html">Go to the Demos page</a></p>
<p>* Pane-resizing is disabled because ui.draggable.js is not linked</p>
<p>* Pane-animation is disabled because ui.effects.js is not linked</p>
</div>
<div class="ui-layout-north">North</div>
<div class="ui-layout-south">South</div>
<div class="ui-layout-east">East</div>
<div class="ui-layout-west">West</div>
var layoutSettings_Outer = {
name: "outerLayout",
defaults: {
size: "auto",
minSize: 50,
paneClass: "pane",
resizerClass: "resizer",
togglerClass: "toggler",
buttonClass: "button",
contentSelector: ".content",
contentIgnoreSelector: "span",
togglerLength_open: 35,
togglerLength_closed: 35,
hideTogglerOnSlide: true,
togglerTip_open: "Close This Pane",
togglerTip_closed: "Open This Pane",
resizerTip: "Resize This Pane",
fxName: "slide",
fxSpeed_open: 750,
fxSpeed_close: 1500,
fxSettings_open: { easing: "easeInQuint" },
fxSettings_close: { easing: "easeOutQuint" }
},
north: {
spacing_open: 1,
togglerLength_open: 0,
togglerLength_closed: -1,
resizable: false,
slidable: false,
fxName: "none"
},
south: {
maxSize: 200,
spacing_closed: 0,
slidable: false,
initClosed: true,
onhide_start: function() { return confirm("START South pane hide \n\n onhide_start callback \n\n Allow pane to hide?"); },
onhide_end: function() { alert("END South pane hide \n\n onhide_end callback"); },
onshow_start: function() { return confirm("START South pane show \n\n onshow_start callback \n\n Allow pane to show?"); },
onshow_end: function() { alert("END South pane show \n\n onshow_end callback"); },
onopen_start: function() { return confirm("START South pane open \n\n onopen_start callback \n\n Allow pane to open?"); },
onopen_end: function() { alert("END South pane open \n\n onopen_end callback"); },
onclose_start: function() { return confirm("START South pane close \n\n onclose_start callback \n\n Allow pane to close?"); },
onclose_end: function() { alert("END South pane close \n\n onclose_end callback"); },
onresize_end: function() { alert("END South pane resize \n\n onresize_end callback \n\n NOTE: onresize_start event was skipped."); }
},
west: {
size: 250,
spacing_closed: 21,
togglerLength_closed: 21,
togglerAlign_closed: "top",
togglerLength_open: 0,
togglerTip_open: "Close West Pane",
togglerTip_closed: "Open West Pane",
resizerTip_open: "Resize West Pane",
slideTrigger_open: "click",
initClosed: true,
fxSettings_open: { easing: "easeOutBounce" }
},
east: {
size: 250,
spacing_closed: 21,
togglerLength_closed: 21,
togglerAlign_closed: "top",
togglerLength_open: 0,
togglerTip_open: "Close East Pane",
togglerTip_closed: "Open East Pane",
resizerTip_open: "Resize East Pane",
slideTrigger_open: "mouseover",
initClosed: true,
fxName: "drop",
fxSpeed: "normal",
fxSettings: { easing: "" }
},
center: {
paneSelector: "#mainContent",
minWidth: 200,
minHeight: 200
}
};
$(function() {
var outerLayout, innerLayout;
outerLayout = $("body").layout(layoutSettings_Outer);
outerLayout.addToggleBtn("#tbarToggleNorth", "north");
outerLayout.addOpenBtn("#tbarOpenSouth", "south");
outerLayout.addCloseBtn("#tbarCloseSouth", "south");
outerLayout.addPinBtn("#tbarPinWest", "west");
outerLayout.addPinBtn("#tbarPinEast", "east");
var westSelector = "body > .ui-layout-west",
eastSelector = "body > .ui-layout-east";
$("<span></span>").addClass("pin-button").prependTo(westSelector);
$("<span></span>").addClass("pin-button").prependTo(eastSelector);
outerLayout.addPinBtn(westSelector + " .pin-button", "west");
outerLayout.addPinBtn(eastSelector + " .pin-button", "east");
$("<span></span>").attr("id", "west-closer").prependTo(westSelector);
$("<span></span>").attr("id", "east-closer").prependTo(eastSelector);
outerLayout.addCloseBtn("#west-closer", "west");
outerLayout.addCloseBtn("#east-closer", "east");
$("a").each(function() {
var path = document.location.href;
if (path.substr(path.length - 1) == "#") path = path.substr(0, path.length - 1);
if (this.href.substr(this.href.length - 1) == "#") this.href = path + "#";
});
});
body { font-size: 85%; }
<link href="http://layout.jquery-dev.net/demos/css/complex.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="http://layout.jquery-dev.net/lib/js/jquery.layout-latest.js"></script>
<script type="text/javascript" src="http://layout.jquery-dev.net/demos/js/complex.js"></script>
<script type="text/javascript" src="http://layout.jquery-dev.net/lib/js/debug.js"></script>
<div class="ui-layout-west">
<div class="header">Outer - West</div>
<div class="content">
<h3><b>Outer Layout</b></h3>
<ul>
<li><a href="#" onClick="outerLayout.toggle('north')">Toggle North</a></li>
<li><a href="#" onClick="outerLayout.toggle('south')">Toggle South</a></li>
<li><a href="#" onClick="outerLayout.toggle('west')"> Toggle West</a></li>
<li><a href="#" onClick="outerLayout.toggle('east')"> Toggle East</a></li>
<li><a href="#" onClick="outerLayout.hide('north')">Hide North</a></li>
<li><a href="#" onClick="outerLayout.hide('south')">Hide South</a></li>
<li><a href="#" onClick="outerLayout.show('south', false)">Unhide South</a></li>
<li><a href="#" onClick="outerLayout.hide('east')"> Hide East</a></li>
<li><a href="#" onClick="outerLayout.show('east', false)">Unhide East</a></li>
<li><a href="#" onClick="outerLayout.open('east')"> Open East</a></li>
<li><a href="#" onClick="outerLayout.open('north'); outerLayout.sizePane('north', 'auto')"> Resize North="auto"</a></li>
<li><a href="#" onClick="outerLayout.sizePane('north', 100); outerLayout.open('north')"> Resize North=100</a></li>
<li><a href="#" onClick="outerLayout.sizePane('north', 300); outerLayout.open('north')"> Resize North=300</a></li>
<li><a href="#" onClick="outerLayout.sizePane('north', 10000); outerLayout.open('north')">Resize North=10000</a></li>
<li><a href="#" onClick="outerLayout.open('south'); outerLayout.sizePane('south', 'auto')"> Resize South="auto"</a></li>
<li><a href="#" onClick="outerLayout.sizePane('south', 100); outerLayout.open('south')"> Resize South=100</a></li>
<li><a href="#" onClick="outerLayout.sizePane('south', 300); outerLayout.open('south')"> Resize South=300</a></li>
<li><a href="#" onClick="outerLayout.sizePane('south', 10000); outerLayout.open('south')">Resize South=10000</a></li>
<li><a href="#" onClick="outerLayout.panes.north.css('backgroundColor','#FCC')">North Color = Red</a></li>
<li><a href="#" onClick="outerLayout.panes.north.css('backgroundColor','#CFC')">North Color = Green</a></li>
<li><a href="#" onClick="outerLayout.panes.north.css('backgroundColor','')"> North Color = Default</a></li>
<li><a href="#" onClick="alert('outerLayout.name = \''+outerLayout.options.name+'\'')">Show Layout Name</a></li>
<li><a href="#" onClick="showOptions(outerLayout,'defaults')">Show Options.Defaults</a></li>
<li><a href="#" onClick="showOptions(outerLayout,'north')"> Show Options.North</a></li>
<li><a href="#" onClick="showOptions(outerLayout,'south')"> Show Options.South</a></li>
<li><a href="#" onClick="showOptions(outerLayout,'west')"> Show Options.West</a></li>
<li><a href="#" onClick="showOptions(outerLayout,'east')"> Show Options.East</a></li>
<li><a href="#" onClick="showOptions(outerLayout,'center')"> Show Options.Center</a></li>
<li><a href="#" onClick="showState(outerLayout,'container')"> Show State.Container</a></li>
<li><a href="#" onClick="showState(outerLayout,'north')"> Show State.North</a></li>
<li><a href="#" onClick="showState(outerLayout,'south')"> Show State.South</a></li>
<li><a href="#" onClick="showState(outerLayout,'west')"> Show State.West</a></li>
<li><a href="#" onClick="showState(outerLayout,'east')"> Show State.East</a></li>
<li><a href="#" onClick="showState(outerLayout,'center')"> Show State.Center</a></li>
</ul>
</div>
<div class="footer">Automatically positioned footer</div>
</div>
<div class="ui-layout-east">
<div class="header">Outer - East</div>
<div class="subhead">I'm a subheader</div>
<div class="content">
<h3><b>Inner Layout</b></h3>
<ul id="createInner">
<li><a href="#" onClick="createInnerLayout(); return false;">CREATE Inner Layout</a></li>
</ul>
<ul id="innerCommands" style="display: none;">
<li><a href="#" onClick="innerLayout.toggle('north')">Toggle North</a></li>
<li><a href="#" onClick="innerLayout.toggle('south')">Toggle South</a></li>
<li><a href="#" onClick="innerLayout.toggle('west')"> Toggle West</a></li>
<li><a href="#" onClick="innerLayout.toggle('east')"> Toggle East</a></li>
<li><a href="#" onClick="innerLayout.hide('north')">Hide North</a></li>
<li><a href="#" onClick="innerLayout.hide('south')">Hide South</a></li>
<li><a href="#" onClick="innerLayout.hide('west')"> Hide West</a></li>
<li><a href="#" onClick="innerLayout.hide('east')"> Hide East</a></li>
<li><a href="#" onClick="innerLayout.show('east')"> Show East</a></li>
<li><a href="#" onClick="innerLayout.sizePane('north', 50); innerLayout.open('north')"> Resize North=50</a></li>
<li><a href="#" onClick="innerLayout.sizePane('north', 300); innerLayout.open('north')"> Resize North=300</a></li>
<li><a href="#" onClick="innerLayout.sizePane('north', 10000); innerLayout.open('north')">Resize North=10000</a></li>
<li><a href="#" onClick="innerLayout.sizePane('south', 50); innerLayout.open('south')"> Resize South=50</a></li>
<li><a href="#" onClick="innerLayout.sizePane('south', 300); innerLayout.open('south')"> Resize South=300</a></li>
<li><a href="#" onClick="innerLayout.sizePane('south', 10000); innerLayout.open('south')">Resize South=10000</a></li>
<li><a href="#" onClick="innerLayout.panes.north.css('backgroundColor','#FCC')">North Color = Red</a></li>
<li><a href="#" onClick="innerLayout.panes.north.css('backgroundColor','#CFC')">North Color = Green</a></li>
<li><a href="#" onClick="innerLayout.panes.north.css('backgroundColor','')"> North Color = Default</a></li>
<li><a href="#" onClick="alert('innerLayout.name = \''+innerLayout.options.name+'\'')">Show Layout Name</a></li>
<li><a href="#" onClick="showOptions(innerLayout,'defaults')">Show Options.Defaults</a></li>
<li><a href="#" onClick="showOptions(innerLayout,'north')"> Show Options.North</a></li>
<li><a href="#" onClick="showOptions(innerLayout,'south')"> Show Options.South</a></li>
<li><a href="#" onClick="showOptions(innerLayout,'west')"> Show Options.West</a></li>
<li><a href="#" onClick="showOptions(innerLayout,'east')"> Show Options.East</a></li>
<li><a href="#" onClick="showOptions(innerLayout,'center')"> Show Options.Center</a></li>
<li><a href="#" onClick="showState(innerLayout,'container')"> Show State.Container</a></li>
<li><a href="#" onClick="showState(innerLayout,'north')"> Show State.North</a></li>
<li><a href="#" onClick="showState(innerLayout,'south')"> Show State.South</a></li>
<li><a href="#" onClick="showState(innerLayout,'west')"> Show State.West</a></li>
<li><a href="#" onClick="showState(innerLayout,'east')"> Show State.East</a></li>
<li><a href="#" onClick="showState(innerLayout,'center')"> Show State.Center</a></li>
</ul>
</div>
<div class="footer">I'm a footer</div>
<div class="footer">I'm another footer</div>
<div class="footer">Unlimited headers & footers</div>
</div>
<div class="ui-layout-north">
<div class="header">Outer - North</div>
<div class="content">
I only have toggler when 'closed' - I cannot be resized - and I do not 'slide open'
</div>
<ul class="toolbar">
<li id="tbarToggleNorth" class="first"><span></span>Toggle NORTH</li>
<li id="tbarOpenSouth"><span></span>Open SOUTH</li>
<li id="tbarCloseSouth"><span></span>Close SOUTH</li>
<li id="tbarPinWest"><span></span>Pin/Unpin WEST</li>
<li id="tbarPinEast" class="last"><span></span>Pin/Unpin EAST</li>
</ul>
</div>
<div class="ui-layout-south">
<div class="header">Outer - South</div>
<div class="content">
<p>I only have a resizer/toggler when 'open'</p>
</div>
</div>
<div id="mainContent">
<div class="ui-layout-center">
<h3 class="header">Inner - Center</h3>
<div class="ui-layout-content">
<p id="createInner2" style="font-weight: bold;"><a href="#" onClick="createInnerLayout(); return false;">Click here to CREATE the Inner Layout</a></p>
<p>See the <a href="#" onclick="outerLayout.open('east'); return false;">Outer-East pane</a> for commands to manipulate the Inner Layout</p>
<p><a href="../demos.html">Go to the Demos page</a></p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
</div>
<div class="footer">Center panes can have headers & footers too</div>
</div>
<div class="ui-layout-north"> Inner - North</div>
<div class="ui-layout-south"> Inner - South</div>
<div class="ui-layout-west"> Inner - West</div>
<div class="ui-layout-east"> Inner - East
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
</div>
</div>
Per Steven Hunt's answer, I have a workaround by adding try/catch blocks, and removing a recursive call.
Replace the block below (from around line 149ish) with this modified version-
try
{
if ( opts.anchorToWindow ) {
// Account for margin or border on the splitter container and enforce min height
splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom");
splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20);
$(window).bind("resize", function(){
var top = splitter.offset().top;
var wh = $(window).height();
splitter.css("height", Math.max(wh-top-splitter._hadjust, splitter._hmin)+"px");
}).trigger("resize");
}
else if ( opts.resizeToWidth && !$.browser.msie )
$(window).bind("resize", function(){
splitter.trigger("resize");
});
}
catch(err)
{
}