使用removeChild方法时出现错误

发布于 2024-08-09 16:51:48 字数 3013 浏览 11 评论 0原文

祝大家万圣节前夕快乐:)

我今天的问题是删除子对象时遇到的 DisplayObject 错误。我有代码将启动(addChild)视频容器和视频控件以及添加关闭按钮。 现在关闭按钮工作正常,一切正常,删除视频和控件,我能够再次选择另一个视频,但是当您第二次单击“关闭”时,我收到此错误:

ArgumentError:错误#2025:提供的 DisplayObject 必须是调用者的子级。 at flash.display::DisplayObjectContainer/removeChild()

因此,我将问题范围缩小到删除 videoContainer(保存视频对象)的位置

播放视频的代码:

public function videoSwitch(videoName):void
{
    nv.closeOut();
    nv.resetNav = false;

    if (!videoPlaying)
    {
        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer);
        container.addChild(videoContainer);
        container.addChild(vc);
        //container.addChildAt(videoContainer, 1);
        //container.addChildAt(vc, 2);
        videoPlaying = true;
        closeVideo();
    }

    else if (videoPlaying)
    {
        vc.clearSource();
        container.removeChild(videoContainer);
        container.removeChild(vc);

        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer);
        container.addChild(videoContainer);
        container.addChild(vc);
        //container.addChildAt(videoContainer, 1);
        //container.addChildAt(vc, 2);
        closeVideo();
    }
        trace("videoPlaying = "+videoPlaying+"\r");
}

关闭视频播放器代码: 您可以在我的评论中看到我尝试过的其他代码,但仍然收到错误。

function closeVideo():void 
{
    closeBtn.visible = true;
    closeBtn.x = 770;
    closeBtn.y = 20;
    closeBtn.buttonMode = true;
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
        vc.clearSource();
        container.removeChild(videoContainer);
        //container.removeChildAt(videoContainer, 1);
        container.removeChild(vc);
        videoPlaying = false;
        closeBtn.visible = false;
    }
}

现在我的电影工作正常,但我担心这个错误发生在后台(并显示在我的输出窗口中)最终会在其他地方引起问题:(

提前感谢您对这个问题的关注!:)


更新: 已修复!问题是我删除了kill VC侦听器,但忘记删除愚蠢的Close Button Mouse_Event侦听器:(

function addCloseButton():void 
{
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
        videoPlaying=false;
        vc.clearSource();
        removeContainerChildren(); // <- thx Joel!
        closeBtn.removeEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
        //^ Forgot this line - thx Jotham!
        container.removeChild(closeBtn);
    }
}

不知道此图是否有帮助,但是: 替代文字

Happy Pre-Halloween everyone :)

My issue today is a DisplayObject error I'm getting when remove a child object. I have code that will launch(addChild) a video container and video controls as well as add a close button. Now the close button works fine and everything, removing the video and controls and I'm able to choose another video again, but when you click close a 2nd time I get this error:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller. at flash.display::DisplayObjectContainer/removeChild()

So I've narrowed down the problem to where I remove the videoContainer (which holds the video object)

My code to play the videos:

public function videoSwitch(videoName):void
{
    nv.closeOut();
    nv.resetNav = false;

    if (!videoPlaying)
    {
        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer);
        container.addChild(videoContainer);
        container.addChild(vc);
        //container.addChildAt(videoContainer, 1);
        //container.addChildAt(vc, 2);
        videoPlaying = true;
        closeVideo();
    }

    else if (videoPlaying)
    {
        vc.clearSource();
        container.removeChild(videoContainer);
        container.removeChild(vc);

        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer);
        container.addChild(videoContainer);
        container.addChild(vc);
        //container.addChildAt(videoContainer, 1);
        //container.addChildAt(vc, 2);
        closeVideo();
    }
        trace("videoPlaying = "+videoPlaying+"\r");
}

The close out video player code:
You can see in my comments other code I tried, but still getting the error.

function closeVideo():void 
{
    closeBtn.visible = true;
    closeBtn.x = 770;
    closeBtn.y = 20;
    closeBtn.buttonMode = true;
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
        vc.clearSource();
        container.removeChild(videoContainer);
        //container.removeChildAt(videoContainer, 1);
        container.removeChild(vc);
        videoPlaying = false;
        closeBtn.visible = false;
    }
}

Now my movie works fine, but I'm worried that this error happening in the background (and showing up in my output window) will eventually cause a problem else where :(

