동적 요소 변동에 대한 자바스크립트 제어

국내에 웹 사이트들이 웹 표준을 지키고 OS나 브라우저와 관계 없이 접근성을 향상 시키기 위한 사이트 버그 신고 및 문제 해결을 위한 게시판입니다.
Post Reply
나비스

동적 요소 변동에 대한 자바스크립트 제어

Post by 나비스 »

이거 내 머리속으론 맞는것 같은데.. 해결이 안되네요.
익스에서는 잘 됩니다.

아래와 같이
<input name=n type=text>
<input name=n type=text>
<input name=n type=text>
<input name=n type=text>

이렇게 여러개 배열로 있는 것을
동적변경을 통하여
<input name=n type=text>
이렇게 하나로 만들었습니다.

그런데. 변동후 자바스크립트 제어는 어케 하나요
도대체 접근 방법이 없네요.

익스에서는 이게 동적적용이 원활이 되어서
배열이 아니라 하나로 인식하여 배열없이 하나로 제어하면 되는데

파이어폭스에서는 왜 이걸 인식못하는건지..
아니면 제가 정확하게 알고 있지 않은건지..

접근 방법은 이렇습니다.
var frm = document.formname;
if (typeof(frm.n[0]) == "object") { //배열이면
n[0].value = "aaa";
}
else { //배열이 아니면..
n.value = "aaa";
}

이런식으로 제어를 하면 익스에서는 원할이 잘 먹습니다.
그래서 동적으로 페이지 내용을 변경하더라도 크게 문제없이 적용이 되는데.

파이어폭스에서는 어떻게 제어하나요.
거참. 골때리네..
화면에 하나밖에 없는데.. 배열도 아니고.. 단일도 아니고..
그럼 머냐..
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

Re: 동적 요소 변동에 대한 자바스크립트 제

Post by 박민권 »

나비스 wrote: 접근 방법은 이렇습니다.
var frm = document.formname;
if (typeof(frm.n[0]) == "object") { //배열이면
n[0].value = "aaa";
}
else { //배열이 아니면..
n.value = "aaa";
}

이런식으로 제어를 하면 익스에서는 원할이 잘 먹습니다.
그래서 동적으로 페이지 내용을 변경하더라도 크게 문제없이 적용이 되는데.

파이어폭스에서는 어떻게 제어하나요.
거참. 골때리네..
화면에 하나밖에 없는데.. 배열도 아니고.. 단일도 아니고..
그럼 머냐..
배열인지 아닌지는 아래의 코드로 판단하시는 것이 좋다고 생각합니다.

Code: Select all

if(frm.n.length) 배열
else 배열아님
배열일 경우 length의 값은 최소 1입니다.

if (typeof(frm.n[0]) == "object") 이 코드를 테스트 해봤는데 동작에 문제 없습니다.

혹시 아래의 코드에서 n.value라고 하신것 맞나요?
그렇다면 틀렸습니다. 님이 선언하신 것 처럼 frm.n.value, frm.n[0].value 가 맞습니다.

Code: Select all

var frm = document.formname;
if (typeof(frm.n[0]) == "object") { //배열이면
    frm.n[0].value = "aaa";
}
else { //배열이 아니면..
    frm.n.value = "aaa";
}

제가 말씀드린 배열인지 판단하는 코드를 사용하면 아래와 같습니다.

Code: Select all

var frm = document.formname;
if (frm.n.length) { //배열이면
    frm.n[0].value = "aaa";
}
else { //배열이 아니면..
    frm.n.value = "aaa";
}
나비스

좀 이상하군요.

Post by 나비스 »

배열이 아닐경우
n.length
라고 하시면.. 에러가 납니다.

왜냐면 배열이 아니라서 length 가 나올수가 없죠

