Чрезвычайно раздражающая ошибка массива / объекта JavaScript - PullRequest
2 голосов
/ 26 ноября 2010

По сути, я переписываю часть одного из моих веб-приложений.У меня был сценарий, который разрушал бы некоторые или все панели интерфейса одновременно, а другой для их кодирования.

Однако мои старые функции выглядели очень некрасиво и раздражали при наборе текста и не были достаточно мощными:*

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=""
}

Теперь у меня есть это:

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")

У меня есть проблема.Firebug говорит мне, что Panel.shift () не является функцией.С помощью некоторого поиска в Google мне удалось выяснить, что panel.arguments - это не массив, а объект, поэтому я не могу использовать для него методы массива.Я просто очень озадачен тем, как можно преобразовать объект в массив или найти другой обходной путь, поскольку я почти ничего не знаю об объектах JavaScript.Некоторые примеры кода будут высоко оценены.

Ответы [ 2 ]

4 голосов
/ 26 ноября 2010

Вы можете сделать это намного проще (очистить форматирование, точки с запятой и т. Д.):

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;
    }
}

Кроме того, если вы переписываете свое приложение, самое время подумать об использовании таких вещей как jQuery . Вы можете назначить каждой из ваших панелей определенное имя класса и уменьшить свой код до чего-то вроде этого:

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

который вы можете использовать так:

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

Или , потому что теперь это так синтаксически просто, вы можете просто создать две отдельные функции, чтобы ваш код был простым и вы точно знали, что он собирается делать, только по именам функций:

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

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

И, наконец, если вы не беспокоитесь о том, чтобы сделать это с помощью CSS, вы можете действительно сократить свой сценарий до этого, что не может быть более понятным:

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

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

Ура!

4 голосов
/ 26 ноября 2010

Вы можете преобразовать объект аргументов в массив следующим образом:

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

Для этого используется метод slice, общий для всех массивов через Array.prototype, для создания подлинного Array объекта из массива, подобного arguments. call() (метод всех функций) используется для вызова этого slice метода со значением this arguments и без параметров, что приводит к копированию всех элементов this в новый массив. Это может показаться хитрым или хакерским, но на самом деле оно разработано на языке: см. Примечание внизу раздела 15.4.4.10 спецификации ECMAScript 3rd Edition .

Кроме того, внутри функции вам предоставляется объект arguments в качестве переменной, поэтому вам не нужно обращаться к нему как к свойству объекта функции, как вы это делаете. В вашем случае просто используйте arguments вместо panel.arguments.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...