jQuery UI:无法读取未定义

时间:2015-09-16 15:32:28

标签: javascript jquery jquery-ui

当我拖动可排序的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);
      });

4 个答案:

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