À l'origine, je voulais créer un effet d'info-bulle combinant le positionnement flottant et le suivi de la souris, mais j'ai trouvé que le positionnement et le suivi de la souris sont encore différents à certains endroits clés, nous devrions donc le faire séparément.
Cet effet en lui-même n'est pas très difficile. Nous avons principalement consacré des efforts à la structure et à l'expansion du programme pour le rendre plus pratique à utiliser et pouvoir être utilisé dans plus d'endroits.
Caractéristiques du programme
Exemple complet de téléchargement (cliquez pour télécharger)
<!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 ">
<tête>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>Effet d'invite de positionnement flottant JavaScript</title>
<script>
var $$ = fonction (id) {
return "string" == type d'identifiant ? 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;
// avec la contribution de Tino Zijdel, Matthias Miller, Diego Perini
// http://dean.edwards.name/weblog/2005/10/add-event/
function addEvent (élément, type, gestionnaire) {
si (element.addEventListener) {
element.addEventListener(type, gestionnaire, false);
} autre {
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
si (!element.events) element.events = {};
var gestionnaires = element.events[type];
si (!gestionnaires) {
gestionnaires = element.events[type] = {};
if (élément["on" + type]) {
gestionnaires[0] = élément["on" + type];
}
}
gestionnaires[handler.$$guid] = gestionnaire;
element["on" + type] = handleEvent;
}
} ;
addEvent.guid = 1;
function removeEvent (élément, type, gestionnaire) {
si (element.removeEventListener) {
element.removeEventListener(type, gestionnaire, false);
} autre {
if (element.events && element.events[type]) {
supprimer element.events[type][handler.$$guid] ;
}
}
} ;
fonction handleEvent (événement) {
var returnValue = vrai ;
event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
var gestionnaires = this.events[event.type];
pour (var i dans les gestionnaires) {
this.$$handleEvent = gestionnaires[i];
if (this.$$handleEvent(event) === false) {
returnValue = faux ;
}
}
retourner valeur de retour ;
} ;
fonction fixEvent (événement) {
event.target = event.srcElement;
if(event.type == "mouseout") {
event.ratedTarget = event.toElement;
}else if(event.type == "mouseover") {
event.ratedTarget = event.fromElement;
}
événement de retour ;
} ;
var Extend = fonction (destination, source) {
pour (propriété var dans la source) {
destination[propriété] = source[propriété];
}
destination de retour ;
}
var Contient = function(a, b){
return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
}
var Bind = fonction (objet, amusant) {
var args = Array.prototype.slice.call(arguments, 2);
fonction de retour() {
return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}
var BindAsEventListener = fonction (objet, amusant) {
var args = Array.prototype.slice.call(arguments, 2);
fonction de retour (événement) {
return fun.apply(object, [event].concat(args));
}
}
var FixeTips = fonction (astuce, options) {
this.Tip = $$(tip);//Boîte d'invite
this._trigger = null;//Objet déclencheur
this._timer = null;//Minuterie
this._cssTip = this.Tip.style;//Code simplifié
this._onshow = false;//Enregistrer l'état d'affichage actuel
this.SetOptions(options);
//Objet Astuce de processus
this._cssTip.margin = 0;//Éviter les problèmes de positionnement
this._cssTip.position = "absolu" ;
this._cssTip.visibility = "caché" ;
this._cssTip.display = "bloquer" ;
this._cssTip.zIndex = 99 ;
this._cssTip.left = this._cssTip.top = "-9999px";//Éviter les barres de défilement dans l'espace réservé
//paramètres de correction de décalage
var iLeft = iTop = 0, p = this.Tip;
tandis que (p.offsetParent) {
p = p.offsetParent; iLeft += p.offsetLeft;
} ;
this._offsetleft = iLeft ;
this._offsettop = iTop ;
//Continue à afficher lors du passage dans l'objet Tip
addEvent(this.Tip, "mouseover", BindAsEventListener(this, function(e){
//Si un élément externe entre, cela signifie qu'il est actuellement en phase de délai de masquage, puis effacez le minuteur pour annuler le masquage.
this.Check(e.ratedTarget) && clearTimeout(this._timer);
}));
//ie6 gère la sélection
si (estIE6) {
this._iframe = document.createElement("<iframe style='position:absolute;filter:alpha(opacity=0);display:none;'>");
document.body.insertBefore(this._iframe, document.body.childNodes[0]);
} ;
//Utilisé pour se cacher en cliquant
this._fCH = BindAsEventListener(this, function(e) {
if (this.Check(e.target) && this.CheckHide()) {
this.ReadyHide(this._trigger.ClickHideDelay);
} ;
});
//Utilisé pour déclencher la méthode de masquage
this._fTH = BindAsEventListener(this, function(e) {
if (this.Check(e.ratedTarget) && this.CheckHide()) {
this.ReadyHide(this._trigger.TouchHideDelay);
} ;
});
} ;
FixesTips.prototype = {
_doc : document.documentElement,//Simplifier le code
//Définir les propriétés par défaut
SetOptions : fonction (options) {
this.options = {//Valeur par défaut
ClickShow : true,//S'il faut afficher en mode clic
ClickShowDelay : false, // Si le délai d'affichage du clic
ClickHide : true,//Si le mode clic est masqué
ClickHideDelay : false,//S'il faut cliquer pour masquer le délai
TouchShow : true,//Si le mode de déclenchement est affiché
TouchShowDelay : true,//S'il faut déclencher le délai d'affichage
TouchHide : true,//Si le mode de déclenchement est masqué
TouchHideDelay : true,//S'il faut déclencher le délai de masquage
ShowDelay : 300,//Délai d'affichage
HideDelay : 300,//Masquer le temps de retard
Aligner : "clientleft",//Positionnement horizontal
vAlign : "clienttop",//positionnement vertical
Personnalisé : {gauche : 0, haut : 0 },//Positionnement personnalisé
Pourcentage : {gauche : 0, haut : 0 },//Positionnement en pourcentage personnalisé
Adaptatif : faux,//S'il s'agit d'un positionnement adaptatif
Réinitialisation : faux,//S'il faut repositionner pendant le positionnement adaptatif
onShow : function(){},//Exécuter lors de l'affichage
onHide : function(){}//Exécuté lorsqu'il est masqué
} ;
Étendre(this.options, options || {});
},
//Vérifie l'élément déclencheur
Vérifier : fonction (élément) {
//Renvoie s'il s'agit d'un élément externe (c'est-à-dire un objet élément autre que l'élément déclencheur et l'objet Tip lui-même et ses éléments internes)
retourner !this._trigger ||
!(
this.Tip === elem || this._trigger.Elem === elem ||
Contient(this.Tip, elem) || Contient(this._trigger.Elem, elem)
);
},
//Prêt à afficher
ReadyShow : fonction (délai) {
clearTimeout(this._timer);
var trigger = this._trigger;
//Cliquez pour masquer
trigger.ClickHide && addEvent(document, "click", this._fCH);
//Mode déclencheur masqué
trigger.TouchHide && addEvent(this._trigger.Elem, "mouseout", this._fTH);
//S'il faut retarder le déclenchement
si (délai) {
this._timer = setTimeout(Bind(this, this.Show), trigger.ShowDelay);
} else { this.Show();
},
//montrer
Afficher : fonction() {
clearTimeout(this._timer);
this._trigger.onShow();//Placez-le devant pour faciliter la modification des attributs
//Calculer la gauche et le haut en fonction du positionnement prédéfini et du positionnement personnalisé
var trigger = this._trigger, rect = 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(rect, trigger.Align) + customLeft,
iTop = this.GetTop(rect, trigger.vAlign) + customTop ;
//Positionnement en pourcentage personnalisé
if (trigger.Percent.left) { iLeft += .01 * trigger.Percent.left * trigger.Elem.offsetWidth } ;
if (trigger.Percent.top) { iTop += .01 * trigger.Percent.top * trigger.Elem.offsetHeight } ;
//Positionnement adaptatif de la fenêtre
if (trigger.Adaptive) {
// Paramètres de positionnement corrects
var maxLeft = this._doc.clientWidth - this.Tip.offsetWidth,
maxTop = this._doc.clientHeight - this.Tip.offsetHeight ;
if (trigger.Reset) {
//Repositionnement automatique
si (iLeft > maxLeft || iLeft < 0) {
iLeft = this.GetLeft(rect, 2 * iLeft > maxLeft ? "left" : "right") + customLeft;
} ;
si (iTop > maxTop || iTop < 0) {
iTop = this.GetTop(rect, 2 * iTop > maxTop ? "top" : "bottom") + customTop;
} ;
} autre {
//Corriger à la position appropriée
iLeft = Math.max(Math.min(iLeft, maxLeft), 0);
iTop = Math.max(Math.min(iTop, maxTop), 0);
} ;
} ;
//Définir la position et l'affichage
this._cssTip.left = iLeft + scrollLeft - this._offsetleft + "px" ;
this._cssTip.top = iTop + scrollTop - this._offsettop + "px" ;
this._cssTip.visibility = "visible";
//ie6 gère la sélection
si (estIE6) {
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 = "";
} ;
//Mode déclencheur masqué
trigger.TouchHide && addEvent(this.Tip, "mouseout", this._fTH);
},
//Obtenir la gauche de l'élément déclencheur relatif
GetLeft : fonction (rect, aligner) {
commutateur (align.toLowerCase()) {
cas "gauche" :
return rect.left - this.Tip.offsetWidth ;
cas "clientleft" :
retourner rect.gauche ;
cas "centre" :
return (rect.left + rect.right - this.Tip.offsetWidth)/2;
cas "droit client" :
return rect.right - this.Tip.offsetWidth ;
cas "correct" :
défaut :
retourner rect.droit ;
} ;
},
//Obtenir le haut par rapport à l'élément déclencheur
GetTop : fonction (rect, valign) {
commutateur (valign.toLowerCase()) {
cas "haut" :
return rect.top - this.Tip.offsetHeight ;
cas "clienttop" :
retourner rect.top ;
cas "centre" :
return (rect.top + rect.bottom - this.Tip.offsetHeight)/2;
cas "clientbottom" :
return rect.bottom - this.Tip.offsetHeight ;
cas "en bas" :
défaut :
retourner rect.bottom;
} ;
},
//Préparez-vous à vous cacher
ReadyHide : fonction (délai) {
clearTimeout(this._timer);
si (délai) {
this._timer = setTimeout(Bind(this, this.Hide), this._trigger.HideDelay);
} else { this.Hide();
},
//cacher
Masquer : fonction() {
clearTimeout(this._timer);
//Configuré pour se cacher
this._cssTip.visibility = "caché" ;
this._cssTip.left = this._cssTip.top = "-9999px";
//ie6 gère la sélection
if (isIE6) { this._iframe.style.display = "aucun" } ;
//Objet déclencheur de processus
si (!!this._trigger) {
this._trigger.onHide();
RemoveEvent(this._trigger.Elem, "mouseout", this._fTH);
}
this._trigger = null ;
//supprimer l'événement
RemoveEvent(this.Tip, "mouseout", this._fTH);
RemoveEvent(document, "clic", this._fCH);
},
//Ajouter un objet déclencheur
Ajouter : fonction (élément, options) {
//Créer un objet déclencheur
var elem = $$(elem), trigger = Extend(Extend({ Elem: elem }, this.options), options || {});
//Cliquez pour afficher
addEvent(elem, "clic", BindAsEventListener(this, function(e){
si (trigger.ClickShow) {
if (this.CheckShow(trigger)) {
this.ReadyShow(trigger.ClickShowDelay);
} autre {
clearTimeout(this._timer);
} ;
} ;
}));
//Affichage du mode de déclenchement
addEvent(elem, "mouseover", BindAsEventListener(this, function(e){
si (trigger.TouchShow) {
if (this.CheckShow(trigger)) {
this.ReadyShow(trigger.TouchShowDelay);
} sinon if (this.Check(e.ratedTarget)) {
clearTimeout(this._timer);
} ;
} ;
}));
//retourne l'objet déclencheur
déclencheur de retour ;
},
//Afficher le chèque
CheckShow : fonction (déclencheur) {
if (trigger !== this._trigger) {
// S'il ne s'agit pas du même objet déclencheur, exécutez d'abord Hide pour éviter les conflits.
this.Hide(); this._trigger = déclencheur ;
} autre { return false } ;
},
//masquer le chèque
CheckHide : fonction() {
if (this._cssTip.visibility === "caché") {
//C'est à l'origine un état caché, plus besoin d'exécuter Hide
clearTimeout(this._timer);
RemoveEvent(this._trigger.Elem, "mouseout", this._fTH);
this._trigger = null ;
RemoveEvent(document, "clic", this._fCH);
renvoie faux ;
} else { return vrai } ;
}
} ;
</script>
</tête>
<corps>
<style>
.trigger{border:1px solid #003099; couleur:#003099; background:#e2e7ff; padding:10px width:200px height:100px;
.tip{border:1px solid #c00000; couleur:#c00000; background:#ffcccc; padding:5px;
</style>
<div style="padding:50px;">
<div id="idTip" class="tip"></div>
<div id="idTrigger1" class="trigger">
<sélectionner>
<option>tester</option>
</sélectionner>
</div>
<br>
position horizontale :
<étiquette>
<input name="nAlign" type="radio" value="left" />
gauche </label>
<étiquette>
<input name="nAlign" type="radio" value="clientleft" />
clientgauche </label>
<étiquette>
<input name="nAlign" type="radio" value="center" />
centre </label>
<étiquette>
<input name="nAlign" type="radio" value="clientright" />
droit du client </label>
<étiquette>
<input name="nAlign" type="radio" value="right" vérifié="checked" />
à droite </label>
<br>
Position verticale :
<étiquette>
<input name="nVALign" type="radio" value="top" />
haut </label>
<étiquette>
<input name="nVALign" type="radio" value="clienttop" />
espace client </label>
<étiquette>
<input name="nVALign" type="radio" value="center" />
centre </label>
<étiquette>
<input name="nVALign" type="radio" value="clientbottom" />
clientbottom </label>
<étiquette>
<input name="nVALign" type="radio" value="bottom" vérifié="checked" />
en bas </label>
<br>
<br>
Ciblage personnalisé :
gauche:
<input id="idLeft" type="text" size="5" value="0" maxlength="3" />
haut:
<input id="idTop" type="text" size="5" value="0" maxlength="3"/>
<br>
<br>
<input id="idClick" type="checkbox" vérifié="checked" />
<label for="idClick">Méthode Click</label>
<input id="idTouch" type="checkbox" vérifié="checked" />
<label for="idTouch">Méthode de déclenchement</label>
<br>
<br>
Temps de retard :
<input id="idDelayTime" type="text" size="5" value="0" maxlength="4"/>
<input id="idDelay" type="button" value="Annuler le délai" />
<br>
<br>
Autres exemples d'application : <br>
<br>
<div id="idTest1"> Utiliser le titre : <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/11/17/1334778.html " title="Effet glisser-déposer"> Faire glisser et déposez l'effet</a> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/12/03/1346386.html " title="Effet glisser-zoomer"> Faites glisser et zoomez Effet</a > <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/07/21/1247267.html " title="Effet de coupe d'image"> Effet de coupe d'image</a > </div >
<br>
<br>
Effets d'affichage d'avatar populaires : <br>
<br>
<div id="idTest2"> <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/07/06/1236770.html " title="Effet de commutation coulissante d'image"> <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="Effet de transformation d'image"><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="Effet d'affichage coulissant d'image"><img src="/articleimg/2009/07/6852/r_mx3.jpg " border="0"/></a> </div>
<br>
<br>
Bouton Fermer : <a id="idTest3" href=" http://www.cnblogs.com/cloudgamer/archive/2009/05/18/TableFixed.html">Effet de positionnement des lignes du tableau </a>
</div>
<script>
var forEach = function(array, callback, thisObject){
si(array.forEach){
array.forEach(callback, thisObject);
}autre{
for (var i = 0, len = array.length; i < len; i++) { callback.call(thisObject, array[i], i, array });
}
}
///////////////////////////////////////
var ft = new FixeTips("idTip");
///////////////////////////////////////
var trigger1 = ft.Add("idTrigger1", {
onShow : fonction(){
//test de positionnement
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 0 || 300;
ft.Tip.innerHTML = sAlign + "<br>" + sVAlign + "<br>" + "left : " + this.Custom.left + ", top : " + this.Custom.top ;
}
});
//test de retard
$$("idDelayTime").value = trigger1.ShowDelay;
$$("idDelay").onclick = function(){
si (trigger1.TouchShowDelay) {
trigger1.ClickShowDelay = trigger1.ClickHideDelay =
trigger1.TouchShowDelay = trigger1.TouchHideDelay = false ;
$$("idDelayTime").disabled = true;
this.value = "Définir le délai" ;
}autre{
trigger1.ClickShowDelay = trigger1.ClickHideDelay =
trigger1.TouchShowDelay = trigger1.TouchHideDelay = true ;
$$("idDelayTime").disabled = false;
this.value = "Annuler le délai" ;
}
}
//test de méthode
$$("idClick").onclick = function(){
trigger1.ClickShow = trigger1.ClickHide = this.checked;
}
$$("idTouch").onclick = function(){
trigger1.TouchShow = trigger1.TouchHide = this.checked;
}
////////////////////////////////////////
forEach($$("idTest1").getElementsByTagName("a"), function(o){
var titre = o.titre; o.titre = "";
ft.Add(o, { vAlign : "bottom", Pourcentage : { gauche : 50, haut : 0 }, onShow : function(){ ft.Tip.innerHTML = title; } });
})
////////////////////////////////////////
forEach($$("idTest2").getElementsByTagName("a"), function(o){
var img = o.getElementsByTagName("img")[0], title = o.title;
o.titre = "" ;
ft.Add(img, { Personnalisé : { gauche : -6, haut : -6 },
onShow : fonction(){
var str = '<a href="' + o.href + '"><img src="' + img.src + '" style="padding-bottom:5px;" border="0"/></ un>';
str += '<br /><a href="' + o.href + '">' + titre + '</a>';
ft.Tip.innerHTML = str;
}
});
})
////////////////////////////////////////
ft.Add("idTest3", { ClickHide : false, TouchHide : false, Align : "right",
onShow : fonction(){
var str = ' <a href=" http://www.cnblogs.com/cloudgamer/archive/2009/03/11/1408333.html "> Dégradé de couleurs et effets de dégradé</a><br />';
str += ' <a href=" http://www.cnblogs.com/cloudgamer/archive/2008/10/20/1314766.html "> Disque réseau imitation 163 sans système de téléchargement de fichiers d'actualisation</a><br / >';
str += '<input type="button" onclick="ft.Hide();" value="Cliquez pour fermer" />';
ft.Tip.innerHTML = str;
}
});
</script>
</corps>
</html>
JavaScript, positionnement, flottant, astuces, info-bulles, FixeTips, Astuce
Description du programme
Objet de l'astuce :
L'objet Tip est un conteneur utilisé pour afficher des informations d'invite et le programme est représenté par l'attribut Tip. Il n'y a aucune exigence pour cela, certains paramètres y seront apportés lors de l'initialisation du programme.
Effectuez d'abord les réglages suivants :
this._cssTip.margin = 0;
this._cssTip.position = "absolu" ;
this._cssTip.visibility = "caché" ;
this._cssTip.display = "bloquer" ;
this._cssTip.zIndex = 99 ;
this._cssTip.left = this._cssTip.top = "-9999px";
La marge est définie sur 0 pour éviter certains problèmes de positionnement. La visibilité est utilisée pour masquer au lieu d'afficher car le programme doit obtenir les valeurs offsetWidth et offsetHeight de la pointe. Il doit également être défini à gauche et en haut pour éviter que la barre de défilement n'apparaisse à cause de cela. la Pointe occupant l'espace.
Étant donné que Tip peut se trouver à l'intérieur d'autres éléments positionnés, deux paramètres de correction de décalage doivent être définis :
var iLeft = iTop = 0, p = this.Tip.offsetParent ;
while (!(p === document.body || p === document.documentElement)) {
iLeft += p.offsetLeft; iTop += p.offsetTop;
} ;
this._offsetleft = iLeft ;
this._offsettop = iTop ;
Enfin, ajoutez un événement au survol de la souris de Tip, qui sera expliqué plus tard.