님 제 코드로 테스트 해 보셨나요.
한번 해보세요.
typeof(.. 를 하면 객체인지 아닌지의 판단기준이 됩니다.
당연히 n[0] 이면 배열이라면 최소 0은 있기 때문에.. 이렇게 해서
object 를 반환하면 배열이라고 판단하는 겁니다.

배열이 아닌데 length 를 쓴다는건 좀 웃기군요
먼저 배열인지 아닌지를 판단해야 하는데
님의 경우

try{
//배열일 경우
if (n.length) {
}
} catch(e) {
//배열이 아닐경우
}
위와 같이 에러처리를 해 줘야지만 제대로 된 걸 껍니다.

n.length 라는 객체가 없는데 쓰면 에러가 나는건 당연할텐데..
쩝..
나비스

한가지 빠뜨린게 있는데..

Post by 나비스 »

동적으로 생성돼는 컨텐츠 입니다.

그냥 찡박아 놓은 게 아니고
페이지 바뀜없이 innerHTML 로 생성되는 것을 말합니다.

해 보세요.

첨엔 배열이다가
innerHTML 로 배열없이 하나만 주면
이렇게 됩니다.

제가 보기엔
동적생성된 객체 제어에 파이어폭스는 제대로 되어 있지 않는듯 하군요.

결론은 열라 노가다 해서 각 이름을 달리 해주고 그걸 검사해서 하는 방법이 젤 효과적인데..
이런 경우 노가다 할일없어 하나..
하며 그냥 안하고 말지..

제가 보기엔 이건 표준이고 머고 보다
ECMA 스크립트의 표준이라고 보는데..
제대로 동적 컨텐츠에 대해서는 안되면 이것부터 제대로 해 놓는게 순서일꺼 같네요.

아마 보기엔. 기존에 있던 컨텐츠를 동적으로 삭제하고 새로 삽입해서
그 전의 객체가 남아있는듯도 보이고..
여튼.. 새로 생성된 것에는 접근 방법이
유일한 아이디를 주는 방법외에는 대안이 없네요.
포기하는게 낫지..
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

...

Post by 박민권 »

에러가 나지는 않습니다.
undefined이 됩니다.
때문에 if(frm.n.length)를 할 경우 배열이 아니면 거짓이 되어버립니다.
에러는 나지 않습니다.

익스와 기타 브라우저의 이벤트 체크시에도

if(window.event) 익스 이벤트 처리
else 기타 브라우저 이벤트 처리

이런식으로 처리하기를 권장하고 있습니다.
다른 브라우저에는 window.event라는 것이 없지만 이것도 마찬가지로
undefined이 되어 거짓으로 처리되고 에러는 나지 않습니다.
이런 식으로 undefined으로 처리되는 값을 통해 브라우저별 판단할때 자주 사용합니다.
UserAgent의 값으로 브라우저 판단하는 것보다 해당 브라우저 고유의 값을
이용하여 undefined 인지의 여부로 브라우저별 동작을 하게 하는 것이 좋습니다.

제가 위에 말씀드렸듯이 님의 코드로 테스트를 해봤기에 님의 코드도 문제가 없다고 이야기 한 것입니다.
typeof(frm.n[0]) == "object" 이 코드가 동작하는데 에러는 없습니다.

n.value 를 frm.n.value로 처리 하신다면 나머지 코드도 문제 없이 동작할 것입니다.

다시 말씀드리지만 님의 코드로 테스트 해봤고 동작에 문제 없으며 frm.n.length도 문제가 없습니다.
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

...

Post by 박민권 »

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" />
<title>무제 문서</title>

</head>

<body>

<form name="frm">
	<input type="text" name="n" />
	<input type="text" name="n" />
</form>

<script type="text/javascript">
	var frm = document.frm;
	if (typeof(frm.n[0]) == "object") { //배열이면
		frm.n[0].value = "aaa";
	}
	else { //배열이 아니면..
		frm.n.value = "aaa";
	} 
</script>
이 코드 그대로 저장해서 테스트 해보세요. 문제없습니다.
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

아..

Post by 박민권 »

마지막에
</body>
</html>
빼먹었네요.
나비스

음. 그건 글네요.

Post by 나비스 »

님의 말씀처럼 에러는 없군요
undefined 라는 걸 보내니..
거짓이 되는군요.

그런데 말입니다.

동적으로 생성해서 해 보세요.
그냥 첨부터 그런거 말고 말입니다.

다들 왜 첨부터 찡박혀 있는걸 얘기하시는지 모르겠군요
첨부터 그런경우는 아무런 문제가 없어요
첨엔 배열이다가
배열 컨텐츠 부분없애고 새로 하나만 생성해서
해보세요.
되는가
익스에서는 잘 돼요.
파폭에서만 안될뿐.
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

ㅠ_ㅠ 잘됩니다.

Post by 박민권 »

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" />
<title>무제 문서</title>

</head>

<body>

<form name="frm" id="frm">

</form>

<script type="text/javascript">
	var code = '';
	for(i=0;i<3;i++){
		code += '<input type="text" name="n" />';
	}

	document.getElementById('frm').innerHTML = code;

	var frm = document.frm;
	if (typeof(frm.n[0]) == "object") { //배열이면
		frm.n[0].value = "aaa";
	}
	else { //배열이 아니면..
		frm.n.value = "aaa";
	} 
</script>

</body>
</html>

위의 것 복사해서 해보세요.
잘됩니다. 전혀 문제없습니다. ㅠ_ㅠ
나비스

음.

Post by 나비스 »

제가 집에서 다시 한번 간단한 코드로 해 보니..

되네요.

왜 회사에서 작업에서는 안 되었지..

다시 한번 검토해서 문제가 있으면 다시 소스까지 올려보겠습니다.

회사에서 좀 동적인 내용이 많은데ㅣ..

똑같은 코드가 익스에서는 잘 먹고
파폭에서 안 먹으면..
먼가 문제가 있는거지 않겠습니까?

내가 코딩을 잘못했나..

여튼.. 민권님 의견 주셔서 감사합니다.
님이 아닌것과 제가 아는것은 같은데..
왜 회사에서는 안 되었는지 모르겠네요.
집에서 간간하게 동적으로 해 보니
되네요...

거참. 이거 무안스러워지네요.
여튼 죄송합니다.
낼 회사가서 한번 더 확인해 봐야겠네요.
코드가 잘못되었던지.. 아니면 동적인게 많이 섞여서 문제가 있는건지..
낼 해서 안되면 여기에 다시 한번 올려볼께요.
오늘 감사합니다.
나비스

참 그러면 한가지 제가 질문드려볼께요.

Post by 나비스 »

제가
아이디로 접근해서 배열이 있습니다.

이런경우 어떻게 객체를 가져와서 사용하나요

예를 들면
참고로( 익스에서는 개발에 아무런 문제가 없습니다.)

<span id="n"></span>
<span id="n"></span>
<span id="n"></span>
<span id="n"></span>
<span id="n"></span>

위와 같은 코드가 있습니다.

이걸 가져올려면 어케해야 하나요
이런 방법을 써 봤습니다.

var obj = document.getElementById("n");
obj[0].innerHTML = "xxxxx";
이런 식으로 하니 안 되더군요
객체를 가져오면 배열이면 자동으로 되지 않나보져.
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

Re: 음.

Post by 박민권 »

나비스 wrote:제가 집에서 다시 한번 간단한 코드로 해 보니..

되네요.

왜 회사에서 작업에서는 안 되었지..

다시 한번 검토해서 문제가 있으면 다시 소스까지 올려보겠습니다.
소스까지 올리시면 힘듭니다. 쿨럭~
원래 크로스브라우징 스크립트 하려면 힘듭니다.
저도 별 삽질 다해봤습니다. ㅡㅡ;
어찌보면 변수하나 잘못 쓴 건데 엉뚱한 상상을 할때도 있습니다.
혹은 캐쉬쪽의 문제로 F5를 눌러도 새로고침이 안되는 것도 모르고
"왜 안돼~" 라며 발광을 하기도 했었습니다. ( ㅡДㅡ)
그래서 저도 초기에 불여우 쓸때 브라우저 문제인가 막 의심했었는데
알고보면 정말 아무것도 아닌 것들 이더군요. ㅡㅡ;
정말 특이한거 빼고는 불여우의 자바스크립트 처리는 문제 없으며
국내의 자바스크립트 샘플은 권장하지 않습니다.
구글등을 통해 해외의 자바스크립트 코드를 참고하시는 것이 크로스브라우징을
구현하는데 좋습니다.
나비스

음.

Post by 나비스 »

제가 말하는건 주로 동적 HTML 작업을 많이합니다.

이런 경우 아니면..
사실 이런 문제 안 생기죠
일반적인 거라면..

크로스브라이징 스크립트 생성하고 쓰는데 아무런 문제 없습니다.

얼마전에야
겨우
크로스브라우징 웹에디터를 개발했는데..
사실 정보 거의 전문해서 열라 고생했ㅤㅉㅛㅤ.
그래도 해 놓고 보니 뿌듯하군요.

사실 이 작업하면서.. 파폭 진짜 쓰고 싶지 않더군요.
회사에서도 울나라에서는 거의 IE니 다른거 지원할 필요없어..
라고 하기때문에.. 나야 별 상관도 없습니다.
그리고 굳이 내가 개발해야될 이유도 없고.. 다른 일도 많은데..

동적인 것에 대한 설명, 파폭 절대 부족... 스펙정보 절대 부족..
입니다.
진짜 개발자에게는 돌아버리는 경우죠.
노가다하면서 이거 해야하나 회의적이죠.
어차피 이거 내가 만든것도 아닌데.. 말이죠..
개발자들을 위한 배려가
내가 보니. 애플리케이션 개발자를 위한 배려밖엔 없는듯..
다른건 맨날 하는 말이 W3C 문서 봐라..
ㅎㅎ
정말 엽기적이라고 생각합니다.
거기 머가 있나요. 예제가 있나요. 자세한 사용방법이 있나요
용어와 정의만 있죠..
이러면서 이걸 쓰길 바라는것 자체가.. 개발자에게 노가다 시키는 것 외엔.. 거의 없는듯..
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

Re: 참 그러면 한가지 제가 질문드려볼께요.

Post by 박민권 »

나비스 wrote: <span id="n"></span>
<span id="n"></span>
<span id="n"></span>
<span id="n"></span>
<span id="n"></span>

위와 같은 코드가 있습니다.

이걸 가져올려면 어케해야 하나요
이런 방법을 써 봤습니다.

var obj = document.getElementById("n");
obj[0].innerHTML = "xxxxx";
이런 식으로 하니 안 되더군요
객체를 가져오면 배열이면 자동으로 되지 않나보져.
id는 말그대로 id이기 때문에 문서에 단 하나만 존재하여야 합니다.
두개의 id는 존재할 수 없습니다.
id1, id2... 이런식으로 하시는 수밖에 없습니다.

Code: Select all

<div id="box">
   <span>1 </span>
   <span>2 </span>
   <span>3 </span>
</div>

alert(document.getElementById('box').getElementsByTagName('span').length);
getElementsByTagName() 메소드를 이용해 인수로 태그명을 적어주면
위처럼 span객체를 다 가져올 수 있습니다.
var objs = document.getElementById('box').getElementsByTagName('span');

이렇게 하셔서 objs 객체를 제어하시면 되겠죠?
참고로 innerHTML은 w3c 권장 코드가 아닙니다.

사실 아까 input 객체도

Code: Select all

//객체생성
var objInput = document.createElement('input');
objInput.setAttribute('type','text');
objInput.setAttribute('name','n');

//frm이라는 id를 가진 객체의 자식노드로 objInput을 추가
document.getElementById('frm').appendChild(objInput);
이게 표준입니다.
하지만 익스도 이 표준대로 동작하지만 어떤 특정한 속성사용시 동작되지 않아서

Code: Select all

if(익스라면) var objInput = document.createElement('<input type="text" name="n">');
else{
	var objInput = document.createElement('input');
	objInput.setAttribute('type','text');
	objInput.setAttribute('name','n');
}
위와 같이 따로 나눠쓰고 있습니다.
name 이던가 value던가 여튼 무슨 속성에서 문제가 생기기 때문에 그 속성을 제외하면
불여우와 같은 코드를 사용해도 문제가 없습니다.

자바스크립트를 통해 html문서를 제어하시려면 node를 다룰 수 있는 메소드를 공부해보세요.

노드를 다룰 수 있는 메소드는 아래와 같습니다.

childNodes
firstChild
lastChild
appendChild
removeChild
... 그외 다수

이런 것들을 조사해 보시면 html문서를 더욱 자유롭게 제어하실 수 있을 겁니다.
객체 node에 대한 개념도 잡히구요.

에고.. 퇴근해서까지 코드 잡고 있으니 머리가 막 핑핑 도네요. 빈혈인가 ㅡㅡ;
나비스

음.

Post by 나비스 »

그건 그렇죠
전 긴 코드 보다
간단히 할 수 있는데 왜 그렇게 할까 생각하지 않습니다.
클라이언트측 코드는 짧고 가볍게 할려고 하기 때문에..

그래서 그런 긴코드 방법말고 쉬운 방법이 있으면 그걸합니다.

노드 따라 가고 하는거.. 사실 귀찮습니다.
예전에 해 봤지만..
요즘 쉬운 방법이 있는데. 굳이 그런걸 하고 싶지도 않네요.
귀차니즘일지도 모르고..
그래도 보니 님 많이 아시는군요.
전 이제 거의 웹일은 안해서.. 다 잊어먹고 있는데..
갑자기 한가지 일 할일이 생겨서 해보니.. 글터군요.
박민권
해커
해커
Posts: 724
Joined: 2005 01 31 22:33 55
Location: 대한민국
Contact:

Re: 음.

Post by 박민권 »

나비스 wrote: 동적인 것에 대한 설명, 파폭 절대 부족... 스펙정보 절대 부족..
입니다.
진짜 개발자에게는 돌아버리는 경우죠.
노가다하면서 이거 해야하나 회의적이죠.
어차피 이거 내가 만든것도 아닌데.. 말이죠..
개발자들을 위한 배려가
내가 보니. 애플리케이션 개발자를 위한 배려밖엔 없는듯..
다른건 맨날 하는 말이 W3C 문서 봐라..
해외의 자바스크립트 코드를 보시면 w3c 표준에 준수한 코드가 상당히 많습니다.
구글 검색을 통해서 많은 샘플을 얻을 수 있고 저도 얻었습니다.
오픈프로젝트다 보니 MSDN처럼 체계적인 자료가 모아져 있지는 않지만
커뮤니티등을 통해 많은 자료가 나와있고 따로 불여우 전용으로 된 것이 아니라
W3C표준에 의한 코드이므로 '불여우용 자바스크립트다' 라고는 말 못하겠습니다.

자료는 많지만 단점이 바로 영어. ㅡㅡ;
제 영어 실력은 "아이엠 어 보이. 유알 어 걸." 수준입니다.
그래서 힘듭니다. OTL
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests