可拖动元素有时会反弹

时间:2017-11-01 10:07:08

标签: jquery jquery-ui draggable

我在下面创建了这个代码段,并且我已经从jquery-ui添加了draggable。我一般它工作得很好,但有时当你拖动元素时,它们开始“弹跳”。

在“完整页面”中尝试然后它会发生

任何人都可以解释为什么会这样。?

这是演示

function loadTM(obj){
    var $this = obj; 
}

$(".add_list_text").on("click",function(){
    $(this).parent().addClass("active")
})

$("#add_list button").on("click",function() {
    if($(this).prev("input").val().length > 0)
    {
        var v = $(this).prev("input").val();
        $(".board_content").prepend(NewTask.format(v));
        $(this).prev("input").val("");
        $(".add_list.active").removeClass("active");
        runDrag();
    }
})

$(document).on("click",".list_head .title",function() {
    $(this).attr("contenteditable",true).focus() 
})

$(document).on("click",".list_footer .add_card",function(){
    $(".list_footer.active .add_card").val("")
    $(".list_footer.active").removeClass("active");
    $(this).closest(".list_footer").addClass("active")
})

$(document).on("click",".list_footer .add_card_form .add_card_button",function(){
    var v = $(this).closest(".add_card_form").find("textarea").val();
    $(this).closest(".list_c").find(".list_body").append(NewCard.format(v));
    $(this).closest(".add_card_form").find("textarea").val("");
    $(this).closest(".list_footer.active").removeClass("active")
})

$(".board_content").on("click",function(e) {
    if((e.target.id != "add_list" && 
        $(e.target).parents("#add_list").length == 0) && 
        $(".add_list.active").length > 0){
        $(".add_list.active").removeClass("active");
    }

    if((Array.from(e.target.classList).indexOf('title') == -1 &&
        $(e.target).parents("#add_list").length == 0)){
        $(".list_head .title[contenteditable=true]").attr("contenteditable",false)
    }
})






var NewTask = '<div class="list">'+
'<div class="list_c">'+
'<div class="list_head">'+
'<div class="title" contenteditable="false">{0}</div>'+
'</div>'+
'<div class="list_body"></div>'+
'<div class="list_footer">'+
'<div class="add_card_form">'+
'<textarea></textarea>'+
'<button type="button" class="btn btn-success add_card_button">Add</button>'+
'</div>'+
'<div class="add_card">Add a card..</div>'+
'</div>'+
'</div>'+
'</div>';

var NewCard = '<div class="card">'+
'<div class="card_title">{0}</div>'+
'</div>';


String.prototype.format = String.prototype.f = function() {
    var s = this,
        i = arguments.length;

    while (i--) {
        s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
    }
    return s;
};

$(document).ready(function(e) {
    $(".list_footer .add_card_form textarea").keypress(function(event) {
      if(e.which == '13') {
        return false;
      }
    });
    runDrag();
});

