Jump to content

Javascript Object Reference Issue


Go to solution Solved by teynon,

Recommended Posts

I'm trying to build a simulator to let users train with. It's a good bit of code at the moment so hopefully this isn't too much for someone to look at right now. Basically, it's Windows in a web page.

 

http://tomsfreelance.com/windows_virtual_security/

 

Current Behavior: 

When opening two "Outlook" windows, changing the folder in the first window changes the second windows outlook.

 

Desired Behavior:

The folders should be specific to the window.

 

Steps to Reproduce:

Double click on "Outlook", doubleclick the title bar to take it out of full screen, then open another Outlook window. Next, click on a folder in the first window. Note that the folder changes in the second window.

 

I know the code below is a lot, so if anyone is willing to view the actual site posted above and try and debug what is happening instead I'd appreciate it very much. (Need a second set of eyes on this, because mine aren't finding it.)

 

The entire code can be seen at http://tomsfreelance.com/windows_virtual_security/js/desktop.js

 

The outlook object is created via a function call:

 

function outlook() {
    var params = {
        ...
        menu : ...,
        messages : ...,
        panes : ...,
        functions : {
            selectFolder : function(that, folder) {
                //that.aliases['Folder->' + folder].block.css("background-color", "#EEEEEE");
                //that.count = 0;
                //setInterval(function() { that.titleBarContainer.text(++that.count); }, 1000);
                console.log(that);
                var that = that;
                // Set title
                that.aliases['Current Folder'].block.text(folder);

                var subPanes = [];

                // Get messages
                if (that.options.params.messages[folder]) {
                    for (var i in that.options.params.messages[folder]) {
                        // Rebuild sub pane object.
                        subPanes.push([{
                            css : {

                            },
                            "class" : "outlook_preview",
                            text : that.options.params.messages[folder][i].Subject,
                            resizable : false,
                            height : "22px" 
                        }]);
                    }
                }

                that.aliases['Folder Messages'].block.empty();
                var parentPane = $('<table class="child_pane"></table>').appendTo(that.aliases['Folder Messages'].block);
                that.buildPanes(parentPane, subPanes);
                
            }

            ..........

            }
        }
    };
    
    return params;
}

 

And new windows are spawned via 

function create_window(parameters) {
    var param = parameters;
    var window = $('<div></div>').prependTo('body');
    window.window({
        params : param
    });
    $('#start_menu').hide();
}

 

The random variable reassignments is me trying to break the reference since I have no clue why / where it is happening... (var param = parameters)

 

The "selectFolder" function is called from the Window jQuery widget I created:


$(function( $, undefined ) {
    $.widget("ui.window", $.ui.mouse, {
        self : this,
        ...,
        _create : function() {
            console.log(this);
            this.createWindow();
            var that = this;
            $('html').click(function() {
                $('.menu').hide();
            });
        },

        createWindow : function() {
            ...
            // Content panes
            this.buildPanes(this.panesBlock, this.options.params.panes);
            this.scalePanes();
            ...
        },

        buildPanes : function(paneBlock, panes) {
            var pane = null;
            var that = this;
            for (var i in panes) {
                this.paneRows++;
                var rowPane = $('<tr></tr>').appendTo(paneBlock);
                for (var h in panes[i]) {
                    panes[i][h].block = $('<td class="pane"></td>').appendTo(rowPane);
                    ...

                    if (pane.subPanes) {
                        var parentPane = $('<table class="child_pane"></table>').appendTo(panes[i][h].block);
                        that.buildPanes(parentPane, pane.subPanes);
                    }

                    if (pane.alias) {
                        that.aliases[pane.alias] = pane;
                    }

                    ...

                    if (pane.onClick) {
                        that.onClick(that, pane);
                    }

                    if (pane.onLoad) {
                        that.onLoad(that, pane);
                    }
                }
            }
        },

        onClick : function(that, pane) {
            pane.block.on("click", function() {
                pane.onClick(that, pane.id);
            });
        },

        onLoad : function(that, pane) {
            var pane = pane;
            var that = that;
            pane.onLoad(that, pane.id);
        },

        scalePanes : function(addHeight) {
            var pane = null;
            var contentHeight = this.element.outerHeight() - (this.titleBar.outerHeight() + this.menuBar.outerHeight() + this.statusBar.outerHeight());
            if (this.element.hasClass("windowed")) contentHeight -= 4;
            var contentWidth = this.contentBox.outerWidth();
            if (addHeight) contentHeight += addHeight;
            console.log(contentHeight);
            this.panesBlock.outerHeight(contentHeight);
        /*
        for (var i in this.options.params.panes) {
            pane = this.options.params.panes[i];
            if (pane.height) {
                pane.block.outerHeight(contentHeight * (pane.height / 100));
            }
            if (pane.width) {
                pane.block.outerWidth(contentWidth * (pane.width / 100));
            }
        }
        */
        },

        closeWindow : function() {
            this.element.remove();
        }
    });
});

 

 

 

Link to comment
https://forums.phpfreaks.com/topic/275678-javascript-object-reference-issue/
Share on other sites

Objects, Arrays, Dates are passed by reference in JavaScript, so even if you assign it to a new variable, it will still point to the original object. Usually, you would loop through the object properties to clone it. I think your problem is with the HTML build up rather than the objects. From a quick look, I don't see a unique id for each window and when you reference to html element by class name, the first element is updated. Each window should have a unique id and all changes or updates should use that reference into account.

The windows are created through a jquery widget. They don't need ID's because the widget holds onto that element. The elements aren't being referenced by class name either in this case. I tried appending instead of prepending and no change was noted, so it's not the order of the elements in the page, but which one was created last. As for the object reference. I'm not really sure why it's being referenced as the function outlook() returns a new object each time. You can do everything with each window individually except click that object. Some other weird things happen too... Like if I reference the title object of it, it goes to the right window.

Edited by teynon

Yes, your objects are not reference and that's why I mentioned the error is most likely in the html build up. Your onclick event might referencing the wrong object. Try to make a different alias for each window or try to make a different outlook window called outlook2 and see if that makes any difference.

  • Solution

I havent used jQuery widgets alot, but the problem was fixed by moving the "aliases" field into the options object.

$.widget("ui.window", $.ui.mouse, {
            ...
            aliases : {},
            options : {
                params : {
                    title : "My Window",
                    icon : false,
                    maximized : true,
                    defaultWidth : 500,
                    defaultHeight : 400,
                    defaultX : 10,
                    defaultY : 10,
                    panes : {},
                    paneRows : 0,
                    css : {},
                    menu : { 
                    }
                },
                functions : {
                    
                }
            },

 

Became

$.widget("ui.window", $.ui.mouse, {
            ...
            options : {
                aliases : {},
                params : {
                    title : "My Window",
                    icon : false,
                    maximized : true,
                    defaultWidth : 500,
                    defaultHeight : 400,
                    defaultX : 10,
                    defaultY : 10,
                    panes : {},
                    paneRows : 0,
                    css : {},
                    menu : { 
                    }
                },
                functions : {
                    
                }
            },

 

I'm guessing by having that value as a root widget variable that it's static somehow? I'm not really sure why.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.