【问题标题】:Draggable element bounce around sometimes可拖动元素有时会反弹
【发布时间】:2018-04-13 14:59:11
【问题描述】:

我在下面创建了这个 sn-p,并从 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>

【问题讨论】:

  • “弹跳”是什么意思?我在整页中看到了您的代码,但没有发现任何问题。

标签: jquery jquery-ui draggable


【解决方案1】:

很难准确指出,因为 sortable 和 draggable 的拖动发生了很多事情,并且您将两者混合在一起,但据我所见,我认为问题来自 draggable 中的行为connectToSortablesortable 冲突。连接到 sortabledraggable 将根据您拖动它的位置激活和停用 sortable。所以它可以触发一个可排序的停止。 但是你有 sortabledraggable 的元素,这意味着你可以从 draggable connectTosortable 触发停止在同一元素的可排序上。但是您的元素也是可排序的,因此它会保留在序列中的其他位置。所以你最终会出现冲突的行为。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多