2008-12-14 9 views
26

Rappelez-vous le petit div apparaissant en haut de la page pour nous informer des choses (comme les nouveaux badges)?Panneau de notification similaire à celui de stackoverflow

je voudrais mettre en œuvre quelque chose comme ça aussi et je cherche des meilleures pratiques ou modèles.

Mon site est également une application ASP.NET MVC. Idéalement, les réponses comprennent des détails comme « mettre ce dans la page principale » et « faire ce dans les contrôleurs ».

Juste pour vous éviter d'avoir à vous regarder, c'est le code que je vois le message de bienvenue que vous obtenez lorsque pas connecté à stackoverflow.

<div class="notify" style=""> 
    <span> 
    First time at Stack Overflow? Check out the 
    <a href="/messages/mark-as-read?returnurl=%2ffaq">FAQ</a>! 
    </span> 
    <a class="close-notify" onclick="notify.close(true)" title="dismiss this notification">×</a> 
</div> 

<script type="text/javascript"> 

    $().ready(function() { 
    notify.show(); 
    }); 

</script> 

Je voudrais ajouter que je comprends parfaitement cela et aussi comprendre l'implication de jquery. Je suis juste intéressé par qui met le code dans le balisage et quand ("qui" comme dans quelles entités au sein d'une application ASP.NET MVC).

Merci!

+0

Notez également que vous pouvez facilement fouiller dans ce code en utilisant: -Firebug pour Firefox -Chrome- Clic droit, "inspecter l'élément" -IE - appuyez sur f12, sélectionnez l'icône de la flèche, cliquez sur l'élément pour inspecter –

Répondre

11

Après fouiner un peu le code, voici une supposition:

Le conteneur de notification suivante est toujours dans le balisage de vue:

<div id="notify-container"> </div> 

Ce conteneur de notification est masquée par défaut, et est peuplé par javascript dans certaines circonstances. Il peut contenir n'importe quel nombre de messages.

Si l'utilisateur n'est pas connecté

persistance: Les cookies sont utilisés pour garder la trace de savoir si un message est affiché ou non.

côté serveur code généré dans la vue: Je pense que stackoverflow ne montre qu'un seul message si vous n'êtes pas connecté Le code suivant est injecté dans la vue.

<script type="text/javascript"> 
    $(function() { notify.showFirstTime(); }); 
</script> 

Le showFirstTime() La méthode javascript détermine simplement s'il faut afficher le message "Est-ce votre première fois ici?" message basé sur si un cookie a été défini ou non. S'il n'y a pas de cookie, le message est affiché. Si l'utilisateur agit, le cookie est défini et le message ne sera pas affiché dans le futur. La fonction nofity.showFirstTime() gère la vérification du cookie.

Si l'utilisateur est connecté

persistance: La base de données est utilisée pour garder une trace de savoir si un message a été montré ou non.

côté serveur code généré dans la vue: Lorsqu'une page est demandée, le code côté serveur vérifie la base de données pour voir quels messages doivent être affichés. Le code côté serveur injecte ensuite les messages au format json dans la vue et place un appel javascript à showMessages().

Par exemple, si je suis connecté en vue, je vois ce qui suit dans le balisage au SO:

<script type="text/javascript"> 
1 
2 var msgArray = [{"id":49611,"messageTypeId":8,"text":"Welcome to Super User! Visit your \u003ca href=\"https://stackoverflow.com/users/00000?tab=accounts\"\u003eaccounts tab\u003c/a\u003e to associate with our other websites!","userId":00000,"showProfile":false}]; 
3 $(function() { notify.showMessages(msgArray); }); 
4 
</script> 

Ainsi, le code côté serveur soit injecte du code pour appeler la méthode « showFirstTime » si l'utilisateur n'est pas connecté ou il injecte des messages et appelle "showMessages" pour un utilisateur connecté.

En savoir plus sur le code côté client

L'autre élément clé est le "notifier" JavaScript Module Picflight a de-minified (vous pouvez faire la même chose en utilisant YSlow pour Firebug). Le module notify gère le remplissage de la div de notification en fonction du javascript généré côté serveur.

Non connecté, côté client

Si l'utilisateur n'est pas connecté, puis gère le module des événements lorsque des des de l'utilisateur X la notification ou va à la FAQ en créant un cookie. Il détermine également si afficher le premier message en vérifiant un cookie.

vous êtes connecté, côté client

Si l'utilisateur est connecté, le module ajoute notifier tous les messages générés par le serveur dans la div de notification. Il utilise également ajax pour mettre à jour la base de données lorsqu'un utilisateur rejette un message.

4

