Splitter.js не будет работать с новыми версиями jQuery

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, но это, похоже, не решает проблему.

Любые советы будут оценены.

Ответы

Ответ 1

У меня возникла такая же проблема. Осмотревся в файле 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]);

Ссылка "yo dawg" была мертвой поддачей:)

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

Ответ 2

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

Ответ 3

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

Крайне минималистский пример

$('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>

Ответ 4

Я столкнулся с той же проблемой при обновлении сайта до jQuery 1.8. После немного отладки и ковыряния в коде, мне кажется, что возникли две проблемы: событие изменения размера запускалось без необходимости в нескольких местах, и оно срабатывало на разделителе до того, как был настроен обработчик событий изменения размера разделителя, Я переключил порядок последних двух кусков кода, чтобы убедиться, что обработчик события изменения размера разделителя настроен первым и прибрал несколько строк. Теперь он выглядит следующим образом:

  // 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");

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

Ответ 5

В ответ Стивена Ханта, у меня есть обходное решение, добавляя блоки 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)
        {
        }