Вопрос по javascript, jquery – Splitter.js не будет работать с новыми версиями jQuery

14
I'm using Splitter.js in a project.

Код отhttp://methvin.com/splitter/ Конкретный JS находится наhttp://methvin.com/splitter/splitter.js

При использовании jQuery v1.5.2 код работает правильно.

Когда я перехожу на jQuery v1.7.2, код завершается ошибкой и выдает «Слишком много рекурсии». ошибка. Это также происходит, когда я использую jQuery 1.6.2

У кого-нибудь есть обходной путь для этого?

Я нашел (обновленную?) Версию splitter.js наhttps://bungeni-exist.googlecode.com/svn-history/r188/xq-framework/trunk/db/framework/assets/bungeni/scripts/splitter.js но это, похоже, не решает проблему.

Любой совет будет принят во внимание.

Ваш Ответ

5   ответов
6

1.8. После небольшой отладки и ковыряния в коде мне кажется, что возникли две проблемы: событие resize вызывалось без необходимости в нескольких местах, и оно запускалось на сплиттере до того, как обработчик события 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");
    });

Кроме того, убедитесь, что вы удалите

if ( !$.browser.msie ) panes.trigger("resize");

из функции повторного разделения. Я загрузил все это наGitHub репо если вы хотите увидеть все это в одном месте.

Спасибо, Джереми! Когда я пробую вашу версию Github, она не выглядит так, как будто она работает для basic-example.html или complex-example.html, какие примеры документации он дает? Я пробовал использовать jQuery с версиями 1.8 и 1.7, но результат кажется одинаковым? Возможно я делаю что-то не так. То, как я ее решаю, - это ПУТЬ грубее - в основном пустые операторы try / catch для «съесть» ошибки. Это работает, но это НЕ правильный способ решить эту проблему, поэтому я с удовольствием переключусь на ваше решение. Вы можете увидеть мое решение (а также две его тестовые страницы) наgithub.com/e1ven/jQuery-Splitter Colin Davis
9

который работает с jQuery 1.8 (также 1.9, если вы восстанавливаетеjQuery.browser) вhttps://github.com/e1ven/jQuery-Splitter.

2

у меня есть обходной путь, добавляя блоки try / catch и удаляя рекурсивный вызов.

Замените блок ниже (из строки 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)
        {
        }
7

UI-макет остается в курсе и делает "расщепление" и многое другое, и довольно прост в использовании.

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="#" onClic,k="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 &amp; 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 &amp; 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
Я уверен, что это здорово, но мне не нужно переписывать сайт. Colin Davis
4

r.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]);

«Йо-Дауг» Ссылка была мертвой раздачей :)

Конечно же, после отладки в Chrome в этой конкретной функции обработчика событий возникает чрезмерная рекурсия. Разработчик, который написал это, попытался решить проблему, но по какой-то причине более новая версия библиотеки JQuery не работает должным образом, и условие escape никогда не выполняется. Из того, что я могу сказать, этот конкретный фрагмент кода используется только во время загрузки страницы, чтобы установить начальную позицию разделителя. Я обнаружил, что сплиттер все еще можно было использовать, кроме переполнения стека, и единственная причина, по которой я заметил проблему, заключалась в том, что мой код javascript после инициализации сплиттера не работал. Если у вас есть время, посмотрите, сможете ли вы выяснить, почему эта часть кода не работает, и опубликуйте исправление. Если вы спешите и не возражаете против использования клейкой ленты, поместите попытку в строку кода, где вы вызываете функцию .splitter (). Кажется, он отлично работает как в Chrome 19, так и в IE 9.

Спасибо! Я посмотрел на то, что ты сказал, я думаю, ты в правильном месте. - Я немного покопался, и, похоже, мне тоже нужно убрать строку if! MSIE, она кажется здоровой. Я опубликую свой код в качестве другого возможного ответа (слишком долго для комментария), пока не будет найдено реальное решение. Colin Davis
Вот отличное решение проблемы из другой ветки:stackoverflow.com/a/10505994/483708, Я также попробовал исправления, перечисленные в этой теме JeremieWood и jd, но они не сработали для меня с примером из 4 панелей (methvin.com/splitter/4psplitter.html). В обоих случаях один из разделительных столбцов (горизонтальный или вертикальный) в этом образце из 4 панелей не работал.

Похожие вопросы