2010-11-26 2 views
2

기본적으로 내 웹 응용 프로그램 중 하나의 일부를 다시 작성하고 있습니다. 한 번에 인터페이스의 일부 또는 모든 패널을 접을 수있는 스크립트와이를 코드화하는 스크립트가있었습니다. 매우 귀찮은 JavaScript 배열/객체 오류

그러나, 내 옛 기능은 정말 추한 모습, 그리고 입력하는 성가신 충분하지 강력했다 :

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

그래도 문제가 :

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

지금 나는이 있습니다. Firebug는 panels.shift()가 함수가 아니라고 말합니다. 일부 인터넷 검색을 통해 나는 panel.arguments가 배열이 아니라 객체라는 것을 알아 냈습니다. 따라서 배열 메소드를 사용할 수 없습니다. 나는 JavaScript 객체에 관해서는 알지 못했지만 객체를 배열로 변환하거나 다른 해결 방법을 찾는 방법에 대해 혼란스러워합니다. 일부 예제 코드는 매우 높이 평가 될 것입니다.

+3

진술이 끝나면 실제로는;를 사용해야합니다.JavaScripts 자동 삽입에 의존하는 것은 당신이 원하는 것이 아닙니다. 날 믿어. – jwueller

+0

제안 해 주셔서 감사합니다. 그러나 저는 전문적인 웹 개발자가 아니며 여러 줄의 코드를 한 줄로 짜 넣었을 때 (그리고 세미콜론을 사용합니다) 다음 줄이 시작될 때만 문제가 있다는 것을 읽었습니다 –

+0

글쎄, 당신은 "전문적인 웹 개발자가 아니기 때문에"나는 당신이 필요하다고 생각하든 그렇지 않든간에, 애매한 조언을 듣고 세미 콜론을 사용할 것을 강력히 권고한다. 가독성을 높이고 컴파일러가 모호한 점을 제거하십시오. –

답변

4

당신은이 같은 배열에 인수 개체를 변환 할 수 있습니다

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

이것이하는 일은에서 정품 Array 개체를 만들 수 Array.prototype를 통해 모든 배열에 공통 slice 방법을 사용하는 것입니다 배열과 같은 arguments. call() (모든 함수의 메서드)은 this 값이 arguments이고 매개 변수가없는 slice 메서드를 호출하는 데 사용되며 모든 요소를 ​​this의 새 배열에 복사하는 효과가 있습니다. 이는 우스꽝스럽고 해커처럼 보일지 모르지만 실제로는 언어로 설계되었습니다. section 15.4.4.10 of the ECMAScript 3rd Edition spec의 하단에있는 참고 사항을 참조하십시오.

또한 함수 내에서 arguments 개체를 변수로 제공하므로 함수 개체의 속성으로 액세스 할 필요가 없습니다. 귀하의 경우 panel.arguments 대신 arguments을 사용하십시오.

당신은 훨씬 더 간단이 (당신의 서식, 세미콜론 등 청소)를 유지할 수
+0

고맙습니다,이 작품은 훌륭합니다. 다른 답변도 유용하지만,이 질문은 첫 번째 답변이기 때문에 선택하겠습니다. 정확히 내가 필요로하는 것. –

+0

'Array.prototype.slice.call()'이 실제로 무엇을하는지 더 자세히 설명 할 수 있습니까? –

+1

@Derek : 설명이 추가되었습니다. –

4

: 당신이 응용 프로그램을 다시 작성하는 경우

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과 같은 것. 지금이기 때문에,

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

또는을 : 당신은 당신의 패널의 각각에게 특정 클래스의 이름을 지정하고,이 같은 뭔가 코드를 줄일 수 :

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

당신과 같이 사용할 수 있습니다 문법적으로 단순하기 때문에 두 개의 개별 함수를 만들어 코드가 간단하고 함수 이름만으로 수행 할 작업을 정확히 알 수 있습니다.

당신이 CSS를 통해 그 일을 걱정하지 않는 경우 0

그리고 마지막으로, 당신은 정말 어떤 명확하지 않을 수있는이에 스크립트를 단축 할 수있다 :

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

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

건배!

+1

+1! 좋은 충고! – jwueller

+0

확실히 좋은 충고. 이것은 jQuery가 자바 스크립트 코드를 정리하는 방법을 보여주는 완벽한 예입니다. –