javascript 未捕获的类型错误:无法读取未定义的属性“位置”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22715621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:39:00  来源:igfitidea点击:

Uncaught TypeError: Cannot read property 'position' of undefined

javascriptjqueryhtmljquery-ui

提问by Venkateshwaran Selvaraj

I am working on draggable items. I am trying to store the final position of the draggable div once it is stopped from being dragged.It was working fine when I had the following javascript code.

我正在处理可拖动的项目。一旦停止拖动,我试图存储可拖动 div 的最终位置。当我有以下 javascript 代码时,它工作正常。

function make_draggable(elements)
 {
  /* Elements is a jquery object: */
  elements.draggable({
    containment: 'parent',
    start: function (e, ui) {
      ui.helper.css('z-index', ++zIndex);
    },
    stop: function (e, ui) {
      /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
      $.get('ajax/update_position.php', {
        x: ui.position.left,
        y: ui.position.top,
        z: zIndex,
        id: parseInt(ui.helper.find('span.data').html())
      });
    }
  });
}

I did not want the database to be updated everytime the user stops dragging the div. So I wanted to add a confirm button(which appears when the users stops dragging) to make the AJAX call. So I tried the following code

我不希望每次用户停止拖动 div 时更新数据库。所以我想添加一个确认按钮(当用户停止拖动时出现)来进行 AJAX 调用。所以我尝试了以下代码

var $button = $("#button");

function make_draggable(elements) {
    /* Elements is a jquery object: */
    elements.draggable({
        containment: 'parent',
        start: function (e, ui) {
            ui.helper.css('z-index', ++zIndex);
            $("#button").animate({
                opacity: 0
            }, 1000);
        },
        stop: function (e, ui) {
            /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
            $('#chatAudio')[0].play();
            $("#button").animate({
                opacity: 1
            }, 1000);
            /*  $.get('ajax/update_position.php',{x : ui.position.left,y: ui.position.top,z: zIndex,id:parseInt(ui.helper.find('span.data').html())});*/
        } /*stop is ending */
    }); /* element.draggable is ending */

}

 function myFunction() {
    alert(1);
    /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
    $.get('ajax/update_position.php', {
        x: ui.position.left,
        y: ui.position.top,
        z: zIndex,
        id: parseInt(ui.helper.find('span.data').html())
    });

}

But when I click the confirm button, I am seeing the Uncaught ReferenceError: ui is not definederror on my javascript console.

但是当我点击确认按钮时,我Uncaught ReferenceError: ui is not defined在我的 javascript 控制台上看到了错误。

I thought that uiwas not defined. So I added (e,ui)as shown below

我认为这ui没有定义。所以我添加(e,ui)如下所示

function myFunction(e,ui) {
        alert(1);
        /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
        $.get('ajax/update_position.php', {
            x: ui.position.left,
            y: ui.position.top,
            z: zIndex,
            id: parseInt(ui.helper.find('span.data').html())
        });

    }

But now I am getting Uncaught TypeError: Cannot read property 'position' of undefined

但现在我得到 Uncaught TypeError: Cannot read property 'position' of undefined

Here is my website

这是我的网站

回答by Montri M

This is all about passing parameter and expose objects. You can't access the ui parameter in your "myFunction" because, if I guess right, it was invoked by the "click" event of the "#button" object. The click event have no idea about the "ui" helper object, so it doesn't get passed to your function.

这都是关于传递参数和公开对象。您无法访问“myFunction”中的 ui 参数,因为如果我猜对了,它是由“#button”对象的“click”事件调用的。click 事件不知道“ui”帮助器对象,因此它不会传递给您的函数。

So, basically, you have many draggable element, but only one confirm button. The easiest way to fix the problem you had is, like Mohit suggested, bind the data you need with the element through its 'data' function. However, don't bind the 'ui' helper object itself, just bind the data that you need.

所以,基本上,你有很多可拖动元素,但只有一个确认按钮。解决您遇到的问题的最简单方法是,就像 Mohit 建议的那样,通过其“数据”函数将您需要的数据与元素绑定。但是,不要绑定“ui”助手对象本身,只需绑定您需要的数据。

In short, try this.

简而言之,试试这个。

var $button = $("#button");

function make_draggable(elements) {
    /* Elements is a jquery object: */
    elements.draggable({
        containment: 'parent',
        start: function (e, ui) {
            ui.helper.css('z-index', ++zIndex);
            $("#button").animate({
                opacity: 0
            }, 1000);
        },
        stop: function (e, ui) {

            // All those fancy objects are accessible here, so we get the snapshot of their values, as simple non-cyclic javascript object, and store it with data function.
            $("#button").data('position', {
                x: ui.position.left,
                y: ui.position.top,
                z: zIndex,
                id: parseInt(ui.helper.find('span.data').html())
            });

            $('#chatAudio')[0].play();
            $("#button").animate({
                opacity: 1
            }, 1000);

        } /*stop is ending */
    }); /* element.draggable is ending */
}

function myFunction() {
    alert(1);
    /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
    $.get('ajax/update_position.php', $("#button").data('position'));
}

回答by Mohit Pandey

