【问题标题】:jQuery UI: cannot read property left of undefinedjQuery UI:无法读取未定义的属性
【发布时间】:2015-09-16 15:32:27
【问题描述】:

当我拖动可排序的 jQuery UI 元素时,我不断收到错误 cannot read property left of undefined。一切都按我的预期工作,但我不断收到错误并希望解决导致它的问题。

目的是拥有一个具有多选功能的可排序列表,这样您就不必一次拖动一个元素。就像我说的那样,我按照this fiddle上的代码进行操作

奇怪的是,当我创建一个包含此问题的代码笔时,我不再在控制台中收到错误消息。我试过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);
      });

【问题讨论】:

  • 这似乎可能是您的一个 jQuery 选择器中的错字。或者喜欢忘记添加“。”到类名选择器。但是通过给出的例子,我不相信你会得到一个有效的答案。
  • 什么js文件报错? jquery-ui?
  • @Zealander 它是 jQuery-UI,特别是 refreshPositions 函数 item.left = p.left;
  • @Joe,你确定你使用的是最新的 jquery-ui 吗?我发现了与您的问题类似的各种错误报告。这些错误已在 1.9.1 中修复:
  • @Joe,一切都很好。祝你好运!

标签: javascript jquery jquery-ui


【解决方案1】:

什么时候加载js文件? 如果你在你处理的 dom 元素之上加载 js 文件, 您的 javascript 代码 $( selector ) 将无法正常工作。

也许Codepen和fiddle在dom元素之后加载你的js文件,所以不会出现错误。

检查您的 html 文件的 javascript 加载点。

很多人喜欢关注。

<html>
    <head>
    </head>

    <body>

        <!-- your dom elements -->
        <script src="yourJavascript.js"></script>
    </body>

</html>    

如果你在&lt;/body&gt;之前加载js文件,你可以在yourJavascript.js中使用你的dom元素

【讨论】:

  • 我将所有内容加载到头部并将代码包装在$(document).ready()中,脚本的顺序是jquery, jquery-ui, my-js
  • 您的代码在我的服务器上运行良好。检查我的 html 文件 codepen.io/anon/pen/RWawmX 在我的 html 中,tt.js 是您的 javascript 部分。我在 chrome browser v45, osX yesemite 中进行了测试。
【解决方案2】:

我遇到了同样的错误,尽管在一些不同的情况下(我手动将项目添加到可排序列表中)。我的问题对时间和环境选项也非常敏感,有时运行正常,有时运行不正常。

This stack overflow answer 帮助我走上了正轨(我需要先克隆对象,然后再将其添加到列表中)

【讨论】:

    【解决方案3】:

    请尝试在 sortable 中添加容器。

    默认值:假 定义可排序项在拖动时被限制到的边界框。

    注意:为包含指定的元素必须具有计算的宽度和高度(尽管它不需要明确)。例如,如果您有 float:left 可排序的子项并指定 contains:"parent" 一定要在可排序/父容器上也有 float:left ,否则它的 height:0 会导致未定义的行为。

    $( ".selector" ).sortable({ 收容:“父母” });

    【讨论】:

      【解决方案4】:

      你有没有试过用 jQuery 封装整个东西,这会延迟执行直到 DOMReady。

      $(function () { /*...YOUR CODE HERE...*/ });
      

      【讨论】:

      • 是的,整个脚本都包含在$(document).ready(function()
      • @Yamaha32088 我无法重现该问题。将您的代码形式codepen复制到本地文件,添加jQuery和jQueryUI,如果我像你一样包装它,它会很顺利。正如 ssohjiro 所问,需要完整的来源。
      • 你可以回到codepen看到整个代码codepen.io/anon/pen/vNGYLa
      • @Yamaha32088 是的,但是 codepen 示例没有产生问题,正如你上面提到的 :)
      猜你喜欢
      • 2018-01-03
      • 2012-08-10
      • 2017-04-20
      • 2021-11-26
      • 1970-01-01
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      相关资源
      最近更新 更多