function runDrag(){
    $( ".list" ).sortable({
        revert: true
      });
    $( ".list_c" ).draggable({ 
        connectToSortable: ".list",
        revert: "invalid",
        start: function( event, ui ) {
            $(".list").addClass("dragChild");
        },
        stop: function( event, ui ) {
            $(".list").removeClass("dragChild");
        }
    });
}
.TM_board {
  background-color: #0079bf;
}
.TM_board .board_header {
  text-align: center;
  color: #7FB3D1;
  padding: 5px 8px;
  height: 30px;
  background-color: #0067A3;
}
.TM_board .board_header .board_header_left {
  float: left;
}
.TM_board .board_header .board_header_center {
  display: inline-block;
  font-weight: bold;
  font-style: italic;
}
.TM_board .board_header .board_header_right {
  float: right;
}
.TM_board .board_content {
  user-select: none;
  white-space: nowrap;
  margin-bottom: 10px;
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 10px;
  padding-right: 56px;
  min-height: 70vh;
  padding-top: 10px;
  display: flex;
}
.TM_board .board_content .list {
  width: 270px;
  margin: 0 5px;
  box-sizing: border-box;
  display: inline-block;
  vertical-align: top;
  white-space: nowrap;
}
.TM_board .board_content .list.dragChild {
  background: rgba(0, 0, 0, 0.12); 
}
.TM_board .board_content .list .list_c {
  background: #E2E4E6;
  border-radius: 3px;
  box-sizing: border-box;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  max-height: 100%;
  position: relative;
  white-space: normal;
  margin-bottom: 8px;
}
.TM_board .board_content .list .list_c .list_head {
  padding: 5px 8px;
  cursor: pointer;
}
.TM_board .board_content .list .list_c .list_body {
  padding: 5px 8px 0 8px;
}
.TM_board .board_content .list .list_c .list_body .card {
  background-color: #fff;
  border-bottom: 1px solid #ccc;
  border-radius: 3px;
  cursor: pointer;
  margin-bottom: 6px;
}
.TM_board .board_content .list .list_c .list_body .card .card_title {
  padding: 5px 8px;
  color: #444;
}
.TM_board .board_content .list .list_c .list_footer .add_card_form {
  display: none;
  padding: 5px 8px;
}
.TM_board .board_content .list .list_c .list_footer .add_card_form textarea {
  border: none;
  width: 100%;
  max-width: 100%;
  min-width: 100%;
  min-height: 50px;
  max-height: 230px;
  margin-top: 0px;
  margin-bottom: 0px;
  background-color: #fff;
  border-bottom: 1px solid #ccc;
  border-radius: 3px;
  overflow: hidden;
  word-wrap: break-word;
}
.TM_board .board_content .list .list_c .list_footer .add_card_form button {
  margin-top: 8px;
  padding: 5px 8px;
  min-width: 4rem;
  cursor: pointer;
}
.TM_board .board_content .list .list_c .list_footer .add_card {
  color: #838c91;
  display: block;
  -webkit-box-flex: 0;
  -webkit-flex: 0 0 auto;
  -ms-flex: 0 0 auto;
  flex: 0 0 auto;
  padding: 8px 10px;
  position: relative;
  text-decoration: none;
  user-select: none;
  cursor: pointer;
}
.TM_board .board_content .list .list_c .list_footer .add_card:hover {
  background-color: #CDD2D4;
  color: #4d4d4d;
  text-decoration: underline;
}
.TM_board .board_content .list .list_c .list_footer.active .add_card_form {
  display: block;
}
.TM_board .board_content .list .list_c .list_footer.active .add_card {
  display: none;
}
.TM_board .board_content .add_list {
  background: rgba(0, 0, 0, 0.12);
  cursor: pointer;
  color: #fff;
  height: 100%;
  min-height: 30px;
  padding: 4px;
  border-radius: 3px;
}
.TM_board .board_content .add_list .add_list_text {
  color: rgba(255, 255, 255, 0.7);
  line-height: 30px;
  padding-left: 5px;
  display: block;
}
.TM_board .board_content .add_list input {
  background: rgba(0, 0, 0, 0.05);
  border-color: #aaa;
  box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.15);
  display: none;
  margin: 0;
  width: 100%;
  box-sizing: border-box;
  -webkit-appearance: none;
  border: 1px solid #CDD2D4;
  border-radius: 3px;
  padding: 7px;
  color: #444;
}
.TM_board .board_content .add_list button {
  display: none;
  margin-top: 4px;
  clear: both;
}
.TM_board .board_content .add_list.active {
  background-color: #E2E4E6;
}
.TM_board .board_content .add_list.active .add_list_text {
  display: none;
}
.TM_board .board_content .add_list.active input {
  display: block;
}
.TM_board .board_content .add_list.active button {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="TM_board"> 
    <div class="board_header">
        <div class="board_header_left">search</div>
        <div class="board_header_center">TM</div>
        <div class="board_header_right"></div>
    </div>
    <div class="board_content">
        <div class="list">
            <div class="list_c">
                <div class="list_head">
                    <div class="title" contenteditable="false">Test</div>
                </div>
                <div class="list_body">
                    <div class="card">
                        <div class="card_title">Title</div>
                    </div>
                </div>
                <div class="list_footer">
                    <div class="add_card_form">
                        <textarea></textarea>
                        <button type="button" class="btn btn-success add_card_button">Add</button>
                    </div>
                    <div class="add_card">Add a card..</div>
                </div>
            </div>
        </div>
        <div class="list">
            <div class="list_c">
                <div class="list_head">
                    <div class="title" contenteditable="false">Test</div>
                </div>
                <div class="list_body">
                    <div class="card">
                        <div class="card_title">Title</div>
                    </div>
                </div>
                <div class="list_footer">
                    <div class="add_card_form">
                        <textarea></textarea>
                        <button type="button" class="btn btn-success add_card_button">Add</button>
                    </div>
                    <div class="add_card">Add a card..</div>
                </div>
            </div>
        </div>
        <div id="add_list" class="list add_list">
            <div class="add_list_text">Add a list...</div>
            <input placeholder="Add a list...">
            <button type="button" class="btn btn-success">Save</button>
        </div>
    </div>
</div>

1 个答案:

答案 0 :(得分:0)

很难确切地指出,因为拖拽和可拖动的拖拽都很多,你可以将两者混合在一起,但从我看到的情况来看,我说这个问题来自 draggable 与 connectToSortable sortable 相冲突。连接到可排序可拖动将根据您拖动它的位置激活和停用可排序。因此它可以触发可排序的停止。 但是你有可排序可拖动的元素,这意味着从可拖动 connectTosortable 可以触发停止在可归类的相同元素上。但是你的元素也是可以排序的,所以它会保留在序列中的其他位置。所以你最终会遇到相互冲突的行为。

您有不同的选项,最明显的选择是删除可拖动的,只保持可排序并连接它们之间的可排序。像这样:

&#13;
&#13;
function loadTM(obj){
    var $this = obj; 
}

$(".add_list_text").on("click",function(){
    $(this).parent().addClass("active")
})

$("#add_list button").on("click",function() {
    if($(this).prev("input").val().length > 0)
    {
        var v = $(this).prev("input").val();
        $(".board_content").prepend(NewTask.format(v));
        $(this).prev("input").val("");
        $(".add_list.active").removeClass("active");
        runDrag();
    }
})

$(document).on("click",".list_head .title",function() {
    $(this).attr("contenteditable",true).focus() 
})

$(document).on("click",".list_footer .add_card",function(){
    $(".list_footer.active .add_card").val("")
    $(".list_footer.active").removeClass("active");
    $(this).closest(".list_footer").addClass("active")
})

$(document).on("click",".list_footer .add_card_form .add_card_button",function(){
    var v = $(this).closest(".add_card_form").find("textarea").val();
    $(this).closest(".list_c").find(".list_body").append(NewCard.format(v));
    $(this).closest(".add_card_form").find("textarea").val("");
    $(this).closest(".list_footer.active").removeClass("active")
})

$(".board_content").on("click",function(e) {
    if((e.target.id != "add_list" && 
        $(e.target).parents("#add_list").length == 0) && 
        $(".add_list.active").length > 0){
        $(".add_list.active").removeClass("active");
    }

    if((Array.from(e.target.classList).indexOf('title') == -1 &&
        $(e.target).parents("#add_list").length == 0)){
        $(".list_head .title[contenteditable=true]").attr("contenteditable",false)
    }
})






var NewTask = '<div class="list">'+
'<div class="list_c">'+
'<div class="list_head">'+
'<div class="title" contenteditable="false">{0}</div>'+
'</div>'+
'<div class="list_body"></div>'+
'<div class="list_footer">'+
'<div class="add_card_form">'+
'<textarea></textarea>'+
'<button type="button" class="btn btn-success add_card_button">Add</button>'+
'</div>'+
'<div class="add_card">Add a card..</div>'+
'</div>'+
'</div>'+
'</div>';

var NewCard = '<div class="card">'+
'<div class="card_title">{0}</div>'+
'</div>';


String.prototype.format = String.prototype.f = function() {
    var s = this,
        i = arguments.length;

    while (i--) {
        s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
    }
    return s;
};

$(document).ready(function(e) {
    $(".list_footer .add_card_form textarea").keypress(function(event) {
      if(e.which == '13') {
        return false;
      }
    });
    runDrag();
});

function runDrag(){
    $( ".list" ).sortable({
        revert: true,
        items: ".list_c",
        connectWith: ".list",
         start: function( event, ui ) {
            $(".list").addClass("dragChild");
        },
        stop: function( event, ui ) {
            $(".list").removeClass("dragChild");
        }
        
      });
   /* $( ".list_c" ).draggable({ 
        connectToSortable: ".list",
        revert: "invalid",
        start: function( event, ui ) {
            $(".list").addClass("dragChild");
        },
        stop: function( event, ui ) {
            $(".list").removeClass("dragChild");
        }
    });*/
}
&#13;
.TM_board {
  background-color: #0079bf;
}
.TM_board .board_header {
  text-align: center;
  color: #7FB3D1;
  padding: 5px 8px;
  height: 30px;
  background-color: #0067A3;
}
.TM_board .board_header .board_header_left {
  float: left;
}
.TM_board .board_header .board_header_center {
  display: inline-block;
  font-weight: bold;
  font-style: italic;
}
.TM_board .board_header .board_header_right {
  float: right;
}
.TM_board .board_content {
  user-select: none;
  white-space: nowrap;
  margin-bottom: 10px;
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 10px;
  padding-right: 56px;
  min-height: 70vh;
  padding-top: 10px;
  display: flex;
}
.TM_board .board_content .list {
  width: 270px;
  margin: 0 5px;
  box-sizing: border-box;
  display: inline-block;
  vertical-align: top;
  white-space: nowrap;
}
.TM_board .board_content .list.dragChild {
  background: rgba(0, 0, 0, 0.12); 
}
.TM_board .board_content .list .list_c {
  background: #E2E4E6;
  border-radius: 3px;
  box-sizing: border-box;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  max-height: 100%;
  position: relative;
  white-space: normal;
  margin-bottom: 8px;
}
.TM_board .board_content .list .list_c .list_head {
  padding: 5px 8px;
  cursor: pointer;
}
.TM_board .board_content .list .list_c .list_body {
  padding: 5px 8px 0 8px;
}
.TM_board .board_content .list .list_c .list_body .card {
  background-color: #fff;
  border-bottom: 1px solid #ccc;
  border-radius: 3px;
  cursor: pointer;
  margin-bottom: 6px;
}
.TM_board .board_content .list .list_c .list_body .card .card_title {
  padding: 5px 8px;
  color: #444;
}
.TM_board .board_content .list .list_c .list_footer .add_card_form {
  display: none;
  padding: 5px 8px;
}
.TM_board .board_content .list .list_c .list_footer .add_card_form textarea {
  border: none;
  width: 100%;
  max-width: 100%;
  min-width: 100%;
  min-height: 50px;
  max-height: 230px;
  margin-top: 0px;
  margin-bottom: 0px;
  background-color: #fff;
  border-bottom: 1px solid #ccc;
  border-radius: 3px;
  overflow: hidden;
  word-wrap: break-word;
}
.TM_board .board_content .list .list_c .list_footer .add_card_form button {
  margin-top: 8px;
  padding: 5px 8px;
  min-width: 4rem;
  cursor: pointer;
}
.TM_board .board_content .list .list_c .list_footer .add_card {
  color: #838c91;
  display: block;
  -webkit-box-flex: 0;
  -webkit-flex: 0 0 auto;
  -ms-flex: 0 0 auto;
  flex: 0 0 auto;
  padding: 8px 10px;
  position: relative;
  text-decoration: none;
  user-select: none;
  cursor: pointer;
}
.TM_board .board_content .list .list_c .list_footer .add_card:hover {
  background-color: #CDD2D4;
  color: #4d4d4d;
  text-decoration: underline;
}
.TM_board .board_content .list .list_c .list_footer.active .add_card_form {
  display: block;
}
.TM_board .board_content .list .list_c .list_footer.active .add_card {
  display: none;
}
.TM_board .board_content .add_list {
  background: rgba(0, 0, 0, 0.12);
  cursor: pointer;
  color: #fff;
  height: 100%;
  min-height: 30px;
  padding: 4px;
  border-radius: 3px;
}
.TM_board .board_content .add_list .add_list_text {
  color: rgba(255, 255, 255, 0.7);
  line-height: 30px;
  padding-left: 5px;
  display: block;
}
.TM_board .board_content .add_list input {
  background: rgba(0, 0, 0, 0.05);
  border-color: #aaa;
  box-shadow: inset 0 1px 8px rgba(0, 0, 0, 0.15);
  display: none;
  margin: 0;
  width: 100%;
  box-sizing: border-box;
  -webkit-appearance: none;
  border: 1px solid #CDD2D4;
  border-radius: 3px;
  padding: 7px;
  color: #444;
}
.TM_board .board_content .add_list button {
  display: none;
  margin-top: 4px;
  clear: both;
}
.TM_board .board_content .add_list.active {
  background-color: #E2E4E6;
}
.TM_board .board_content .add_list.active .add_list_text {
  display: none;
}
.TM_board .board_content .add_list.active input {
  display: block;
}
.TM_board .board_content .add_list.active button {
  display: block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="TM_board"> 
    <div class="board_header">
        <div class="board_header_left">search</div>
        <div class="board_header_center">TM</div>
        <div class="board_header_right"></div>
    </div>
    <div class="board_content">
        <div class="list">
            <div class="list_c">
                <div class="list_head">
                    <div class="title" contenteditable="false">Test</div>
                </div>
                <div class="list_body">
                    <div class="card">
                        <div class="card_title">Title</div>
                    </div>
                </div>
                <div class="list_footer">
                    <div class="add_card_form">
                        <textarea></textarea>
                        <button type="button" class="btn btn-success add_card_button">Add</button>
                    </div>
                    <div class="add_card">Add a card..</div>
                </div>
            </div>
        </div>
        <div class="list">
            <div class="list_c">
                <div class="list_head">
                    <div class="title" contenteditable="false">Test</div>
                </div>
                <div class="list_body">
                    <div class="card">
                        <div class="card_title">Title</div>
                    </div>
                </div>
                <div class="list_footer">
                    <div class="add_card_form">
                        <textarea></textarea>
                        <button type="button" class="btn btn-success add_card_button">Add</button>
                    </div>
                    <div class="add_card">Add a card..</div>
                </div>
            </div>
        </div>
        <div id="add_list" class="list add_list">
            <div class="add_list_text">Add a list...</div>
            <input placeholder="Add a list...">
            <button type="button" class="btn btn-success">Save</button>
        </div>
    </div>
</div>
&#13;
&#13;
&#13;