You can use dataatribute property to pass uivalue to button.

您可以使用data属性属性将ui值传递给按钮。

Try this:

试试这个:

var $button = $("#button");

function make_draggable(elements) {
    /* Elements is a jquery object: */
    elements.draggable({
        containment: 'parent',
        start: function (e, ui) {
            ui.helper.css('z-index', ++zIndex);
            $("#button").animate({
                opacity: 0
            }, 1000);
        },
        stop: function (e, ui) {
            /* adding ui to button data attribute */
            $("#button").data('ui', JSON.stringify(ui));
            /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
            $('#chatAudio')[0].play();
            $("#button").animate({
                opacity: 1
            }, 1000);
            /*  $.get('ajax/update_position.php',{x : ui.position.left,y: ui.position.top,z: zIndex,id:parseInt(ui.helper.find('span.data').html())});*/
        } /*stop is ending */
    }); /* element.draggable is ending */

}

function myFunction() {
    /* get data attribute for ui value */
    var ui = JSON.parse($("#button").data('ui'));
    /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
    $.get('ajax/update_position.php', {
        x: ui.position.left,
        y: ui.position.top,
        z: zIndex,
        id: parseInt(ui.helper.find('span.data').html())
    });
}

回答by stevethecollier

you are not setting ui to anything in your stop function, so when you try to send the ui.position, there is nothing to send.

您没有在停止函数中将 ui 设置为任何内容,因此当您尝试发送 ui.position 时,没有任何内容可发送。

you can fix this by setting ui in the stop function and then using it in your get.

你可以通过在 stop 函数中设置 ui 然后在你的 get 中使用它来解决这个问题。

function make_draggable(elements) {
    /* Elements is a jquery object: */
    elements.draggable({
        containment: 'parent',
        start: function (e, ui) {
            ui.helper.css('z-index', ++zIndex);
            $("#button").animate({
                opacity: 0
            }, 1000);
        },
        stop: function (e, ui) {

            window.ui = ui //----------------ADD THIS LINE TO SET IT---------------------------

            /* Sending the z-index and positon of the note to update_position.php via AJAX GET: */
            $('#chatAudio')[0].play();
            $("#button").animate({
                opacity: 1
            }, 1000);
            /*  $.get('ajax/update_position.php',{x : ui.position.left,y: ui.position.top,z: zIndex,id:parseInt(ui.helper.find('span.data').html())});*/
        } /*stop is ending */
    }); /* element.draggable is ending */

}

 function myFunction(e, ui) {
    alert(1);

    ui = window.ui   //------------AND SET IT HERE SO IT IS NOT UNDEFINED IN THE GET-------

    $.get('ajax/update_position.php', {
        x: ui.position.left,
        y: ui.position.top,
        z: zIndex,
        id: parseInt(ui.helper.find('span.data').html())
    });
}

回答by Lee Gary

Shouldn't you be using droppabletogether with draggable? Under the documentationfor droppable, you can get ui.position too

您不应该将droppable与draggable 一起使用吗?在droppable的文档下,您也可以获得 ui.position

回答by Buzinas

Well, it seems you were updating each div at a time, when you were calling the PHP inside your stop function. And it seems you want to update all your divs at once now, after clicking the confirm button.

好吧,当您在 stop 函数中调用 PHP 时,您似乎一次更新了每个 div。在单击确认按钮后,您似乎想立即更新所有 div。

There are two ways to solve your problem, the first is to change your PHP to receive all the divs in a parameter (an Object with all those divs, for example), and the second is to loop your PHP request, passing all divs, one by one.

有两种方法可以解决您的问题,第一种是更改 PHP 以接收参数中的所有 div(例如,具有所有这些 div 的对象),第二种是循环您的 PHP 请求,传递所有 div,逐个。

You change your make_draggable function to:

您将 make_draggable 函数更改为:

function make_draggable(elements) {
    window.myDragglableDivs = {}; // add an object to keep your data
    elements.draggable({
        containment: 'parent',
        start: function (e, ui) {
            ui.helper.css('z-index', ++zIndex);
            $("#button").animate({
                opacity: 0
            }, 1000);
        },
        stop: function (e, ui) {
            // add/update the div positions in your object:
            var divID = ui.helper.find('span.data').html();
            window.myDragglableDivs[divID] = {
                x: ui.position.left,
                y: ui.position.top,
                z: zIndex,
                id: parseInt(divID)
            };

            $('#chatAudio')[0].play();
            $("#button").animate({
                opacity: 1
            }, 1000);
        }
    });
}

My first solution is sending all divs at once (you must change your PHP to receive them in this case):

我的第一个解决方案是一次发送所有 div(在这种情况下,您必须更改 PHP 才能接收它们):

function myFunction() {
    $.get('ajax/update_position.php', window.myDraggableDivs);
}

Or, my second solution, you won't need to make any change in your PHP:

或者,我的第二个解决方案,您不需要对 PHP 进行任何更改:

function myFunction() {
    for (var key in window.myDraggableDivs) {
        $.get('ajax/update_position.php', window.myDraggableDivs[key]);
    }
}