Bien que ceux-ci ne sont nullement officiels, les pratiques communes que je suis aboutiraient à quelque chose comme ceci:

  • Créer l'élément qui agira en tant que conteneur de notification dans le balisage, mais cacher par défaut (cela peut être fait de nombreuses façons - JavaScript, CSS externe ou styles en ligne).
  • conserverez les scripts responsables du comportement de la notification en dehors du balisage. Dans l'exemple ci-dessus, vous pouvez voir qu'il y a un onclick ainsi qu'une autre fonction qui se déclenche au chargement de la page contenue dans le balisage. Bien que cela fonctionne, je vois cela comme un mélange de présentation et de comportement.
  • Conserve la présentation du message de notification contenue dans une feuille de style externe.

Encore une fois, ce ne sont que mes pratiques courantes énoncées dans le contexte de votre question. La chose avec le développement web, comme le montre la nature de votre question, c'est qu'il y a tellement de façons de faire la même chose avec les mêmes résultats.

+0

Aime également ajouter: Mettez tout le code JavaScript de notification dans un fichier .JS externe. Vous en aurez probablement une bonne partie, c'est donc bien que les utilisateurs puissent le mettre en cache. De plus, il servira bien pour l'organisation du code. –

+0

Si je peux ajouter à cela. N'oubliez pas de mettre ce .js au bas de votre structure afin qu'il ne bloque pas le téléchargement de la page jusqu'à ce que ce soit nécessaire, comme javascript bloque les téléchargements parallèles d'autres ressources externes. –

2

StackOverflow utilise jQuery - le code JS vous de SO est posté un appel jQuery. Il fera exactement ce que vous voulez avec presque aucun code. Hautement recommandé.

12

This answer a une solution complète.

Copier-coller:

C'est le balisage, d'abord caché afin que nous puissions disparaître dans:

<div id='message' style="display: none;"> 
    <span>Hey, This is my Message.</span> 
    <a href="#" class="close-notify">X</a> 
</div> 

Voici les styles appliqués:

#message { 
    font-family:Arial,Helvetica,sans-serif; 
    position:fixed; 
    top:0px; 
    left:0px; 
    width:100%; 
    z-index:105; 
    text-align:center; 
    font-weight:bold; 
    font-size:100%; 
    color:white; 
    padding:10px 0px 10px 0px; 
    background-color:#8E1609; 
} 

#message span { 
    text-align: center; 
    width: 95%; 
    float:left; 
} 

.close-notify { 
    white-space: nowrap; 
    float:right; 
    margin-right:10px; 
    color:#fff; 
    text-decoration:none; 
    border:2px #fff solid; 
    padding-left:3px; 
    padding-right:3px 
} 

.close-notify a { 
    color: #fff; 
} 

Et ceci est le javascript (en utilisant jQuery):

$(document).ready(function() { 
    $("#message").fadeIn("slow"); 
    $("#message a.close-notify").click(function() { 
     $("#message").fadeOut("slow"); 
     return false; 
    }); 
}); 

Et voilà. En fonction de la configuration de votre page, vous pouvez également modifier la marge supérieure du corps à l'écran.

Here is a demo of it in action.

+1

il y a beaucoup plus de système de notification de stackoverflow que cet exemple. Reportez-vous au code javascript déminéralisé fourni par Picflight ou utilisez la fonction "jsured" de ySlow pour voir le code client. Il y a aussi le code côté serveur impliqué ... – ckarbass

4

Je vois la fonction jQuery suivante? Je crois que cela injecte le html dans la div avec l'ID notify-container.

Je ne comprends pas comment ce JS est utilisé et appelé en fonction de certains événements, peut-être que quelqu'un peut expliquer.

var notify = function() { 
var d = false; 
var e = 0; 
var c = -1; 
var f = "m"; 
var a = function(h) { 
    if (!d) { 
     $("#notify-container").append('<table id="notify-table"></table>'); 
     d = true 
    } 
    var g = "<tr" + (h.messageTypeId ? ' id="notify-' + h.messageTypeId + '"' : ""); 
    g += ' class="notify" style="display:none"><td class="notify">' + h.text; 
    if (h.showProfile) { 
     var i = escape("https://stackoverflow.com/users/" + h.userId); 
     g += ' See your <a href="/messages/mark-as-read?messagetypeid=' + h.messageTypeId + "&returnurl=" + i + '">profile</a>.' 
    } 
    g += '</td><td class="notify-close"><a title="dismiss this notification" onclick="notify.close('; 
    g += (h.messageTypeId ? h.messageTypeId : "") + ')">&times;</a></td></tr>'; 
    $("#notify-table").append(g) 
}; 
var b = function() { 
    $.cookie("m", "-1", { 
     expires: 90, 
     path: "/" 
    }) 
}; 
return { 
    showFirstTime: function() { 
     if ($.cookie("new")) { 
      $.cookie("new", "0", { 
       expires: -1, 
       path: "/" 
      }); 
      b() 
     } 
     if ($.cookie("m")) { 
      return 
     } 
     $("body").css("margin-top", "2.5em"); 
     a({ 
      messageTypeId: c, 
      text: 'First time here? Check out the <a onclick="notify.closeFirstTime()">FAQ</a>!' 
     }); 
     $(".notify").fadeIn("slow") 
    }, 
    showMessages: function(g) { 
     for (var h = 0; h < g.length; h++) { 
      a(g[h]) 
     } 
     $(".notify").fadeIn("slow"); 
     e = g.length 
    }, 
    show: function(g) { 
     $("body").css("margin-top", "2.5em"); 
     a({ 
      text: g 
     }); 
     $(".notify").fadeIn("slow") 
    }, 
    close: function(g) { 
     var i; 
     var h = 0; 
     if (g && g != c) { 
      $.post("/messages/mark-as-read", { 
       messagetypeid: g 
      }); 
      i = $("#notify-" + g); 
      if (e > 1) { 
       h = parseInt($("body").css("margin-top").match(/\d+/)); 
       h = h - (h/e) 
      } 
     } else { 
      if (g && g == c) { 
       b() 
      } 
      i = $(".notify") 
     } 
     i.children("td").css("border-bottom", "none").end().fadeOut("fast", function() { 
      $("body").css("margin-top", h + "px"); 
      i.remove() 
     }) 
    }, 
    closeFirstTime: function() { 
     b(); 
     document.location = "/faq" 
    } 
} 
}(); 
0

