javascript Splitter.js 不适用于新版本的 jQuery
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10097458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Splitter.js won't work with new versions of jQuery
提问by Colin Davis
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
代码来自http://methvin.com/splitter/具体JS在http://methvin.com/splitter/splitter.js
When using jQuery v1.5.2, the code works correctly.
使用 jQuery v1.5.2 时,代码工作正常。
When I move to jQuery v1.7.2, the code fails, and gives a "Too Much recursion" error. This also appears to happen when I use jQuery 1.6.2
当我使用 jQuery v1.7.2 时,代码失败,并给出“递归过多”错误。当我使用 jQuery 1.6.2 时,这似乎也会发生
Does anyone have a workaround for this?
有没有人有解决方法?
I did find an (updated?) version of splitter.js at https://bungeni-exist.googlecode.com/svn-history/r188/xq-framework/trunk/db/framework/assets/bungeni/scripts/splitter.jsbut this doesn't appear to solve the problem.
我确实在https://bungeni-exist.googlecode.com/svn-history/r188/xq-framework/trunk/db/framework/assets/bungeni/scripts/splitter找到了一个(更新?)版本的 splitter.js 。 js,但这似乎并没有解决问题。
Any advice would be appreciated.
任何意见,将不胜感激。
采纳答案by Steven Hunt
I was experiencing this same issue. After looking around in the splitter.js file for a while, I came across this section of code:
我遇到了同样的问题。在 splitter.js 文件中查看了一段时间后,我发现了这部分代码:
// 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 :)
“哟dawg”参考是死赠品:)
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.
果然,在 Chrome 中调试后,这个特定的事件处理函数存在过多的递归。编写它的开发人员试图解决该问题,但由于某种原因,较新版本的 JQuery 库无法按预期工作,并且从未满足转义条件。据我所知,这段特定的代码仅在页面加载期间用于设置拆分器的初始位置。我发现除了堆栈溢出之外,拆分器仍然可用,我注意到这个问题的唯一原因是因为我的 javascript 代码在初始化拆分器后没有运行。如果你有时间,看看你是否能找出为什么这部分代码不起作用并发布修复程序。如果您赶时间并且不介意使用胶带,请在调用 . 分离器()函数。它似乎在 Chrome 19 和 IE 9 中都可以正常工作。
回答by jd.
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.
jQuery.browser
在https://github.com/e1ven/jQuery-Splitter有一个 jQuery.splitter 的更新分支,它适用于 jQuery 1.8(如果你恢复,也是 1.9 )。
回答by SpYk3HH
UI-Layoutstays up-to-date and does "splitting" and alot more, and is fairly easy to use.
UI-Layout保持最新状态并进行“拆分”等等,并且相当易于使用。
Extremely Minimalist Example
极简主义的例子
$('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>
Complex Demo
复杂的演示
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>
Advanced Complex Demo
高级复杂演示
回答by Jeremie Wood
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:
我在将站点升级到 jQuery 1.8 的过程中遇到了同样的问题。在对代码进行了一些调试和探索之后,在我看来有两个问题:resize 事件在一些地方被不必要地触发,并且在设置拆分器的调整大小事件处理程序之前在拆分器上触发了它. 我改变了最后两段代码的顺序,以确保首先设置拆分器的调整大小事件处理程序并整理几行。现在看起来像这样:
// 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 repoif you want to see it all in one place.
来自 reSplit 函数。如果您想在一个地方查看所有内容,我已将整个内容上传到GitHub 存储库。
回答by Colin Davis
Per Steven Hunt's answer, I have a workaround by adding try/catch blocks, and removing a recursive call.
根据 Steven Hunt 的回答,我有一个解决方法,即添加 try/catch 块并删除递归调用。
Replace the block below (from around line 149ish) with this modified version-
用这个修改后的版本替换下面的块(从大约 149ish 行开始)-
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)
{
}