2010-01-05 4 views
3

Javascript (Prototype 사용)에서 특정 div 내의 첫 번째 양식 항목에 커서를 맞추기위한 요구 사항이 있습니다.div 내에서 모든 유형의 첫 번째 포커스가있는 항목 찾기

간단한 예 :

<form id="theForm"> 
    <div id="part1"> 
    <input id="aaa" .../> 
    <select id="bbb">...</select> 
    </div> 
    <div id="part2"> 
    <select id="ccc">...</select> 
    <input id="ddd" .../> 
    </div> 
</form> 

내가 theForm 내 사업부의 이름을 사용하고 DIV의 첫 번째 항목에 커서를 초점을 맞춘 자바 스크립트 함수를 작성하려면 - 예를 들어,

$(pDiv).select('input','select',...etc.); 

그러나,이 모든 선택 다음에 모든 입력을 포함하는 배열, 등 그것은 아무튼를 반환

:

focusOnFirst('part1'); // will put focus on input "aaa" 
focusOnFirst('part2'); // will put focus on select "ccc" 

는 나는이 같은 프로토 타입의 선택 방법을 사용할 수있을 줄 알았는데 div 안에 나타나는 순서대로 항목을 반환하지 않습니다. 위의 예에서 "ccc"를 선택하는 대신 "ddd"입력에 포커스를 둡니다.

또 다른 가능성은 양식 getElements 방법입니다 :

$('theForm').getElements(); 

하지만 지금은 각 항목이 필요한 DIV 내부에 떨어지면 볼 반환 심문 할 필요가있다. 그리고 현재 내가 아는 유일한 방법은 모든 조상을 얻고 선택한 div가 있는지 확인하는 것입니다. 그렇게 할 수는 있지만 가장 효율적인 솔루션이 아닐까 걱정됩니다.

누구나 더 좋은 방법을 제안 할 수 있습니까?

답변

1

무엇 CSS3 선택기 사용에 대한 : 그래서 그냥 첫 번째를 잡고 그것을 초점

$$('#theForm input:first-of-type')[0].focus() 

그것은 우리가 하나 개의 요소를 포함 것 알고있다하더라도, 배열을 반환합니다.

I've worked up a quick example.

- 편집 좋아, 나는 그것이 선택 요소를 놓친 것을 깨달았다. 나는 내 연결 예를 업데이트했습니다

function focusOnFirst2(divName) { 
    $$('#' + divName + ' [name]')[0].focus(); 
} 

: (다른 것을 사용할 수 있습니다, 당신은 이름 속성을 가지고 가정)을 name 속성을 가진 첫 번째 요소를 선택 -이 --edit

가 작동하는 것 같다 나의 잘못된 첫 시도뿐만 아니라 이것을 포함 시키십시오.

--edit 마지막 시간 :

나는 당신의 기능을 수행하고이 사업부의 자녀가 아닌 형태의 어린이를 기반으로 검색이 때문에 주위를 설정하려고 시도했습니다.

function focusFirstItem (divId) 
{ 
    if ($(divId)) 
    { 
     var elems = $('myForm').getElements(); 
     var elems2 = $(divId).select('*'); 
     for (i=0, l=elems2.length; i<l; ++i) { 
      var item = elems2[i]; 
      if (item.id && !item.disabled && !item.readOnly && item.visible) { 
       if (elems.find(function(s){return s.id = item.id})) 
       item.focus(); 
       break; 
      } 
     } 
    } 
} 

In example page with rudimentary timing : 나는 100 번으로 전화를 잘 모르겠어요은 현실 세계에서 더 좋은 당신을 위해있을거야 여부, IE에서 ~ 45 %의 개선을 볼 수있는 루프에 붙어.

+0

감사합니다. 특히 예제를 추가해 주셔서 감사합니다. 그러나 항목이 입력 또는 선택 (또는 텍스트 영역 등) 일 수있는 경우에도 이와 동일한 문제가 발생합니다. 지정한 순서에 따라 결과가 달라집니다. "3"을 선택 목록으로 변경하고 코드를 "$$ ('#'+ divName + '입력 : 첫 번째 형식', '#'+ divName + 'select : first- type ') [0] .focus() "Div Two 버튼은 두 매개 변수를 교환하지 않는 한"Three "대신"Four "항목에 포커스를 둡니다. 이 프로토 타입 문서에도 불구하고 "확장 된 DOM 요소의 문서 순서 배열을 반환합니다." –

+0

예, 방금 선택한 요소에 대해 생각하지 않았습니다. – robertc

+0

위의 코드에서 이름 속성이 없기 때문에 속성을 추가해야한다면 클래스 이름을 추가하고 선택할 수 있습니다. – robertc

1

이것은 내가 지금까지 가지고 올 관리 한 것입니다 : 끔찍한

focusFirstItem (divId) 
{ 
    if ($(divId)) 
    { 
     var elems = $('myForm').getElements(); 
     for (i=0, l=elems.length; i<l; ++i) { 
      var item = $(elems[i]); 
      if (!item.disabled && !item.readOnly && item.visible) { 
       if (item.ancestors().find(function(s){return s.id == divId})) { 
        $(item).focus(); 
        break; 
       } 
      } 
     } 
    } 
} 

, 나는 알고있다.IE6에서 실행하는 데는 약 0.5 초가 걸리지 만 FF에서는 70ms 정도면 더 좋습니다. Prototype을 사용하여 "for"루프를 제거 할 수 있어야한다는 것을 알고 있지만 그렇게하려는 내 시도에 현혹 적으로 실패했습니다.

+0

.ancestors 호출은 최적화를위한 좋은 타겟 일 수 있다고 생각합니다. 루프를 통해 매번 동일한 요소를 많이 수집하게 될 것입니다. $ ('myForm'). getElements()가 얼마나 오래 걸릴 수 있습니까? – robertc

+0

나는 내 대답에 약간 옆으로 당신의 접근 방식을 돌리려고했다. – robertc

관련 문제