2011-11-20 2 views
0

좋아, 내가 질문을하고 있지만, 질문이 사라져서, 그래서 나는 무언가를 만들고있다. 참고로, 최우선 순위가 아니므로 의무감을 느끼지 마십시오.sortable의 jquery 스왑 정렬

어느 쪽이든, 제대로 작동하지 않기 때문에 어디로 가야할지 조언이 필요합니다. 나는 노드 스왑 다운을 가지고 있지만, 제대로 스왑 할 수는 없다. 나는 요소들을 적절히 다루지 않는다고 생각합니다.

1 2 3 4 5

한 후 2 이상이면 (x는 1 셀 들고)

첫 번째 단계는 스왑 그래서, 기본적으로 이동하는 원소로 가야했다 :

X 2 3 4 5

1이면 3 이상 :

2 3 4 5 X

이것은 내가 지금까지 가지고있는 것입니다. "_rearrange"전화 교환에서 "정렬"합니다 ($) 기능 "_mouseDrag"에서

_NodeHold_pos: false, 

// return what n1 get's replaced with 
nodeSwap: function(n1, n2) { 
    // not null and not same node and both have parents 
    // hmm, !n1.isSameNode(n2) doesn't work here for some reason 
    if (n1 && n2 && n1 != n2 && n1.parentNode && n2.parentNode) { 
     // if they don't have same parent, we need to make sure they don't contain each other (untested) 
     if (!n1.parentNode.isSameNode(n2.parentNode)) { 
      prnt = n1.parentNode; 
      while (prnt) { 
       if (prnt.isSameNode(n2)) return; 
      } 
      prnt = n2.parentNode; 
      while (prnt) { 
       if (prnt.isSameNode(n1)) return; 
      } 
     } 
     n1h = n1.cloneNode(true); 
     n1.parentNode.replaceChild(n1h,n1); 
     n2.parentNode.replaceChild(n1,n2); 
     n1h.parentNode.replaceChild(n2,n1h); 
     //sn2.parentNode.removeChild(n1h); 
     return n2; 
    } 
    return n1; 
}, 

_rearrange2: function(event, i) { 
    var n1 = this.placeholder[0]; 
    var n2 = (this.direction == 'down' || !i.item[0].nextSibling? i.item[0] : i.item[0].nextSibling); 

    if (n2 && !this._NodeHold_pos) { 
     this._NodeHold_pos = this.nodeSwap(n1,n2); 
    } else if (n2) { 
     var hold = n1; 
     this.nodeSwap(n1,this._NodeHold_pos); 
     this._NodeHold_pos = this.nodeSwap(n1,n2); 
    } 

    //Various things done here to improve the performance: 
    // 1. we create a setTimeout, that calls refreshPositions 
    // 2. on the instance, we have a counter variable, that get's higher after every append 
    // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same 
    // 4. this lets only the last addition to the timeout stack through 
    this.counter = this.counter ? ++this.counter : 1; 
    var self = this, counter = this.counter; 

    window.setTimeout(function() { 
     if(counter == self.counter) self.refreshPositions(true); //Precompute after each DOM insertion, NOT on mousemove 
    },0); 
}, 

는 토글 설정, "_rearrange2"기능 "_mouseStop"에서

   //* <-- add '/' in front for this or remove for next 
       this._rearrange(event, item); 
       /*/ 
       this._rearrange2(event,item); 
       //*/ 

를 추가하는 것입니다 "_NodeHold_pos"를 거짓으로 되 돌린다

나는 그것이 내가 설정 한 전부라고 생각한다. 어느 쪽이든, 스왑을 테스트하고 작동하는 것처럼 보이지만 다시 되돌리려 고 할 때 null 노드가 계속 전송되어 계속해서 멈추게됩니다. 나는 이것이 이상한 행동을 일으킨다 고 생각한다.

아, HTML (이 데모에서입니다) :

<html> 
<head> 
<script src="../jquery-1.7.min.js" type="text/javascript"></script> 
<script src="../jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script> 
<link rel="stylesheet" href="../jquery-ui-1.8.16.custom.css"></link> 
<script src="../jquery/development-bundle/ui/jquery.ui.sortable.js" type="text/javascript"></script> 
</head> 
<body> 
<meta charset="utf-8"> 
    <style> 
    #sortable2 { list-style-type: none; margin: 0; padding: 0; zoom: 1; } 
    #sortable2 li { margin: 0 5px 5px 5px; padding: 3px; width: 90%; } 
    </style> 
<script> 
    $(function() { 
     $("#sortable2").sortable({ tolerance: 'pointer', 
      //items: "li:not(.ui-state-disabled)", 
      cancel: ".ui-state-disabled", 
     }); 
     $("#sortable2 li").disableSelection(); 
    }); 
</script> 
<div class="demo"> 
<h3 class="docs">Cancel sorting (but keep as drop targets):</h3> 

