Панель уведомлений похожа на stackoverflow - PullRequest
26 голосов
/ 14 декабря 2008

Помните маленький div, который появляется вверху страницы, чтобы уведомить нас о вещах (например, о новых значках)?

Я бы тоже хотел реализовать что-то подобное и ищу несколько лучших практик или шаблонов.

Мой сайт также является приложением ASP.NET MVC. В идеале ответы должны включать такие особенности, как «положить this на главной странице» и «сделать this в контроллерах».

Просто чтобы избавить вас от необходимости искать себя, этот код я вижу в приветственном сообщении, которое вы получаете, когда не авторизуетесь в 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 ]

12 голосов
/ 18 мая 2009

Этот ответ имеет полное решение.

Copy-вставка:

Это разметка, изначально скрытая, чтобы мы могли ее добавить:

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

И вуаля. В зависимости от настроек вашей страницы вы также можете отредактировать верхнюю часть поля тела на дисплее.

Вот демонстрация этого в действии .

11 голосов
/ 18 сентября 2009

Немного подглядывая вокруг кода, вот предположение:

Следующий контейнер уведомлений всегда находится в разметке представления:

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

Этот контейнер уведомлений скрыт по умолчанию и заполняется JavaScript при определенных обстоятельствах. Может содержать любое количество сообщений.

Если пользователь не вошел в систему

Постоянство : файлы cookie используются для отслеживания того, отображается сообщение или нет.

Сгенерированный на стороне сервера код в представлении : Я думаю, что stackoverflow показывает только одно сообщение, если вы не вошли в систему. Следующий код вставляется в представление:

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

Метод javascript showFirstTime () просто определяет, показывать ли «Вы здесь впервые?» сообщение, основанное на том, был ли установлен cookie или нет. Если нет cookie, сообщение показывается. Если пользователь предпринимает какие-либо действия, файл cookie устанавливается, и сообщение не будет отображаться в будущем. Функция nofity.showFirstTime () обрабатывает проверку на наличие cookie.

Если пользователь вошел в систему

Постоянство : База данных используется для отслеживания того, было ли сообщение показано или нет.

Сгенерированный на стороне сервера код в представлении : Когда запрашивается страница, серверный код проверяет базу данных, чтобы увидеть, какие сообщения необходимо отобразить. Затем код на стороне сервера внедряет сообщения в формате json в представление и вызывает вызов javascript для showMessages ().

Например, если я вошел в представление, я вижу следующее в разметке в 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 "notify", который Picflight деминифицировал (вы можете сделать то же самое, используя yslow для firebug). Модуль notify обрабатывает заполнение div уведомлений на основе сгенерированного javascript на стороне сервера.

Не авторизован, на стороне клиента

Если пользователь не вошел в систему, то модуль обрабатывает события, когда пользователь Х выходит из уведомления или переходит в FAQ, создавая файл cookie. Он также определяет, отображать ли первое сообщение, проверяя наличие cookie.

Вход в систему на стороне клиента

Если пользователь вошел в систему, модуль уведомлений добавляет все сообщения, сгенерированные сервером, в раздел уведомлений. Он также, скорее всего, использует ajax для обновления базы данных, когда пользователь отклоняет сообщение.

4 голосов
/ 03 сентября 2009

Я вижу следующую функцию jQuery? Я полагаю, что HTML вводит в div с идентификатором notify-container.

Я не понимаю, как этот 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"
    }
 }
} ();
4 голосов
/ 14 декабря 2008

Хотя они ни в коем случае не официальные, общие практики, которым я следую, приведут к чему-то вроде этого:

  • Создайте элемент, который будет действовать как контейнер уведомлений в разметке , но по умолчанию скрывайте его (это можно сделать несколькими способами - JavaScript, внешний CSS или встроенные стили).
  • Держите сценарии ответственными за поведение уведомления вне разметки . В приведенном выше примере вы можете видеть, что есть onclick, а также другая функция, которая запускается при загрузке страницы, содержащейся в разметке. Хотя это работает, я вижу в этом смешивание презентации и поведения.
  • Содержит презентацию уведомления, содержащуюся во внешней таблице стилей.

Опять же, это всего лишь мои обычные практики, изложенные в контексте вашего вопроса. Суть веб-разработки, как уже показывает характер вашего вопроса, заключается в том, что существует множество способов сделать одно и то же с одинаковыми результатами.

2 голосов
/ 14 декабря 2008

StackOverflow использует jQuery - код JS, отправленный вами из SO, является вызовом jQuery. Он будет делать то, что вы хотите, практически без кода. Настоятельно рекомендуется.

0 голосов
/ 15 февраля 2011

Я написал этот фрагмент Javascript, который делает именно это, включая укладку, оставаясь с вами во время прокрутки, как это делает переполнение стека, и толкая всю страницу вниз при добавлении новой панели. Бары также истекают. Бары также скользят в существование.

// 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, и они будут автоматически складываться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...