2013-10-17 60 views
4

我使用設在這裏這個jQuery分路器插件:http://methvin.com/splitter/jQuery的分路器插件得到錯誤太多遞歸

這是工作的罰款與我使用的jQuery的版本,直到我讓resizeToWidth屬性然後它給我的錯誤:遞歸太多。

這裏是一個演示中,我上的jsfiddle創建一個鏈接:http://jsfiddle.net/S97rv/4/

㈣看着插件代碼,但我不是一個JavaScript專家,不想惹它來了。

任何人都可以看到這個錯誤的解決方案嗎?

這裏是插件代碼,但可能會更好,只是在看的jsfiddle鏈接:

;(function($){ 

$.fn.splitter = function(args){ 
args = args || {}; 
return this.each(function() { 
    var zombie;  // left-behind splitbar for outline resizes 
    function startSplitMouse(evt) { 
     if (opts.outline) 
      zombie = zombie || bar.clone(false).insertAfter(A); 
     panes.css("-webkit-user-select", "none"); // Safari selects A/B text on a move 
     bar.addClass(opts.activeClass); 
     A._posSplit = A[0][opts.pxSplit] - evt[opts.eventPos]; 
     $(document) 
      .bind("mousemove", doSplitMouse) 
      .bind("mouseup", endSplitMouse); 
    } 
    function doSplitMouse(evt) { 
     var newPos = A._posSplit+evt[opts.eventPos]; 
     if (opts.outline) { 
      newPos = Math.max(0, Math.min(newPos, splitter._DA - bar._DA)); 
      bar.css(opts.origin, newPos); 
     } else 
      resplit(newPos); 
    } 
    function endSplitMouse(evt) { 
     bar.removeClass(opts.activeClass); 
     var newPos = A._posSplit+evt[opts.eventPos]; 
     if (opts.outline) { 
      zombie.remove(); zombie = null; 
      resplit(newPos); 
     } 
     panes.css("-webkit-user-select", "text"); // let Safari select text again 
     $(document) 
      .unbind("mousemove", doSplitMouse) 
      .unbind("mouseup", endSplitMouse); 
    } 
    function resplit(newPos) { 
     // Constrain new splitbar position to fit pane size limits 
     newPos = Math.max(A._min, splitter._DA - B._max, 
       Math.min(newPos, A._max, splitter._DA - bar._DA - B._min)); 
     // Resize/position the two panes 
     bar._DA = bar[0][opts.pxSplit];  // bar size may change during dock 
     bar.css(opts.origin, newPos).css(opts.fixed, splitter._DF); 
     A.css(opts.origin, 0).css(opts.split, newPos).css(opts.fixed, splitter._DF); 
     B.css(opts.origin, newPos+bar._DA) 
      .css(opts.split, splitter._DA-bar._DA-newPos).css(opts.fixed, splitter._DF); 
     // IE fires resize for us; all others pay cash 
     if (!$.browser.msie) 
      panes.trigger("resize"); 
    } 
    function dimSum(jq, dims) { 
     // Opera returns -1 for missing min/max width, turn into 0 
     var sum = 0; 
     for (var i=1; i < arguments.length; i++) 
      sum += Math.max(parseInt(jq.css(arguments[i])) || 0, 0); 
     return sum; 
    } 

    // Determine settings based on incoming opts, element classes, and defaults 
    var vh = (args.splitHorizontal? 'h' : args.splitVertical? 'v' : args.type) || 'v'; 
    var opts = $.extend({ 
     activeClass: 'active', // class name for active splitter 
     pxPerKey: 8,   // splitter px moved per keypress 
     tabIndex: 0,   // tab order indicator 
     accessKey: ''   // accessKey for splitbar 
    },{ 
     v: {     // Vertical splitters: 
      keyLeft: 39, keyRight: 37, cursor: "e-resize", 
      splitbarClass: "vsplitbar", outlineClass: "voutline", 
      type: 'v', eventPos: "pageX", origin: "left", 
      split: "width", pxSplit: "offsetWidth", side1: "Left", side2: "Right", 
      fixed: "height", pxFixed: "offsetHeight", side3: "Top", side4: "Bottom" 
     }, 
     h: {     // Horizontal splitters: 
      keyTop: 40, keyBottom: 38, cursor: "n-resize", 
      splitbarClass: "hsplitbar", outlineClass: "houtline", 
      type: 'h', eventPos: "pageY", origin: "top", 
      split: "height", pxSplit: "offsetHeight", side1: "Top", side2: "Bottom", 
      fixed: "width", pxFixed: "offsetWidth", side3: "Left", side4: "Right" 
     } 
    }[vh], args); 

    // Create jQuery object closures for splitter and both panes 
    var splitter = $(this).css({position: "relative"}); 
    var panes = $(">*", splitter[0]).css({ 
     position: "absolute",   // positioned inside splitter container 
     "z-index": "1",     // splitbar is positioned above 
     "-moz-outline-style": "none" // don't show dotted outline 
    }); 
    var A = $(panes[0]);  // left or top 
    var B = $(panes[1]);  // right or bottom 

    // Focuser element, provides keyboard support; title is shown by Opera accessKeys 
    var focuser = $('<a href="javascript:void(0)"></a>') 
     .attr({accessKey: opts.accessKey, tabIndex: opts.tabIndex, title: opts.splitbarClass}) 
     .bind($.browser.opera?"click":"focus", function(){ this.focus(); bar.addClass(opts.activeClass) }) 
     .bind("keydown", function(e){ 
      var key = e.which || e.keyCode; 
      var dir = key==opts["key"+opts.side1]? 1 : key==opts["key"+opts.side2]? -1 : 0; 
      if (dir) 
       resplit(A[0][opts.pxSplit]+dir*opts.pxPerKey, false); 
     }) 
     .bind("blur", function(){ bar.removeClass(opts.activeClass) }); 

    // Splitbar element, can be already in the doc or we create one 
    var bar = $(panes[2] || '<div></div>') 
     .insertAfter(A).css("z-index", "100").append(focuser) 
     .attr({"class": opts.splitbarClass, unselectable: "on"}) 
     .css({position: "absolute", "user-select": "none", "-webkit-user-select": "none", 
      "-khtml-user-select": "none", "-moz-user-select": "none"}) 
     .bind("mousedown", startSplitMouse); 
    // Use our cursor unless the style specifies a non-default cursor 
    if (/^(auto|default|)$/.test(bar.css("cursor"))) 
     bar.css("cursor", opts.cursor); 

    // Cache several dimensions for speed, rather than re-querying constantly 
    bar._DA = bar[0][opts.pxSplit]; 
    splitter._PBF = $.boxModel? dimSum(splitter, "border"+opts.side3+"Width", "border"+opts.side4+"Width") : 0; 
    splitter._PBA = $.boxModel? dimSum(splitter, "border"+opts.side1+"Width", "border"+opts.side2+"Width") : 0; 
    A._pane = opts.side1; 
    B._pane = opts.side2; 
    $.each([A,B], function(){ 
     this._min = opts["min"+this._pane] || dimSum(this, "min-"+opts.split); 
     this._max = opts["max"+this._pane] || dimSum(this, "max-"+opts.split) || 9999; 
     this._init = opts["size"+this._pane]===true ? 
      parseInt($.curCSS(this[0],opts.split)) : opts["size"+this._pane]; 
    }); 

    // Determine initial position, get from cookie if specified 
    var initPos = A._init; 
    if (!isNaN(B._init)) // recalc initial B size as an offset from the top or left side 
     initPos = splitter[0][opts.pxSplit] - splitter._PBA - B._init - bar._DA; 
    if (opts.cookie) { 
     if (!$.cookie) 
      alert('jQuery.splitter(): jQuery cookie plugin required'); 
     var ckpos = parseInt($.cookie(opts.cookie)); 
     if (!isNaN(ckpos)) 
      initPos = ckpos; 
     $(window).bind("unload", function(){ 
      var state = String(bar.css(opts.origin)); // current location of splitbar 
      $.cookie(opts.cookie, state, {expires: opts.cookieExpires || 365, 
       path: opts.cookiePath || document.location.pathname}); 
     }); 
    } 
    if (isNaN(initPos)) // King Solomon's algorithm 
     initPos = Math.round((splitter[0][opts.pxSplit] - splitter._PBA - bar._DA)/2); 

    // 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); 
     $(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"); 
      if (!$.browser.msie) splitter.trigger("resize"); 
     }).trigger("resize"); 
    } 
    else if (opts.resizeToWidth && !$.browser.msie) 
     $(window).bind("resize", function(){ 
      splitter.trigger("resize"); 
     }); 

    // 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; 
     // 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)); 
    }).trigger("resize" , [initPos]); 
}); 
}; 

})(jQuery); 
+0