<ul id="sortable2"> 
    <li class="ui-state-default">Item 1</li> 
    <li class="ui-state-default">Item 2</li> 
    <li class="ui-state-default">Item 3</li> 
    <li class="ui-state-default ui-state-disabled">(I'm not sortable)</li> 
    <li class="ui-state-default ui-state-disabled">(I'm not sortable)</li> 
    <li class="ui-state-default">Item 4</li> 
</ul> 

</div> 
</body> 
</html> 

편집 : 당신은 rearrange2의 부분을 주석 (그리고이 호출되고이) 그냥 스왑 호출하는 경우 :

this.nodeSwap(n1,n2); 
    /* 
    if (n2 && !this._NodeHold_pos) { 
     this._NodeHold_pos = this.nodeSwap(n1,n2); 
    } else if (n2) { 
     var hold = n1; 
     this.nodeSwap(n1,this._NodeHold_pos); 
     this._NodeHold_pos = this.nodeSwap(n1,n2); 
    } 
    */ 

그 스왑 종류의 작품을 볼 수 있습니다. 어쩌면 먼저 해결해야 할 것 같습니다. 때로는 매달 리며 때로는 모든 것을 푸시하지만 대부분은 작동합니다. 테스트 할 때 노드를 볼 수있을 때도 노드가 정의되지 않은 경우가 있습니다. DOM 등을 새로 고쳐야합니까?

답변

2

글쎄, 잠시 동안 만져본 적이 없으며 아무도 대답하지 않으므로. 좋아, 나는 스왑 기능을 작동하게했다. 가장 큰 문제는 재 배열이 내가 보지 못했던 몇 곳에서 호출되었다는 것입니다 (이 때문에 두 변수를 함수로 전달한 이유가 무엇입니까). 그리고 n2가 다른 유형의 정렬로 설정되었습니다. 또한 스왑은 JQuery의 설정에 대해 부모님을 확인할 필요가 없습니다.

는 여기를 설정하려면 내가 시험에 사용되는 HTML입니다 :

<html> 
<head> 
<script src="jquery-1.7.1.min.js" type="text/javascript"></script> 
<script src="jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script> 
<link rel="stylesheet" href="jquery-ui-1.8.16.custom.css"></link> 
<!-- this is from the development bundle so that it can be seen easier --> 
<script src="jquery.ui.sortable.js" type="text/javascript"></script> 
<meta charset="utf-8"> 
<style> 
#sortable1, #sortable2 { list-style-type: none; margin: 0; padding: 0; zoom: 1; } 
#sortable1 li { margin: 0 5px 5px 5px; padding: 3px; width: 40%; } 
#sortable2 li { margin: 0 5px 5px 5px; padding: 3px; width: 30%; } 
</style> 
<script> 
    $(function() { 
     $(".sortable").sortable({ tolerance: 'pointer',cancel: ".ui-state-disabled",}); 
     $(".sortable li").disableSelection(); 
    }); 
</script> 
</head> 
<body> 
<ul class="sortable" id="sortable1"> 
    <li class="ui-state-default">Item 1</li> 
    <li class="ui-state-default">Item 2</li> 
    <li class="ui-state-default">Item 3</li> 
    <li class="ui-state-default ui-state-disabled">(I'm not sortable 1)</li> 
    <li class="ui-state-default ui-state-disabled">(I'm not sortable 2)</li> 
    <li class="ui-state-default">Item 4</li> 
    <ul class="sortable" id="sortable2"> 
     <li class="ui-state-default">sub 2</li> 
     <li class="ui-state-default">sub 3</li> 
    </ul> 
</ul> 
</body> 
</html> 

은 나뿐만 아니라 다른 것들에 대한 테스트하기 위해 일부 서브 노드를 사용가.

내가 포함시킨 jquery.ui.sortable.js 파일에서 다음과 같이 변경했습니다.함수 _rearrange를 들어

, 나는 다음으로 대체 :

_NodeHold_pos: false, 

// return what n1 get's swapped with 
nodeSwap: function(n1, n2) { 
    if (n1 && n2 && n1 !== n2) { 
     var n1h = n1.cloneNode(false); 
     n1.parentNode.replaceChild(n1h,n1); 
     n2.parentNode.replaceChild(n1,n2); 
     n1h.parentNode.replaceChild(n2,n1h); 
     return n2; 
    } 
    return n1; 
}, 

// _rearrange rework for specific sort 
_rearrange: function(event, i, a, hardRefresh) { 

    if (a) { 
     a[0].appendChild(this.placeholder[0]); 
     return; 
    } 

    var n1 = this.placeholder[0]; 
    var n2 = i.item[0]; 
    /* 
    // swap in place, from where you were last (during mouseovers) 
    this.nodeSwap(n1,n2); 
    /*/ 
    // swap from original position (before picking up node) 
    if (this._NodeHold_pos === false) { 
     this._NodeHold_pos = this.nodeSwap(n1,n2); 
    } else if (n2 === this._NodeHold_pos) { 
     this.nodeSwap(n1,n2); 
     this._NodeHold_pos = false; 
    } else if (n1 !== this._NodeHold_pos) { 
     this.nodeSwap(n1,this._NodeHold_pos); 
     this._NodeHold_pos = this.nodeSwap(n1,n2); 
    } else { 
     alert("here"); 
     this._NodeHold_pos = false; // shouldn't really reach this 
    } 
    //*/ 
    this.counter = this.counter ? ++this.counter : 1; 
    var self = this, counter = this.counter; 

    window.setTimeout(function(){ 
     if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove 
    },0); 
}, 

나는 _mousestop이 라인을 추가 :

this._NodeHold_pos = false; 

지금은 잘 작동합니다. 나는 두 가지 다른 스왑을 사용했는데 (왜냐하면 나는 무엇이 버그가 될지 모르기 때문에), 둘 다 똑같이 작동하는 것처럼 보였으므로 코드가 적은 것을 선택했습니다.

저는 처음 시작한 원래 질문에 답하는 것이 아니지만이 방법이 효과적이므로이 질문에 대한 답을 얻을 수 있습니다.

관련 문제