원래는 부동 위치 지정과 마우스 따르기를 결합하는 툴팁 효과를 만들고 싶었지만 위치 지정과 마우스 따르기가 여전히 일부 주요 위치에서 다르기 때문에 별도로 수행해야 합니다.
이 효과 자체는 그다지 어렵지 않습니다. 주로 프로그램 구조와 확장에 힘써 좀 더 사용하기 편리하고 더 많은 곳에서 사용할 수 있도록 했습니다.
프로그램 특징
<!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 ">
<머리>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>JavaScript 부동 위치 지정 프롬프트 효과</title>
<스크립트>
var $$ = 함수(id) {
return "string" == id 유형 ? document.getElementById(id) : id;
};
var isIE = navigator.userAgent.indexOf('MSIE') != -1;
var isIE6 = isIE && ([/MSIE (d).0/i.exec(navigator.userAgent)][0][1] == "6");
var isChrome = navigator.userAgent.indexOf('Chrome') != -1;
var isSafari = navigator.userAgent.indexOf('AppleWebKit') != -1;
// Tino Zijdel, Matthias Miller, Diego Perini의 입력 포함
// http://dean.edwards.name/weblog/2005/10/add-event/
function addEvent(요소, 유형, 핸들러) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} 또 다른 {
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
if (!element.events) element.events = {};
var 핸들러 = element.events[type];
if (! 핸들러) {
핸들러 = element.events[type] = {};
if (요소["on" + 유형]) {
핸들러[0] = 요소["on" + 유형];
}
}
핸들러[handler.$$guid] = 핸들러;
요소["on" + 유형] = handlerEvent;
}
};
addEvent.guid = 1;
function RemoveEvent(요소, 유형, 핸들러) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} 또 다른 {
if (element.events && element.events[type]) {
element.events[type][handler.$$guid] 삭제;
}
}
};
함수 핸들이벤트(이벤트) {
var returnValue = true;
event = 이벤트 || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
var handlers = this.events[event.type];
for (핸들러의 var i) {
this.$$handleEvent = 핸들러[i];
if (this.$$handleEvent(event) === false) {
반환 값 = 거짓;
}
}
반환 값;
};
함수 fixEvent(이벤트) {
event.target = event.srcElement;
if(event.type == "mouseout") {
event.관련Target = event.toElement;
}else if(event.type == "mouseover") {
event.관련Target = event.fromElement;
}
복귀 이벤트;
};
var Extend = function(대상, 소스) {
for(소스의 var 속성) {
목적지[속성] = 소스[속성];
}
귀국 목적지;
}
var 포함 = 함수(a, b){
return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
}
var 바인딩 = 함수(객체, 재미) {
var args = Array.prototype.slice.call(인수, 2);
반환 함수() {
return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}
var BindAsEventListener = function(객체, 재미) {
var args = Array.prototype.slice.call(인수, 2);
반환 함수(이벤트) {
return fun.apply(object, [event].concat(args));
}
}
var FixTips = function(팁, 옵션){
this.Tip = $$(tip);//프롬프트 상자
this._trigger = null;//트리거 객체
this._timer = null;//타이머
this._cssTip = this.Tip.style;//단순화된 코드
this._onshow = false;//현재 디스플레이 상태를 기록합니다.
this.SetOptions(옵션);
//팁 객체 처리
this._cssTip.margin = 0;//위치 문제 방지
this._cssTip.position = "절대";
this._cssTip.visibility = "숨김";
this._cssTip.display = "차단";
this._cssTip.zIndex = 99;
this._cssTip.left = this._cssTip.top = "-9999px";//자리 표시자에 스크롤 막대 방지
//오프셋 보정 매개변수
var iLeft = iTop = 0, p = this.Tip;
동안(p.offsetParent) {
p = p.offsetParent; iLeft += p.offsetLeft;
};
this._offsetleft = iLeft;
this._offsettop = 아이탑;
//Tip 객체로 이동할 때 계속 표시
addEvent(this.Tip, "mouseover", BindAsEventListener(this, function(e){
//외부 요소가 들어오면 현재 은닉 지연 단계에 있다는 의미이며, 타이머를 클리어하여 은닉을 취소합니다.
this.Check(e.관련Target) &&clearTimeout(this._timer);
}));
//ie6은 선택을 처리합니다.
만약 (isIE6) {
this._iframe = document.createElement("<iframe style='position:absolute;filter:alpha(opacity=0);display:none;'>");
document.body.insertBefore(this._iframe, document.body.childNodes[0]);
};
//클릭하여 숨기는 데 사용됩니다.
this._fCH = BindAsEventListener(this, function(e) {
if (this.Check(e.target) && this.CheckHide()) {
this.ReadyHide(this._trigger.ClickHideDelay);
};
});
//숨기기 메소드를 트리거하는 데 사용됩니다.
this._fTH = BindAsEventListener(this, function(e) {
if (this.Check(e.관련Target) && this.CheckHide()) {
this.ReadyHide(this._trigger.TouchHideDelay);
};
});
};
FixTips.prototype = {
_doc: document.documentElement,//코드 단순화
//기본 속성 설정
SetOptions: 함수(옵션) {
this.options = {//기본값
ClickShow: true,//클릭 모드에서 표시할지 여부
ClickShowDelay: false,//클릭 표시 지연 여부
ClickHide: true,//클릭 모드 숨김 여부
ClickHideDelay: false,//지연을 숨기기 위해 클릭할지 여부
TouchShow: true,//트리거 모드 표시 여부
TouchShowDelay: true,//디스플레이 지연을 트리거할지 여부
TouchHide: true,//트리거 모드가 숨겨져 있는지 여부
TouchHideDelay: true,//숨기기 지연을 트리거할지 여부
ShowDelay: 300,//표시 지연 시간
HideDelay: 300,//지연 시간 숨기기
Align: "clientleft",//가로 위치 지정
vAlign: "clienttop",//세로 위치 지정
사용자 정의: { 왼쪽: 0, 위쪽: 0 },//사용자 정의 위치 지정
백분율: { 왼쪽: 0, 위쪽: 0 },//사용자 정의된 백분율 위치 지정
적응형: false,//적응형 위치 지정 여부
재설정: false,//적응형 포지셔닝 중 위치를 변경할지 여부
onShow: function(){},//표시할 때 실행
onHide: function(){}//숨겨지면 실행됩니다.
};
확장(this.options, 옵션 || {});
},
//트리거 요소 확인
확인: function(elem) {
//외부 요소(즉, 트리거 요소가 아닌 요소 객체와 Tip 객체 자체 및 내부 요소)인지 여부를 반환합니다.
return !this._trigger ||
!(
this.Tip === elem || this._trigger.Elem === elem ||
포함(this.Tip, elem) || 포함(this._trigger.Elem, elem)
);
},
//표시할 준비가 되었습니다.
ReadyShow: 기능(지연) {
ClearTimeout(this._timer);
var 트리거 = this._trigger;
//숨기려면 클릭하세요.
Trigger.ClickHide && addEvent(document, "click", this._fCH);
//트리거 모드 숨김
Trigger.TouchHide && addEvent(this._trigger.Elem, "mouseout", this._fTH);
//트리거를 지연할지 여부
if (지연) {
this._timer = setTimeout(Bind(this, this.Show), Trigger.ShowDelay);
} else { this.Show() };
},
//보여주다
표시: 함수() {
ClearTimeout(this._timer);
this._trigger.onShow();//속성을 쉽게 수정할 수 있도록 앞에 배치합니다.
//사전 설정된 위치 지정 및 사용자 지정 위치 지정을 기반으로 왼쪽과 위쪽을 계산합니다.
var 트리거 = this._trigger, ret = Trigger.Elem.getBoundingClientRect(),
scrolldoc = isChrome || isSafari ? document.body : this._doc,
scrollLeft = scrolldoc.scrollLeft, scrollTop = scrolldoc.scrollTop,
customLeft = Trigger.Custom.left, customTop = Trigger.Custom.top,
iLeft = this.GetLeft(직사각형, Trigger.Align) + customLeft,
iTop = this.GetTop(ect, Trigger.vAlign) + customTop;
//사용자 지정 비율 위치 지정
if (trigger.Percent.left) { iLeft += .01 * Trigger.Percent.left * Trigger.Elem.offsetWidth };
if (trigger.Percent.top) { iTop += .01 * Trigger.Percent.top * Trigger.Elem.offsetHeight };
//적응형 창 위치 지정
if (trigger.Adaptive) {
//올바른 위치 매개변수
var maxLeft = this._doc.clientWidth - this.Tip.offsetWidth,
maxTop = this._doc.clientHeight - this.Tip.offsetHeight;
if (trigger.Reset) {
//자동 위치 조정
if (iLeft > maxLeft || iLeft < 0) {
iLeft = this.GetLeft(ect, 2 * iLeft > maxLeft ? "왼쪽" : "오른쪽") + customLeft;
};
if (iTop > maxTop || iTop < 0) {
iTop = this.GetTop(ect, 2 * iTop > maxTop ? "top" : "bottom") + customTop;
};
} 또 다른 {
//적절한 위치로 수정
iLeft = Math.max(Math.min(iLeft, maxLeft), 0);
iTop = Math.max(Math.min(iTop, maxTop), 0);
};
};
//위치 설정 및 표시
this._cssTip.left = iLeft + scrollLeft - this._offsetleft + "px";
this._cssTip.top = iTop + scrollTop - this._offsettop + "px";
this._cssTip.visibility = "표시됨";
//ie6은 선택을 처리합니다.
만약 (isIE6) {
this._iframe.style.left = iLeft + scrollLeft + "px";
this._iframe.style.top = iTop + scrollTop + "px";
this._iframe.style.width = this.Tip.offsetWidth + "px";
this._iframe.style.height = this.Tip.offsetHeight + "px";
this._iframe.style.display = "";
};
//트리거 모드 숨김
Trigger.TouchHide && addEvent(this.Tip, "mouseout", this._fTH);
},
//상대 트리거 요소의 왼쪽을 가져옵니다.
GetLeft: 함수(직사각형, 정렬) {
스위치(align.toLowerCase()) {
"왼쪽" 경우:
ret.left 반환 - this.Tip.offsetWidth;
사례 "clientleft":
ret.left를 반환;
케이스 "센터":
return (직류.왼쪽 + 직류.오른쪽 - this.Tip.offsetWidth)/2;
케이스 "clientright":
ret.right 반환 - this.Tip.offsetWidth;
"오른쪽":
기본 :
ret.right를 반환;
};
},
//트리거 요소를 기준으로 상단을 가져옵니다.
GetTop: 함수(직사각형, valign) {
스위치(valign.toLowerCase()) {
케이스 "상단":
ret.top 반환 - this.Tip.offsetHeight;
케이스 "클라이언트톱":
ret.top을 반환합니다.
케이스 "센터":
return (직사각형 상단 + 직사각형 하단 - this.Tip.offsetHeight)/2;
사례 "clientbottom":
ret.bottom 반환 - this.Tip.offsetHeight;
케이스 "하단":
기본 :
ret.bottom을 반환합니다.
};
},
//숨길 준비
ReadyHide: 기능(지연) {
ClearTimeout(this._timer);
if (지연) {
this._timer = setTimeout(Bind(this, this.Hide), this._trigger.HideDelay);
} else { this.Hide() };
},
//숨다
숨기기: 함수() {
ClearTimeout(this._timer);
//숨기도록 설정
this._cssTip.visibility = "숨김";
this._cssTip.left = this._cssTip.top = "-9999px";
//ie6은 선택을 처리합니다.
if (isIE6) { this._iframe.style.display = "없음" };
//프로세스 트리거 객체
if (!!this._trigger) {
this._trigger.onHide();
RemoveEvent(this._trigger.Elem, "mouseout", this._fTH);
}
this._trigger = null;
//이벤트 제거
RemoveEvent(this.Tip, "mouseout", this._fTH);
RemoveEvent(document, "click", this._fCH);
},
//트리거 객체 추가
추가: function(elem, options) {
//트리거 객체 생성
var elem = $$(elem), Trigger = Extend(Extend({ Elem: elem }, this.options), options || {});
//표시하려면 클릭하세요.
addEvent(elem, "click", BindAsEventListener(this, function(e){
if (trigger.ClickShow) {
if (this.CheckShow(trigger)) {
this.ReadyShow(trigger.ClickShowDelay);
} 또 다른 {
ClearTimeout(this._timer);
};
};
}));
//트리거 모드 표시
addEvent(elem, "mouseover", BindAsEventListener(this, function(e){
if (trigger.TouchShow) {
if (this.CheckShow(trigger)) {
this.ReadyShow(trigger.TouchShowDelay);
} else if (this.Check(e.관련Target)) {
ClearTimeout(this._timer);
};
};
}));
//트리거 객체 반환
리턴 트리거;
},
//체크 표시
CheckShow: 함수(트리거) {
if (트리거 !== this._trigger) {
//동일한 트리거 객체가 아닌 경우 먼저 Hide를 실행하여 충돌을 방지합니다.
this.Hide(); this._trigger = 트리거;
} else { false를 반환 };
},
//숨기기 체크
CheckHide: 함수() {
if (this._cssTip.visibility === "숨김") {
//원래 히든상태이므로 더 이상 Hide를 실행할 필요가 없습니다.
ClearTimeout(this._timer);
RemoveEvent(this._trigger.Elem, "mouseout", this._fTH);
this._trigger = null;
RemoveEvent(document, "click", this._fCH);
거짓을 반환;
} else { 참을 반환 };
}
};
</script>
</head>
<본문>
<스타일>
.trigger{테두리:1px 솔리드 #003099; 배경:#e2e7ff; 너비:200px; 여백:150px
.tip{테두리:1px 단색 #c00000; 배경:#ffcccc; 라인 높이:20px;
</style>
<div 스타일="패딩:50px;">
<div id="idTip" class="tip"></div>
<div id="idTrigger1" class="trigger">
<선택>
<옵션>테스트</옵션>
</select>
</div>
<br>
수평 위치:
<라벨>
<input name="nAlign" type="radio" value="left" />
왼쪽 </label>
<라벨>
<input name="nAlign" type="radio" value="clientleft" />
클라이언트왼쪽 </label>
<라벨>
<input name="nAlign" type="radio" value="center" />
센터 </label>
<라벨>
<input name="nAlign" type="radio" value="clientright" />
클라이언트권 </label>
<라벨>
<input name="nAlign" type="radio" value="right" check="checked" />
오른쪽 </label>
<br>
수직 위치:
<라벨>
<input name="nVAlign" type="radio" value="top" />
상단 </label>
<라벨>
<input name="nVAlign" type="radio" value="clienttop" />
클라이언트탑 </label>
<라벨>
<input name="nVAlign" type="radio" value="center" />
센터 </label>
<라벨>
<input name="nVAlign" type="radio" value="clientbottom" />
클라이언트하단 </label>
<라벨>
<input name="nVAlign" type="radio" value="bottom" check="checked" />
하단 </label>
<br>
<br>
맞춤 타겟팅:
왼쪽:
<input id="idLeft" type="text" size="5" value="0" maxlength="3" />
맨 위:
<input id="idTop" type="text" size="5" value="0" maxlength="3"/>
<br>
<br>
<input id="idClick" type="checkbox" selected="checked" />
<label for="idClick">클릭 방법</label>
<input id="idTouch" type="checkbox" selected="checked" />
<label for="idTouch">트리거 방법</label>
<br>
<br>
지연 시간:
<input id="idDelayTime" type="text" size="5" value="0" maxlength="4"/>
<input id="idDelay" type="button" value="지연 취소" />
<br>
<br>
기타 적용 예: <br>
<br>
<div id="idTest1"> 제목 사용: <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/11/17/1334778.html " title="드래그 앤 드롭 효과"> 드래그 및 드롭 효과</a> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/12/03/1346386.html " title="드래그 및 확대/축소 효과"> 드래그 및 확대/축소 효과</a > <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/07/21/1247267.html " title="사진 자르기 효과"> 사진 자르기 효과</a > </div >
<br>
<br>
인기 있는 아바타 표시 효과: <br>
<br>
<div id="idTest2"> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/07/06/1236770.html " title="사진 슬라이딩 전환 효과"> <img src= "/articleimg/2009/07/6852/r_mx1.jpg" border="0"/></a> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/05/ 23/1205642.html " title="사진 변형 효과"><img src="/articleimg/2009/07/6852/r_mx2.jpg" border="0"/></a> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/05/13/1194272.html " title="사진 슬라이딩 디스플레이 효과"><img src="/articleimg/2009/07/6852/r_mx3.jpg " border="0"/></a> </div>
<br>
<br>
닫기 버튼: <a id="idTest3" href=" http://www.cnblogs.com/cloudgamer/archive/2009/05/18/TableFixed.html">테이블 행 위치 지정 효과</a>
</div>
<스크립트>
var forEach = function(배열, 콜백, thisObject){
if(array.forEach){
array.forEach(콜백, thisObject);
}또 다른{
for (var i = 0, len = array.length; i < len; i++) { callback.call(thisObject, array[i], i, array) }
}
}
/////////////////////////////////////////
var ft = new FixTips("idTip");
/////////////////////////////////////////
var Trigger1 = ft.Add("idTrigger1", {
onShow: 함수(){
//위치 테스트
var sAlign = this.Align, sVAlign = this.vAlign;
forEach(document.getElementsByName("nAlign"), function(o){ if(o.checked){ sAlign = o.value; } });
forEach(document.getElementsByName("nVAlign"), function(o){ if(o.checked){ sVAlign = o.value; } });
this.Align = sAlign;
this.vAlign = sVAlign;
this.Custom.left = $$("idLeft").value 0;
this.Custom.top = $$("idTop").value 0;
Trigger1.ShowDelay = Trigger1.HideDelay = $$("idDelayTime").value 300;
ft.Tip.innerHTML = sAlign + "<br>" + sVAlign + "<br>" + "왼쪽: " + this.Custom.left + ", 위쪽: " + this.Custom.top;
}
});
//지연 테스트
$$("idDelayTime").value = Trigger1.ShowDelay;
$$("idDelay").onclick = 함수(){
if(trigger1.TouchShowDelay){
Trigger1.ClickShowDelay = Trigger1.ClickHideDelay =
Trigger1.TouchShowDelay = Trigger1.TouchHideDelay = 거짓;
$$("idDelayTime").disabled = true;
this.value = "지연 설정";
}또 다른{
Trigger1.ClickShowDelay = Trigger1.ClickHideDelay =
Trigger1.TouchShowDelay = Trigger1.TouchHideDelay = true;
$$("idDelayTime").disabled = false;
this.value = "지연 취소";
}
}
//메서드 테스트
$$("idClick").onclick = 함수(){
Trigger1.ClickShow = Trigger1.ClickHide = this.checked;
}
$$("idTouch").onclick = 함수(){
Trigger1.TouchShow = Trigger1.TouchHide = this.checked;
}
//////////////////////////////////////////
forEach($$("idTest1").getElementsByTagName("a"), function(o){
var 제목 = o.제목 = "";
ft.Add(o, { vAlign: "bottom", Percent: { 왼쪽: 50, 위쪽: 0 }, onShow: function(){ ft.Tip.innerHTML = title; } });
})
//////////////////////////////////////////
forEach($$("idTest2").getElementsByTagName("a"), function(o){
var img = o.getElementsByTagName("img")[0], title = o.title;
o.제목 = "";
ft.Add(img, { 사용자 정의: { 왼쪽: -6, 위쪽: -6 },
onShow: 함수(){
var str = '<a href="' + o.href + '"><img src="' + img.src + '" style="padding-bottom:5px;" border="0"/></ 가>';
str += '<br /><a href="' + o.href + '">' + 제목 + '</a>';
ft.Tip.innerHTML = str;
}
});
})
//////////////////////////////////////////
ft.Add("idTest3", { ClickHide: false, TouchHide: false, Align: "오른쪽",
onShow: 함수(){
var str = ' <a href=" http://www.cnblogs.com/cloudgamer/archive/2009/03/11/1408333.html "> 색상 그라데이션 및 그라데이션 효과</a><br />';
str += ' <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/10/20/1314766.html "> 모방 163 네트워크 디스크 새로 고침 파일 업로드 시스템 없음</a><br / >';
str += '<input type="button" onclick="ft.Hide();" value="닫으려면 클릭하세요" />';
ft.Tip.innerHTML = str;
}
});
</script>
</body>
</html>
JavaScript, 포지셔닝, 플로팅, 팁, 툴팁, FixTips, Tip
프로그램 설명
팁 개체 :
Tip 개체는 프롬프트 정보를 표시하는 데 사용되는 컨테이너이며 프로그램은 Tip 속성으로 표시됩니다. 이에 대한 요구 사항은 없으며 프로그램이 초기화될 때 일부 설정이 지정됩니다.
먼저 다음 설정을 수행하십시오.
this._cssTip.margin = 0;
this._cssTip.position = "절대";
this._cssTip.visibility = "숨김";
this._cssTip.display = "차단";
this._cssTip.zIndex = 99;
this._cssTip.left = this._cssTip.top = "-9999px";
일부 위치 지정 문제를 방지하기 위해 여백은 0으로 설정됩니다. 프로그램이 팁의 offsetWidth 및 offsetHeight를 가져와야 하기 때문에 표시 대신 숨기기 위해 사용됩니다. 팁이 공간을 차지하고 있습니다.
팁은 위치가 지정된 다른 요소 내부에 있을 수 있으므로 두 개의 오프셋 수정 매개변수를 설정해야 합니다.
var iLeft = iTop = 0, p = this.Tip.offsetParent;
while (!(p === document.body || p === document.documentElement)) {
iLeft += p.offsetLeft; iTop += p.offsetTop p = p.offsetParent;
};
this._offsetleft = iLeft;
this._offsettop = 아이탑;
마지막으로 나중에 설명할 Tip의 마우스 오버에 이벤트를 추가합니다.