在最新版本的jquery中使用此腳本也存在錯誤。 $ .browser折舊。 – user794846

+0

http://stackoverflow.com/questions/10097458/splitter-js-wont-work-with-new-versions-of-jquery可能的副本當你使用jQuery 1.5.2時,你的jsfiddle停止了拋出錯誤:http:// jsfiddle .net/S97rv/6/ – showdev

+0

感謝,讓我找到有用的信息 – user794846

回答

5

您正在使用的插件是基於jQuery的舊版本。出於某種原因,jQuery 1.6引入了無限遞歸,可能是由於事件冒泡。看起來好像在特定DOM元素上觸發的resize事件遵循事件傳播路徑,一直到document

在resize事件處理函數,你可以添加一個測試,以防止遞歸:

$(window).bind("resize", function (e) { 
    if (e.target === window) { splitter.trigger('resize'); } 
}); 

這樣的作品,至少在Chrome和Firefox瀏覽器。

使用jQuery Migrate plugin將允許您使用jQuery 1.9甚至2.0;但依靠瀏覽器的具體行爲通常是一種不好的做法。您可能會看看this splitter.js fork,它已經使用上面的相同測試修復了您的無限遞歸問題。

+2

謝謝,實際上我發現這個叉,它也修復了它也https://github.com/e1ven/jQuery-Splitter。 – user794846

+0

另一方面請注意,原作者在文檔中聲明瞭這一點:另一種方法是將leftDock,rightDock,topDock,bottomDock中的一個作爲字符串傳遞,該字符串指定默認的對接端。任何人都知道你會怎麼稱呼這個leve和正確的碼頭,我看不出如何去做。 – user794846