当我拖动可排序的jQuery UI元素时,我不断收到错误cannot read property left of undefined
。一切都像我想要的那样工作,但我不断得到错误,并希望解决导致它的问题。
目的是拥有一个具有多选功能的可排序列表,这样您就不必一次拖动一个元素。就像我说的那样有效,我遵循了this fiddle
上的代码奇怪的是,当我创建一个包含此问题的codepen时,我不再在控制台中收到错误消息。我试过codepen和jsfiddle。我意识到如果你不能自己看错,但希望有人能够发现错误或给我建议检查什么,可能很难排除故障。
以下是my codepen和一些代码:
修改 由于评论,问题已得到解决。我需要更改我的jQuery版本。
HTML:
<div id="wrapper">
<ul id="elePool" class="sortme">
<li class="draggable element" data-element="1">sku</li>
<li class="draggable element" data-element="2">type</li>
<li class="draggable element" data-element="3">attribute_set</li>
</ul>
<ul id="eleGroups">
<li class="sortme group attribute required" id="group-weight"></li>
<li class="sortme group attribute required" id="group-visibility"></li>
<li class="sortme group attribute" id="group-status"></li>
<li class="sortme group attribute" id="group-short_description"></li>
</ul>
<ul class='custom-menu' id="elementMenu">
<li class='visibleElement' data-action="duplicate">Duplicate</li>
<li class='visibleElement' data-action="delete">Delete</li>
<li class='visibleElement' data-action="copy">Copy</li>
<li class='visibleElement' data-action="cut">Cut</li>
</ul>
<ul class='custom-menu' id='attributeMenu'>
<li class='visibleAttribute' data-action="paste">Paste</li>
</ul>
</div>
CSS:
ul {
padding: 0;
}
#elePool,
#eleGroups {
float:left;
margin-right:30px;
width:300px;
border:1px solid #808080;
min-height:25px;
}
#eleGroups {
min-height:300px;
}
li.selected {
background-color: #DAA520 !important;
}
#eleGroups .group li,
#elePool li {
border:1px solid #808080;
background-color:#E0FFFF;
line-height:25px;
cursor: -webkit-grab;
cursor: move;
text-indent:15px;
list-style: none;
}
#eleGroups > li {
position:relative;
box-sizing: border-box;
min-height:100px;
border:1px dashed #D3D3D3;
padding-top: 20px;
list-style: none;
}
#eleGroups > li:after {
position:absolute;
top:1px;
left:2px;
font-size:16px;
text-transform: uppercase;
color: #808080;
}
li.group {
float: left;
width: 33.3%;
}
ul#eleGroups {
width:50%;
}
.required {
background-color:#FFEBE8;
}
.complete {
background-color:#EEFFAA !important;
}
/* The whole thing */
.custom-menu {
display: none;
z-index: 1000;
position: absolute;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 5px;
padding: 0;
}
/* Each of the items in the list */
.custom-menu li {
padding: 8px 12px;
cursor: pointer;
list-style-type: none;
}
.custom-menu li:hover {
background-color: #DEF;
}
#group-weight:after {content: 'weight'}
#group-visibility:after {content: 'visibility'}
#group-status:after {content: 'status'}
#group-short_description:after {content: 'short_description'}
JS:
function addElementMenu() {
$('.element').on("contextmenu", function (e) {
// Avoid the real one
e.preventDefault();
e.stopPropagation();
//set clicked item
clicked = $(this);
parent = $(this).parent().attr('id');
// Show contextmenu
$("#elementMenu").finish().show().css({
top: event.pageY + "px",
left: event.pageX + "px",
display: 'block'
});
});
}
function addAttributeMenu() {
$('.attribute').on("contextmenu", function (e) {
// Avoid the real one
e.preventDefault();
e.stopPropagation();
//set clicked item
clicked = $(this);
parent = $(this).parent().attr('id');
// Show contextmenu
$("#attributeMenu").finish().show().css({
top: event.pageY + "px",
left: event.pageX + "px",
display: 'block'
});
});
}
$('.sortme').on('click', 'li', function(e) {
if(e.ctrlKey || e.metaKey) {
$(this).toggleClass("selected");
} else {
$(this).addClass("selected").siblings().removeClass('selected');
}
}).sortable({
connectWith: ".sortme",
delay: 150,
revert: 0,
helper: function (e, item) {
var helper = $('<li/>');
if(!item.hasClass('selected')) {
item.addClass('selected').siblings().removeClass('selected');
}
var elements = item.parent().children('.selected').clone();
item.data('multidrag', elements).siblings('.selected').remove();
return helper.append(elements);
},
stop: function(e, info) {
info.item.after(info.item.data('multidrag')).remove();
},
update: function(event, ui) {
checkRequired(this);
}
});
function checkRequired(elementToCheck) {
if($(elementToCheck).hasClass('required')) {
if($(elementToCheck).is(':empty')) {
$(elementToCheck).removeClass('complete');
} else {
$(elementToCheck).addClass('complete');
}
}
}
//add the context menus
addElementMenu();
addAttributeMenu();
// If the document is clicked somewhere
$(document).bind("mousedown", function (e) {
// If the clicked element is not the menu
if (!$(e.target).parents(".custom-menu").length > 0) {
// Hide it
$(".custom-menu").hide(100);
}
});
// If the menu element is clicked
$(".custom-menu li").click(function(){
// This is the triggered action name
switch($(this).attr("data-action")) {
// A case for each action. Your actions here
case "duplicate": duplicateItem(clicked); break;
case "delete": deleteItem(clicked); break;
case "copy": copyItem(clicked); break;
case "cut": cutItem(clicked); break;
case "paste": pasteItem(); break;
}
// Hide it AFTER the action was triggered
$(".custom-menu").hide(100);
});
答案 0 :(得分:0)
加载js文件?
如果你在你处理的dom元素上面加载js文件,
您的JavaScript代码$( selector )
将无法正常运行。
也许Codepen和小提琴在dom元素之后加载你的js文件,所以不会发生错误。
检查你的html文件的javascript加载点。
很多人喜欢跟随。
<html>
<head>
</head>
<body>
<!-- your dom elements -->
<script src="yourJavascript.js"></script>
</body>
</html>
如果您在</body>
之前加载js文件,则可以使用yourJavascript.js
中的dom元素
答案 1 :(得分:0)
我遇到了同样的错误,尽管情况有所不同(我手动将项目添加到可排序列表中)。我的问题也对时间和环境选择非常敏感,有时它运行正常,有时候没有。
This stack overflow answer帮助我走上了正确的轨道(在将其添加到列表之前我需要克隆该对象)
答案 2 :(得分:0)
请尝试在sortable中添加包含。
默认值:false 定义一个边界框,可拖动时可对可排序项目进行约束。
注意:为包含指定的元素必须具有计算的宽度和高度(尽管它不必是显式的)。例如,如果你有float:left sortable children并指定包含:&#34; parent&#34;一定要有float:也可以在sortable / parent容器上,或者它的高度为:0,导致未定义的行为。
$(&#34; .selector&#34;).sortable({ 遏制:&#34;父母&#34; }); 强>
答案 3 :(得分:-1)
你是否尝试过在jQuery中包装整个内容,这会将执行延迟到DOMReady。
$(function () { /*...YOUR CODE HERE...*/ });