Originalmente quería crear un efecto de información sobre herramientas que combinara el posicionamiento flotante y el seguimiento del mouse, pero descubrí que el posicionamiento y el seguimiento del mouse aún son diferentes en algunos lugares clave, por lo que debemos hacerlo por separado.
Este efecto en sí no es muy difícil. Principalmente ponemos un poco de esfuerzo en la estructura y expansión del programa para que sea más conveniente de usar y pueda usarse en más lugares.
Características del programa
Descarga completa del ejemplo (haga clic para descargar)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transicional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
<html xmlns=" http://www.w3.org/1999/xhtml ">
<cabeza>
<meta http-equiv="Tipo de contenido" content="text/html; charset=gb2312" />
<title>Efecto de solicitud de posicionamiento flotante de JavaScript</title>
<guión>
var $$ = función (identificación) {
devolver "cadena" == tipo de identificación? document.getElementById(id): identificación;
};
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;
// con aportes de Tino Zijdel, Matthias Miller, Diego Perini
// http://dean.edwards.name/weblog/2005/10/add-event/
función addEvent(elemento, tipo, controlador) {
si (elemento.addEventListener) {
element.addEventListener(tipo, controlador, falso);
} demás {
if (!handler.$$guid) controlador.$$guid = addEvent.guid++;
if (!element.events) element.events = {};
controladores var = elemento.eventos[tipo];
si (! controladores) {
controladores = elemento.eventos[tipo] = {};
if (elemento["on" + tipo]) {
controladores[0] = elemento["on" + tipo];
}
}
controladores[controlador.$$guid] = controlador;
elemento["on" + tipo] = handleEvent;
}
};
agregarEvento.guid = 1;
función eliminarEvento(elemento, tipo, controlador) {
si (elemento.removeEventListener) {
element.removeEventListener(tipo, controlador, falso);
} demás {
if (elemento.eventos && elemento.eventos[tipo]) {
eliminar elemento.eventos[tipo][controlador.$$guid];
}
}
};
función manejarEvento(evento) {
var returnValue = verdadero;
evento = evento || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
controladores var = this.events[event.type];
para (var i en controladores) {
this.$$handleEvent = controladores[i];
if (this.$$handleEvent(evento) === falso) {
valorretorno = falso;
}
}
devolver valor de retorno;
};
función arreglarEvento(evento) {
evento.target = evento.srcElement;
if(event.type == "mouseout") {
evento.relacionadoTarget = evento.toElement;
}si no (event.type == "mouseover") {
evento.relacionadoTarget = evento.fromElement;
}
evento de regreso;
};
var Extender = función (destino, fuente) {
para (propiedad var en fuente) {
destino[propiedad] = fuente[propiedad];
}
destino de regreso;
}
var Contiene = función(a, b){
return a.contiene ? a != b && a.contiene(b) : !!(a.compareDocumentPosition(b) & 16);
}
var Bind = función (objeto, diversión) {
var args = Array.prototype.slice.call(argumentos, 2);
función de retorno() {
return fun.apply(object, args.concat(Array.prototype.slice.call(argumentos)));
}
}
var BindAsEventListener = función (objeto, diversión) {
var args = Array.prototype.slice.call(argumentos, 2);
función de retorno (evento) {
return fun.apply(objeto, [evento].concat(args));
}
}
var Consejos Fijos = función(consejo, opciones){
this.Tip = $$(tip);//Cuadro de aviso
this._trigger = null;//Objeto desencadenante
this._timer = null;//Temporizador
this._cssTip = this.Tip.style;//Código simplificado
this._onshow = false;//Registra el estado de visualización actual
this.SetOptions(opciones);
//Objeto de sugerencia de proceso
this._cssTip.margin = 0;//Evitar problemas de posicionamiento
this._cssTip.position = "absoluto";
this._cssTip.visibility = "oculto";
this._cssTip.display = "bloquear";
this._cssTip.zIndex = 99;
this._cssTip.left = this._cssTip.top = "-9999px";//Evitar las barras de desplazamiento en el marcador de posición
//parámetros de corrección de compensación
var iLeft = iTop = 0, p = this.Tip;
mientras (p.offsetParent) {
p = p.offsetParent; iLeft += p.offsetLeft;
};
this._offsetleft = iLeft;
this._offsettop = iTop;
//Seguir mostrándose al pasar al objeto Tip
addEvent(this.Tip, "mouseover", BindAsEventListener(this, function(e){
// Si ingresa un elemento externo, significa que actualmente se encuentra en la etapa de retraso de ocultación, luego borre el temporizador para cancelar la ocultación.
this.Check(e. relatedTarget) && clearTimeout(this._timer);
}));
//ie6 maneja la selección
si (es IE6) {
this._iframe = document.createElement("<iframe style='position:absolute;filter:alpha(opacity=0);display:none;'>");
document.body.insertBefore(this._iframe, document.body.childNodes[0]);
};
//Se utiliza para ocultar haciendo clic
this._fCH = BindAsEventListener(esto, función(e) {
si (this.Check(e.target) && this.CheckHide()) {
this.ReadyHide(this._trigger.ClickHideDelay);
};
});
//Se utiliza para activar el método para ocultar
this._fTH = BindAsEventListener(esto, función(e) {
if (this.Check(e. relatedTarget) && this.CheckHide()) {
this.ReadyHide(this._trigger.TouchHideDelay);
};
});
};
Consejos fijos.prototipo = {
_doc: document.documentElement, // Simplifica el código
//Establecer propiedades predeterminadas
Establecer Opciones: función (opciones) {
this.options = {//Valor predeterminado
ClickShow: verdadero,//Si se muestra en modo clic
ClickShowDelay: false // Si el clic muestra retraso
ClickHide: verdadero, // Si el modo de clic está oculto
ClickHideDelay: false // Si se debe hacer clic para ocultar el retraso
TouchShow: verdadero, // Si se muestra el modo de disparo
TouchShowDelay: verdadero, // Ya sea para activar el retraso de visualización
TouchHide: verdadero, // Si el modo de disparo está oculto
TouchHideDelay: verdadero, // Si se activa el retraso de ocultación
ShowDelay: 300,//Mostrar tiempo de retardo
HideDelay: 300,//Ocultar tiempo de retraso
Alinear: "clientleft", // Posicionamiento horizontal
vAlign: "clienttop", // posicionamiento vertical
Personalizado: {izquierda: 0, arriba: 0}, // Posicionamiento personalizado
Porcentaje: {izquierda: 0, arriba: 0},//Posicionamiento porcentual personalizado
Adaptativo: falso // Ya sea para posicionamiento adaptativo
Restablecer: falso // Si reposicionar durante el posicionamiento adaptativo
onShow: function(){},//Ejecutar al mostrar
onHide: function(){}//Ejecutado cuando está oculto
};
Extender(this.options, options || {});
},
//Comprueba el elemento desencadenante
Verificar: función (elem) {
// Devuelve si es un elemento externo (es decir, un objeto de elemento distinto del elemento desencadenante y el objeto Tip en sí y sus elementos internos)
devolver !this._trigger ||
!(
this.Tip === elem || this._trigger.Elem === elem ||
Contiene(this.Tip, elem) || Contiene(this._trigger.Elem, elem)
);
},
//Listo para mostrar
ReadyShow: función (retraso) {
clearTimeout(this._timer);
var disparador = this._trigger;
//Haga clic para ocultar
trigger.ClickHide && addEvent(documento, "clic", this._fCH);
//Modo de disparo oculto
trigger.TouchHide && addEvent(this._trigger.Elem, "mouseout", this._fTH);
//Si retrasar la activación
si (retraso) {
this._timer = setTimeout(Bind(this, this.Show), trigger.ShowDelay);
} más { this.Show();
},
//espectáculo
Mostrar: función() {
clearTimeout(this._timer);
this._trigger.onShow();//Póngalo al frente para modificar fácilmente los atributos
//Calcular la izquierda y la parte superior según el posicionamiento preestablecido y el posicionamiento personalizado
var disparador = this._trigger, rect = disparador.Elem.getBoundingClientRect(),
scrolldoc = esChrome || esSafari? documento.body: this._doc,
scrollLeft = scrolldoc.scrollLeft, scrollTop = scrolldoc.scrollTop,
personalizadoIzquierda = disparador.Personalizado.izquierda, personalizadoTop = disparador.Personalizado.arriba,
iLeft = this.GetLeft(rect, trigger.Align) + customLeft,
iTop = this.GetTop(rect, trigger.vAlign) + customTop;
//Posicionamiento porcentual personalizado
if (trigger.Percent.left) { iLeft += .01 * trigger.Percent.left * trigger.Elem.offsetWidth };
if (trigger.Percent.top) { iTop += .01 * trigger.Percent.top * trigger.Elem.offsetHeight };
//Posicionamiento de ventana adaptable
si (disparador.Adaptable) {
//Parámetros de posicionamiento correctos
var maxLeft = this._doc.clientWidth - this.Tip.offsetWidth,
maxTop = this._doc.clientHeight - this.Tip.offsetHeight;
si (trigger.Reset) {
//Reposicionamiento automático
if (iLeft > maxLeft || iLeft < 0) {
iLeft = this.GetLeft(rect, 2 * iLeft > maxLeft? "izquierda": "derecha") + customLeft;
};
si (iTop > maxTop || iTop < 0) {
iTop = this.GetTop(rect, 2 * iTop > maxTop ? "arriba": "abajo") + customTop;
};
} demás {
//Corregir a la posición apropiada
iLeft = Math.max(Math.min(iLeft, maxLeft), 0);
iTop = Math.max(Math.min(iTop, maxTop), 0);
};
};
//Establecer posición y visualización
this._cssTip.left = iLeft + scrollLeft - this._offsetleft + "px";
this._cssTip.top = iTop + scrollTop - this._offsettop + "px";
this._cssTip.visibility = "visible";
//ie6 maneja la selección
si (es IE6) {
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 = "";
};
//Modo de disparo oculto
trigger.TouchHide && addEvent(this.Tip, "mouseout", this._fTH);
},
//Obtiene la izquierda del elemento disparador relativo
GetLeft: función (rectificar, alinear) {
cambiar (align.toLowerCase()) {
caso "izquierda":
return rect.left - this.Tip.offsetWidth;
caso "clienteizquierdo":
volver recto.izquierdo;
caso "centro":
return (rect.izquierda + rect.derecha - this.Tip.offsetWidth)/2;
caso "derecho del cliente":
return rect.right - this.Tip.offsetWidth;
caso "correcto":
por defecto :
volver a la derecha;
};
},
//Obtener la parte superior relativa al elemento desencadenante
GetTop: función (rect, valign) {
cambiar (valign.toLowerCase()) {
caso "arriba":
devolver rect.top - this.Tip.offsetHeight;
caso "cliente superior":
devolver rect.top;
caso "centro":
return (rect.top + rect.bottom - this.Tip.offsetHeight)/2;
caso "cliente inferior":
devolver rect.bottom - this.Tip.offsetHeight;
caso "abajo":
por defecto :
devolver rect.bottom;
};
},
//Prepárate para esconderte
ReadyHide: función (retraso) {
clearTimeout(this._timer);
si (retraso) {
this._timer = setTimeout(Bind(this, this.Hide), this._trigger.HideDelay);
} más { this.Hide();
},
//esconder
Ocultar: función() {
clearTimeout(this._timer);
//Configurar para ocultar
this._cssTip.visibility = "oculto";
this._cssTip.left = this._cssTip.top = "-9999px";
//ie6 maneja la selección
if (isIE6) { this._iframe.style.display = "ninguno" };
//Objeto desencadenante del proceso
si (!!this._trigger) {
this._trigger.onHide();
removeEvent(this._trigger.Elem, "mouseout", this._fTH);
}
this._trigger = nulo;
//eliminar evento
removeEvent(this.Tip, "mouseout", this._fTH);
removeEvent(documento, "hacer clic", this._fCH);
},
//Agregar objeto desencadenante
Agregar: función (elem, opciones) {
//Crear un objeto desencadenante
var elem = $$(elem), disparador = Extender(Extender({ Elem: elem }, this.options), opciones || {});
//Haga clic para mostrar
addEvent(elem, "hacer clic", BindAsEventListener(este, función(e){
si (trigger.ClickShow) {
si (this.CheckShow(trigger)) {
this.ReadyShow(trigger.ClickShowDelay);
} demás {
clearTimeout(this._timer);
};
};
}));
// Visualización del modo de disparo
addEvent(elem, "mouseover", BindAsEventListener(esto, función(e){
si (trigger.TouchShow) {
si (this.CheckShow(trigger)) {
this.ReadyShow(trigger.TouchShowDelay);
} else if (this.Check(e. relatedTarget)) {
clearTimeout(this._timer);
};
};
}));
//devuelve el objeto activador
disparador de retorno;
},
//Mostrar cheque
CheckShow: función (activador) {
si (disparador! == this._trigger) {
// Si no es el mismo objeto desencadenante, ejecute Ocultar primero para evitar conflictos.
this.Hide(); this._trigger = disparador; devuelve verdadero;
} más {retornar falso};
},
//ocultar verificación
ComprobarOcultar: función() {
if (this._cssTip.visibility === "oculto") {
// Originalmente es un estado oculto, ya no es necesario ejecutar Ocultar
clearTimeout(this._timer);
removeEvent(this._trigger.Elem, "mouseout", this._fTH);
this._trigger = nulo;
removeEvent(documento, "hacer clic", this._fCH);
devolver falso;
} más { devolver verdadero };
}
};
</script>
</cabeza>
<cuerpo>
<estilo>
.trigger{borde:1px sólido #003099; color:#003099; fondo:#e2e7ff; relleno:10px; ancho:200px;alto:100px;
.tip{borde:1px sólido #c00000; color:#c00000; fondo:#ffcccc;
</estilo>
<div estilo="relleno:50px;">
<div id="idTip" class="tip"></div>
<div id="idTrigger1" clase="trigger">
<seleccionar>
<opción>prueba</opción>
</seleccionar>
</div>
<br>
posición horizontal:
<etiqueta>
<nombre de entrada="nAlign" tipo="radio" valor="izquierda" />
izquierda </etiqueta>
<etiqueta>
<nombre de entrada="nAlign" tipo="radio" valor="clienteizquierdo" />
cliente izquierdo </label>
<etiqueta>
<nombre de entrada="nAlign" tipo="radio" valor="centro" />
centro </etiqueta>
<etiqueta>
<nombre de entrada="nAlign" tipo="radio" valor="derecho de cliente" />
derecho de cliente </label>
<etiqueta>
<nombre de entrada="nAlign" tipo="radio" valor="derecho" marcado="marcado" />
derecha </etiqueta>
<br>
Posición vertical:
<etiqueta>
<nombre de entrada="nVAlign" tipo="radio" valor="arriba" />
arriba </etiqueta>
<etiqueta>
<nombre de entrada="nVAlign" tipo="radio" valor="clienttop" />
parte superior del cliente </label>
<etiqueta>
<nombre de entrada="nVAlign" tipo="radio" valor="centro" />
centro </etiqueta>
<etiqueta>
<nombre de entrada="nVAlign" tipo="radio" valor="clientbottom" />
parte inferior del cliente </label>
<etiqueta>
<nombre de entrada="nVAlign" tipo="radio" valor="inferior" marcado="marcado" />
abajo </etiqueta>
<br>
<br>
Orientación personalizada:
izquierda:
<entrada id="idLeft" tipo="texto" tamaño="5" valor="0" longitud máxima="3" />
arriba:
<entrada id="idTop" tipo="texto" tamaño="5" valor="0" maxlength="3"/>
<br>
<br>
<input id="idClick" tipo="casilla de verificación" marcada="marcada" />
<label for="idClick">Método de clic</label>
<input id="idTouch" tipo="casilla de verificación" marcada="marcada" />
<label for="idTouch">Método de activación</label>
<br>
<br>
Tiempo de retraso:
<entrada id="idDelayTime" tipo="texto" tamaño="5" valor="0" maxlength="4"/>
<input id="idDelay" tipo="botón" valor="Cancelar retraso" />
<br>
<br>
Otros ejemplos de aplicación: <br>
<br>
<div id="idTest1"> Usar título: <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/11/17/1334778.html " title="Efecto de arrastrar y soltar"> Arrastrar y suelte Efecto</a> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/12/03/1346386.html " title="Efecto de arrastrar y acercar"> Arrastrar y acercar Efecto</a > <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/07/21/1247267.html " title="Efecto de corte de imagen"> Efecto de corte de imagen</a > </div>
<br>
<br>
Efectos de visualización de avatar populares: <br>
<br>
<div id="idTest2"> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/07/06/1236770.html " title="Efecto de cambio de deslizamiento de imagen"> <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="Efecto de transformación de imagen"><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="Efecto de visualización deslizante de imagen"><img src="/articleimg/2009/07/6852/r_mx3.jpg " borde="0"/></a> </div>
<br>
<br>
Botón Cerrar: <a id="idTest3" href=" http://www.cnblogs.com/cloudgamer/archive/2009/05/18/TableFixed.html">Efecto de posicionamiento de fila de tabla </a>
</div>
<guión>
var paraCada = función (matriz, devolución de llamada, esteObjeto){
si (matriz.para cada uno) {
array.forEach(devolución de llamada, esteObjeto);
}demás{
for (var i = 0, len = array.length; i < len; i++) { callback.call(thisObject, array[i], i, array }
}
}
//////////////////////////////////////////
var ft = nuevos consejos fijos ("idTip");
//////////////////////////////////////////
var disparador1 = ft.Add("idTrigger1", {
enMostrar: función(){
//prueba de posicionamiento
var sAlign = this.Align, sVAlign = this.vAlign;
forEach(document.getElementsByName("nAlign"), función(o){ if(o.checked){ sAlign = o.value; } });
forEach(document.getElementsByName("nVAlign"), función(o){ if(o.checked){ sVAlign = o.value; } });
this.Align = sAlign;
this.vAlign = sVAlign;
this.Custom.left = $$("idLeft").valor 0;
this.Custom.top = $$("idTop").valor 0;
trigger1.ShowDelay = trigger1.HideDelay = $$("idDelayTime").valor 0 ||
ft.Tip.innerHTML = sAlign + "<br>" + sVAlign + "<br>" + "izquierda: " + this.Custom.left + ", arriba: " + this.Custom.top;
}
});
//prueba de retraso
$$("idDelayTime").value = disparador1.ShowDelay;
$$("idDelay").onclick = función(){
si(trigger1.TouchShowDelay){
disparador1.ClickShowDelay = disparador1.ClickHideDelay =
trigger1.TouchShowDelay = trigger1.TouchHideDelay = falso;
$$("idDelayTime").disabled = verdadero;
this.value = "Establecer retraso";
}demás{
disparador1.ClickShowDelay = disparador1.ClickHideDelay =
trigger1.TouchShowDelay = trigger1.TouchHideDelay = verdadero;
$$("idDelayTime").disabled = falso;
this.value = "Cancelar retraso";
}
}
//prueba del método
$$("idClick").onclick = función(){
trigger1.ClickShow = trigger1.ClickHide = this.checked;
}
$$("idTouch").onclick = función(){
trigger1.TouchShow = trigger1.TouchHide = this.checked;
}
///////////////////////////////////////////
forEach($$("idTest1").getElementsByTagName("a"), función(o){
var título = o.título; o.título = "";
ft.Add(o, { vAlign: "abajo", Porcentaje: { izquierda: 50, arriba: 0 }, onShow: function(){ ft.Tip.innerHTML = título; } });
})
///////////////////////////////////////////
forEach($$("idTest2").getElementsByTagName("a"), función(o){
var img = o.getElementsByTagName("img")[0], título = o.title;
o.título = "";
ft.Add(img, {Personalizado: {izquierda: -6, arriba: -6},
enMostrar: función(){
var str = '<a href="' + o.href + '"><img src="' + img.src + '" style="padding-bottom:5px;" border="0"/></ a>';
str += '<br /><a href="' + o.href + '">' + título + '</a>';
ft.Tip.innerHTML = str;
}
});
})
///////////////////////////////////////////
ft.Add("idTest3", { ClickHide: falso, TouchHide: falso, Alinear: "derecha",
enMostrar: función(){
var str = ' <a href=" http://www.cnblogs.com/cloudgamer/archive/2009/03/11/1408333.html "> Degradado de color y efectos de degradado</a><br />';
str += ' <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/10/20/1314766.html "> Disco de red de imitación 163 sin sistema de carga de archivos actualizado</a><br / >';
str += '<tipo de entrada="botón" onclick="ft.Hide();" valor="Haga clic para cerrar" />';
ft.Tip.innerHTML = str;
}
});
</script>
</cuerpo>
</html>
JavaScript, posicionamiento, flotante, sugerencias, información sobre herramientas, FixedTips, Tip
Descripción del programa
Objeto de sugerencia :
El objeto Tip es un contenedor que se utiliza para mostrar información de solicitud y el programa está representado por el atributo Tip. No hay requisitos para esto, se realizarán algunas configuraciones cuando se inicialice el programa.
Primero realice las siguientes configuraciones:
this._cssTip.margin = 0;
this._cssTip.position = "absoluto";
this._cssTip.visibility = "oculto";
this._cssTip.display = "bloquear";
this._cssTip.zIndex = 99;
this._cssTip.left = this._cssTip.top = "-9999px";
El margen se establece en 0 para evitar algunos problemas de posicionamiento. La visibilidad se usa para ocultar en lugar de mostrar porque el programa necesita obtener el ancho y la altura del desplazamiento de la punta. También debe configurarse hacia la izquierda y hacia arriba para evitar que aparezca la barra de desplazamiento. la punta ocupando el espacio.
Debido a que Tip puede estar dentro de otros elementos posicionados, se deben establecer dos parámetros de corrección de desplazamiento:
var iLeft = iTop = 0, p = this.Tip.offsetParent;
while (!(p === documento.cuerpo || p === documento.documentElement)) {
iLeft += p.offsetLeft; iTop += p.offsetTop;
};
this._offsetleft = iLeft;
this._offsettop = iTop;
Finalmente, agregue un evento al pasar el mouse sobre Tip, que se explicará más adelante.