Extremely annoying JavaScript arrayobject error - Stack Overflow

Basically, I am rewriting part of one of my web applications. I had a script that would collapse some o

Basically, I am rewriting part of one of my web applications. I had a script that would collapse some or all panels of the interface at once, and another to code them.

However, my old functions looked really ugly, and were annoying to type and not powerful enough:

function collapse_all()
{
    document.getElementById("panel_1").style.display="none"
    document.getElementById("panel_2").style.display="none"
    document.getElementById("panel_3").style.display="none"
}
function expand_all()
{
    document.getElementById("panel_1").style.display=""
    document.getElementById("panel_2").style.display=""
    document.getElementById("panel_3").style.display=""
}

Now I have this:

function panel() //first variable in argument is collapse or expand, all others are panels to act on
{
    var panels = panel.arguments
    alert(typeof panel.arguments)
    var mode = panels.shift() //here's my problem
    if(mode=="collapse") {mode="none"}
    if(mode=="expand") {mode=""}
    var items = panels.length
    for (i = 0;i < items;i++) {document.getElementById(panels[i]).style.display=mode}
}

panel("collapse","panel_1","panel_2","panel_3")

I have a problem though. Firebug tells me panels.shift() is not a function. With some Googling I managed to find out that panel.arguments isn't an array but an object, so I can't use array methods on it. I'm just really confused as to how I could either convert the object into an array or find another workaround, as I know next to nothing about JavaScript objects. Some example code would be highly appreciated.

Basically, I am rewriting part of one of my web applications. I had a script that would collapse some or all panels of the interface at once, and another to code them.

However, my old functions looked really ugly, and were annoying to type and not powerful enough:

function collapse_all()
{
    document.getElementById("panel_1").style.display="none"
    document.getElementById("panel_2").style.display="none"
    document.getElementById("panel_3").style.display="none"
}
function expand_all()
{
    document.getElementById("panel_1").style.display=""
    document.getElementById("panel_2").style.display=""
    document.getElementById("panel_3").style.display=""
}

Now I have this:

function panel() //first variable in argument is collapse or expand, all others are panels to act on
{
    var panels = panel.arguments
    alert(typeof panel.arguments)
    var mode = panels.shift() //here's my problem
    if(mode=="collapse") {mode="none"}
    if(mode=="expand") {mode=""}
    var items = panels.length
    for (i = 0;i < items;i++) {document.getElementById(panels[i]).style.display=mode}
}

panel("collapse","panel_1","panel_2","panel_3")

I have a problem though. Firebug tells me panels.shift() is not a function. With some Googling I managed to find out that panel.arguments isn't an array but an object, so I can't use array methods on it. I'm just really confused as to how I could either convert the object into an array or find another workaround, as I know next to nothing about JavaScript objects. Some example code would be highly appreciated.

Share Improve this question edited Nov 26, 2010 at 18:23 jwueller 31k5 gold badges67 silver badges70 bronze badges asked Nov 26, 2010 at 18:20 Nicky McCurdyNicky McCurdy 19.6k5 gold badges60 silver badges88 bronze badges 4
  • 3 You really should use ; at the end of your statements. Relying on JavaScripts auto-insertion is not what you want. Trust me. – jwueller Commented Nov 26, 2010 at 18:24
  • Thanks for the suggestion, but I'm not a professional web developer and I've read it's only a problem when you have multiple lines of code squeezed into one line (and I do use semicolons for that) and when the next line starts with (. I've never had problems with it. – Nicky McCurdy Commented Nov 26, 2010 at 18:35
  • Well, since you're "not a professional web developer," I would highly remend taking elusive's advice and use the semi-colons whether you think you need them or not. They improve readability and remove any ambiguity the piler might run into. – Cᴏʀʏ Commented Nov 26, 2010 at 18:39
  • Alright, I'll consider it, thanks. – Nicky McCurdy Commented Nov 26, 2010 at 18:42
Add a ment  | 

2 Answers 2

Reset to default 4

You can convert the arguments object into an array like this:

var argsArray = Array.prototype.slice.call(arguments);

What this does is use the slice method mon to all arrays via Array.prototype to create a genuine Array object from the array-like arguments. call() (a method of all functions) is used to call this slice method with a this value of arguments and no parameters, which has the effect of copying all of the elements of this into a new array. This may seem devious or hacky but it is actually designed into the language: see the note at the bottom of section 15.4.4.10 of the ECMAScript 3rd Edition spec.

Also, within a function you are provided the arguments object as a variable, so you don't need to access it as a property of the function object as you are doing. In your case, just use arguments rather than panel.arguments.

You could keep it much simpler (cleaned up your formatting, semi-colons, etc.):

function panel() 
{
    var panels = Array.prototype.slice.call(arguments);
    var displayMode = (panels[0] == "collapse" ? "none" : "");

    for (var i = 1; i < panels.length - 1; i++) 
    {
        document.getElementById(panels[i]).style.display = displayMode;
    }
}

Also, if you're rewriting your application, it might be a good time to consider using things like jQuery. You could assign each one of your panels a certain class name, and reduce your code to something like this:

function panel(hide)
{
    $('.className').css({ display: (hide ? 'none' : '') });
}

which you could use like so:

panel(true); // or
panel(false);

Or, because now it's so syntactically simple, you might as well just create two separate functions so that your code is straightforward and you know exactly what it's going to do from the function names alone:

function showPanels() {
    $('.className').css({ display: '' });
}

function hidePanels() {
    $('.className').css({ display: 'none' });
}

And finally, if you don't worry about doing it via CSS, you could really shorten your script to this, which can't be any clearer:

function showPanels() {
    $('.className').show();
}

function hidePanels() {
    $('.className').hide();
}

Cheers!

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745406341a4626330.html

相关推荐

  • Extremely annoying JavaScript arrayobject error - Stack Overflow

    Basically, I am rewriting part of one of my web applications. I had a script that would collapse some o

    13小时前
    40

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信