代码之家  ›  专栏  ›  技术社区  ›  Rob

通知面板类似于stackoverflow

  •  26
  • Rob  · 技术社区  · 17 年前

    还记得页面顶部显示的小div,用于通知我们一些事情(比如新徽章)吗?

    我也想实现类似的东西,并正在寻找一些最佳实践或模式。

    我的网站是一个ASP。NET MVC应用程序也是如此。理想情况下,答案应包括“放 这 在母版页中“和”do 这 在控制器中”。

    为了使您不必亲自查看,这是我在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>
    

    我想补充一点,我完全理解这一点,也理解jquery的参与。我只对谁在何时将代码放入标记中感兴趣(“谁”是ASP.NET MVC应用程序中的哪些实体)。

    谢谢!

    6 回复  |  直到 14 年前
        1
  •  12
  •   Community Mohan Dere    9 年前

    This answer 有一个完整的解决方案。

    复制粘贴:

    这是标记,最初隐藏,以便我们可以淡入:

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

    以下是应用的样式:

    #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;
    }
    

    这是javascript(使用jQuery):

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

    瞧。根据您的页面设置,您可能还想编辑显示器顶部的正文边距。

    Here is a demo of it in action .

        2
  •  11
  •   ckarbass    17 年前

    在仔细研究了代码之后,这里有一个猜测:

    以下通知容器始终位于视图标记中:

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

    默认情况下,该通知容器是隐藏的,在特定情况下由javascript填充。它可以包含任意数量的消息。

    如果用户未登录

    坚持不懈 :Cookie用于跟踪是否显示消息。

    视图中服务器端生成的代码 : 我认为stackoverflow在您未登录的情况下只显示一条消息。以下代码被注入到视图中:

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

    showFirstTime()javascript方法只是根据是否设置了cookie来确定是否显示“这是你第一次来这里吗?”消息。如果没有cookie,则显示消息。如果用户采取行动,cookie将被设置,并且消息将来不会显示。nofity.showFirstTime()函数处理cookie的检查。

    如果用户已登录

    坚持不懈 :数据库用于跟踪消息是否已显示。

    视图中服务器端生成的代码 : 当请求页面时,服务器端代码会检查数据库,查看需要显示哪些消息。然后,服务器端代码将json格式的消息注入到视图中,并对showMessages()进行javascript调用。

    例如,如果我登录到一个视图,我会在SO的标记中看到以下内容:

        <script type="text/javascript">
    1
    2 var msgArray = [{"id":49611,"messageTypeId":8,"text":"Welcome to Super User! Visit your \u003ca href=\"/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>
    

    因此,服务器端代码要么在用户未登录的情况下注入代码以调用“showFirstTime”方法,要么为登录的用户注入消息并调用“showMessages”。

    更多关于客户端代码的信息

    另一个关键组件是“通知”JavaScript模块Picflight已经缩减(您可以使用yslow for firebug进行同样的操作)。notify模块根据服务器端生成的javascript处理通知div的填充。

    客户端未登录

    如果用户未登录,则当用户X退出通知或通过创建cookie转到常见问题解答时,模块会处理事件。它还通过检查cookie来确定是否显示首次消息。

    客户端登录

    如果用户已登录,notify模块会将服务器生成的所有消息添加到通知div中。当用户关闭消息时,它也很可能使用ajax来更新数据库。

        3
  •  4
  •   Tom    17 年前

    虽然这些绝不是官方的,但我遵循的常见做法会导致这样的结果:

    • 创建将充当通知容器的元素 在标记中 ,但默认情况下隐藏它(这可以通过多种方式完成——JavaScript、外部CSS或内联样式)。
    • 让脚本对通知的行为负责 标记之外 在上面的例子中,你可以看到有一个 onclick 以及在标记中包含的页面加载时触发的另一个函数。虽然它有效,但我认为这是将演示和行为混合在一起。
    • 将通知消息的演示文稿包含在外部样式表中。

    同样,这些只是我在回答你的问题时所说的常见做法。正如你的问题的性质所表明的那样,网络开发的问题是,有很多方法可以用同样的结果做同样的事情。

        4
  •  4
  •   Picflight    17 年前

    我看到以下jQuery函数了吗?我相信这会将html注入到id为notify的div容器中。

    我不明白这个JS是如何根据某些事件使用和调用的,也许有人可以解释一下。

    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("/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"
        }
     }
    } ();
    
        5
  •  2
  •   Mike Scott    17 年前

    StackOverflow使用 jQuery -你从SO发布的JS代码是一个jQuery调用。它几乎不需要任何代码,就能做你想做的事情。强烈推荐。

        6
  •  0
  •   Paul Mendoza    15 年前

    我写了这段Javascript,它就是这样做的,包括堆叠,像Stack Overflow一样滚动时陪伴在你身边,以及在添加新栏时向下推整个页面。酒吧也过期了。酒吧也逐渐形成。

    // 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);
        }    
    }
    

    要使用它,您必须使用jQuery,并确保页面正文上没有边距或填充。

    AdvancedMessageBar所采用的参数是可选的。如果提供,它将导致条形图在一定时间(毫秒)后消失。

    var mBar = new AdvancedMessageBar(10000);
    mBar.setMessage('This is my message', 'Left Message', 'Right Message');
    mBar.show();
    

    如果你想堆叠这些对象,那么只需创建更多AdvancedMessageBar对象,它们就会自动堆叠。