Панель уведомлений, похожая на stackoverflow

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

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

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

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

Спасибо!

14.12.2008 19:10:02
Также обратите внимание, что вы можете легко разбираться в этом коде, используя: -Firebug для Firefox -Chrome- Щелкните правой кнопкой мыши, «осмотрите элемент» -IE - нажмите f12, выберите значок стрелки, нажмите на элемент для проверки
Brady Moritz 12.08.2010 06:38:35
6 ОТВЕТОВ
РЕШЕНИЕ

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

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

<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 для обновления базы данных, когда пользователь отклоняет сообщение.

11
21.09.2009 06:11:32

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

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

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

4
14.12.2008 19:21:05
Я также хотел бы добавить: Поместите весь код JavaScript для уведомлений в один внешний файл .JS. Скорее всего, у вас их будет немного, поэтому хорошо, что пользователи могут их кешировать. Плюс это хорошо послужит для организации кода.
Vilx- 14.12.2008 19:28:02
Если я могу добавить к этому. Не забудьте поместить этот файл .js в нижней части вашей структуры, чтобы он не блокировал загрузку остальной части страницы до тех пор, пока она не понадобится, поскольку javascript блокирует параллельные загрузки других внешних ресурсов.
Kit Sunde 14.12.2008 21:31:48

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

2
14.12.2008 20:50:12

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

Копирование-вставка:

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

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

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

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

12
23.05.2017 11:46:45
в системе уведомлений stackoverflow намного больше, чем в этом примере. Посмотрите де-минимизированный код javascript, предоставленный Picflight, или воспользуйтесь функцией «украшенной js» ySlow, чтобы увидеть код клиента. Также задействован код на стороне сервера ...
ckarbass 17.09.2009 22:58:06

Я вижу следующую функцию 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
2.09.2009 20:33:42

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

0
14.02.2011 22:50:07