Thanks in advance for any eyes on this one! :)


UPDATE:
FIXED! The problem was I remove the kill VC listener, but forgot to remove the stupid Close Button Mouse_Event listener :(

function addCloseButton():void 
{
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
        videoPlaying=false;
        vc.clearSource();
        removeContainerChildren(); // <- thx Joel!
        closeBtn.removeEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
        //^ Forgot this line - thx Jotham!
        container.removeChild(closeBtn);
    }
}

Don't know if this graphic helps but:
alt text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

〗斷ホ乔殘χμё〖 2024-08-16 16:51:49

这是避免该错误的一种方法:

    public function videoSwitch(videoName):void
    {
        nv.closeOut();
        nv.resetNav = false;

        if (videoPlaying)
        {
            vc.clearSource();
            removeContainerChildren()
        }

        addContainerChildren();
        closeVideo();
    }

    protected function removeContainerChildren():void
    {
        if(container.contains(videoContainer))
            container.removeChild(videoContainer);
        if(container.contains(vc))
        {
            container.removeChild(vc)   
            vc.removeEventListener("KillMovie", removePlayer)
        }
    }

    protected function addContainerChildren():void
    {
        videoPlaying = true;
        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer, false, 0, true); 
        container.addChild(videoContainer);
        container.addChild(vc);

        trace("videoPlaying = "+videoPlaying+"\r");
    }

here is one approach to avoid the error:

    public function videoSwitch(videoName):void
    {
        nv.closeOut();
        nv.resetNav = false;

        if (videoPlaying)
        {
            vc.clearSource();
            removeContainerChildren()
        }

        addContainerChildren();
        closeVideo();
    }

    protected function removeContainerChildren():void
    {
        if(container.contains(videoContainer))
            container.removeChild(videoContainer);
        if(container.contains(vc))
        {
            container.removeChild(vc)   
            vc.removeEventListener("KillMovie", removePlayer)
        }
    }

    protected function addContainerChildren():void
    {
        videoPlaying = true;
        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer, false, 0, true); 
        container.addChild(videoContainer);
        container.addChild(vc);

        trace("videoPlaying = "+videoPlaying+"\r");
    }
落花浅忆 2024-08-16 16:51:49

你移除过监听器吗?您很可能会多次触发它。

Do you ever remove the listener? You could well be having it fire multiple times.

迷乱花海 2024-08-16 16:51:49

试试这个:

 container.removeChild(container.videoContainer);
 container.removeChild(container.vc);

Try this:

 container.removeChild(container.videoContainer);
 container.removeChild(container.vc);
自此以后,行同陌路 2024-08-16 16:51:49

我有一种感觉,是其他一些代码导致了实际的问题。如果 videouPlaying 变量在其他地方发生了更改,从而导致您删除了尚不存在的内容,则此错误是有意义的。也许检查一下您是否没有在其他地方更改此变量。

I have a feeling that it is some other piece of code causing the actual problem. This error would make sense if the videuPlaying variable got changed somewhere else so that you were removing something that did not exist as yet. Maybe check that you are not changing this variable somewhere else.

听闻余生 2024-08-16 16:51:49

这是另一种非常巧妙的方法,通常不推荐,但它肯定会确保 videoContainer/vc 从它所在的 DisplayList 中删除。

private function removeFromStack(target:DisplayObject):void
{
    if (target.parent)
        target.parent.removeChild(target);
}

private function removeVideo():void
{
    removeFromStack(vc);
    removeFromStack(videoContainer);
    vc = videoContainer = null;
}

重申一下,这不是首选方法,但它不会出现错误。如果您开始收到“无法访问空对象引用”错误,那么正如前面的人所建议的那样,事件侦听器或其他一些依赖项仍然由有问题的 DisplayObject 持有。

希望这有帮助

This is another uber hacky way of doing this, not usually recommended but it will definitly insure that the videoContainer/vc is removed from whichever DisplayList it is on.

private function removeFromStack(target:DisplayObject):void
{
    if (target.parent)
        target.parent.removeChild(target);
}

private function removeVideo():void
{
    removeFromStack(vc);
    removeFromStack(videoContainer);
    vc = videoContainer = null;
}

Just to re-itterate, this is not the preferred way, but it will work without errors. If you start to get a "cannot access null object reference" error, then as previous people have suggested, event listeners or some other dependancies are still held by the DisplayObject's in question.

Hope this helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文