J'ai écrit ce morceau de Javascript qui ne fait qu'empiler, rester avec vous pendant que vous faites défiler comme Stack Overflow fait et en poussant toute la page vers le bas chaque fois qu'une nouvelle barre est ajoutée. Les barres expirent également. Les barres glissent aussi dans l'existence.

// Show a message bar at the top of the screen to tell the user that something is going on. 
// hideAfterMS - Optional argument. When supplied it hides the bar after a set number of milliseconds. 
    function AdvancedMessageBar(hideAfterMS) { 
     // Add an element to the top of the page to hold all of these bars. 
     if ($('#barNotificationContainer').length == 0) 
     {    

     var barContainer = $('<div id="barNotificationContainer" style="width: 100%; margin: 0px; padding: 0px;"></div>'); 
     barContainer.prependTo('body'); 

     var barContainerFixed = $('<div id="barNotificationContainerFixed" style="width: 100%; position: fixed; top: 0; left: 0;"></div>'); 
     barContainerFixed.prependTo('body'); 
    } 

    this.barTopOfPage = $('<div style="margin: 0px; background: orange; width: 100%; text-align: center; display: none; font-size: 15px; font-weight: bold; border-bottom-style: solid; border-bottom-color: darkorange;"><table style="width: 100%; padding: 5px;" cellpadding="0" cellspacing="0"><tr><td style="width: 20%; font-size: 10px; font-weight: normal;" class="leftMessage" ></td><td style="width: 60%; text-align: center;" class="messageCell"></td><td class="rightMessage" style="width: 20%; font-size: 10px; font-weight: normal;"></td></tr></table></div>'); 
    this.barTopOfScreen = this.barTopOfPage.clone(); 

    this.barTopOfPage.css("background", "transparent"); 
    this.barTopOfPage.css("border-bottom-color", "transparent"); 
    this.barTopOfPage.css("color", "transparent"); 

    this.barTopOfPage.prependTo('#barNotificationContainer'); 
    this.barTopOfScreen.appendTo('#barNotificationContainerFixed'); 


    this.setBarColor = function (backgroundColor, borderColor) {  

     this.barTopOfScreen.css("background", backgroundColor); 
     this.barTopOfScreen.css("border-bottom-color", borderColor); 
    }; 

    // Sets the message in the center of the screen. 
    // leftMesage - optional 
    // rightMessage - optional 
    this.setMessage = function (message, leftMessage, rightMessage) { 
     this.barTopOfPage.find('.messageCell').html(message); 
     this.barTopOfPage.find('.leftMessage').html(leftMessage); 
     this.barTopOfPage.find('.rightMessage').html(rightMessage); 

     this.barTopOfScreen.find('.messageCell').html(message); 
     this.barTopOfScreen.find('.leftMessage').html(leftMessage); 
     this.barTopOfScreen.find('.rightMessage').html(rightMessage); 
    }; 


    this.show = function() { 
     this.barTopOfPage.slideDown(1000); 
     this.barTopOfScreen.slideDown(1000); 
    }; 

    this.hide = function() { 
     this.barTopOfPage.slideUp(1000); 
     this.barTopOfScreen.slideUp(1000); 
    }; 

    var self = this; 


    if (hideAfterMS != undefined) { 
     setTimeout(function() { self.hide(); }, hideAfterMS); 
    }  
} 

Pour l'utiliser, vous devez utiliser jQuery et assurer qu'il n'y a pas de marge ou de rembourrage sur le corps de votre page.

Le paramètre que AdvancedMessageBar prend est facultatif. Si cela est prévu, la barre disparaîtra après un certain temps en millisecondes. Si vous souhaitez les empiler, créez simplement d'autres objets AdvancedMessageBar et ils seront automatiquement empilés.

Questions connexes