StackExchange / Facebook就像通知框定位

时间:2016-08-09 06:51:30

标签: javascript html css

以下是细分:

screenshot

这里运作良好 http://www.whycall.me/member/notification/notificationIndex2.php

但是当我尝试将铃声整合到现有标题中时,我无法将其显示为最后一个菜单项。

我认为问题在于:

  • 点击的铃声有“position:relative”
  • 包含通知的框有“position:absolute”

我希望它显示为最后一个菜单项,同时点击铃声应该会展开右下方的通知框。

有没有办法建立它,所以通知框总是出现在小铃铛下面?

HTML和Javascript

        <button type="button" class="button-default show-notifications js-show-notifications" onClick="updateNotificationCheckDate()">
      <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="32" viewBox="0 0 30 32">
        <defs>
          <g id="icon-bell">
              <path class="path1" d="M15.143 30.286q0-0.286-0.286-0.286-1.054 0-1.813-0.759t-0.759-1.813q0-0.286-0.286-0.286t-0.286 0.286q0 1.304 0.92 2.223t2.223 0.92q0.286 0 0.286-0.286zM3.268 25.143h23.179q-2.929-3.232-4.402-7.348t-1.473-8.652q0-4.571-5.714-4.571t-5.714 4.571q0 4.536-1.473 8.652t-4.402 7.348zM29.714 25.143q0 0.929-0.679 1.607t-1.607 0.679h-8q0 1.893-1.339 3.232t-3.232 1.339-3.232-1.339-1.339-3.232h-8q-0.929 0-1.607-0.679t-0.679-1.607q3.393-2.875 5.125-7.098t1.732-8.902q0-2.946 1.714-4.679t4.714-2.089q-0.143-0.321-0.143-0.661 0-0.714 0.5-1.214t1.214-0.5 1.214 0.5 0.5 1.214q0 0.339-0.143 0.661 3 0.357 4.714 2.089t1.714 4.679q0 4.679 1.732 8.902t5.125 7.098z" />
          </g>
        </defs>
        <g fill="#000000">
            <use xlink:href="#icon-bell" transform="translate(0 0)"></use>
        </g>
      </svg>
        <div class="notifications-count js-count"></div>
      </button>


        <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
    <script src='http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.2/mustache.min.js'></script>



    <script>
    $(function () {
      var items = generateItems();
      refreshNotifications(items);
    });

    function refreshNotifications(items) {
      items = items || [];

      var cssTransitionEnd = getTransitionEnd();
      var container = $('body');

      items.forEach(function(item) {
        item.isExpired = false;

      });

      var template =
          '<div class="notifications js-notifications">' +
            '<h3>Notifications</h3>' +
            '<ul class="notifications-list">' +
              '<li class="item no-data">You don\'t have notifications</li>' +
              '{{#items}}' +
                '<li class="item js-item {{#isExpired}}expired{{/isExpired}}" data-id="{{id}}">' +
                  '<div class="details">' +
                    '<span class="title"><a href="http://whycall.me/{{phone}}.html#a{{commentID}}" style="color:#7f8c8d; text-decoration: none;">{{title}}</a></span>' +
                    '<span class="date">- {{dateEvent}} ago</span>' +
                  '</div>' +
                  '<button type="button" class="button-default button-dismiss js-dismiss">×</button>' +
                '</li>' +
              '{{/items}}' +
            '</ul>' +
            '<a href="#" class="show-all">Show all notifications</a>' +
          '</div>';

      container
        .append(Mustache.render(template, { items: items }))
        .find('.js-count').attr('data-count', items.length).html(items.length).end()

        .on('click', '.js-show-notifications', function(event) {
          $(event.currentTarget).closest('.js-show-notifications').toggleClass('active').blur();
          return true;
        })


          // think this part is what closes or opens the notification bar
        .on('click', '.js-dismiss', function(event) {
          var item = $(event.currentTarget).parents('.js-item');

          var removeItem = function() {
            item[0].removeEventListener(cssTransitionEnd, removeItem, false);
            item.remove();

            /* update notifications' counter */
            var countElement = container.find('.js-count');
            var prevCount = +countElement.attr('data-count');
            var newCount = prevCount - 1;
            countElement
              .attr('data-count', newCount)
              .html(newCount);


            if(newCount === 0) {
              countElement.remove();
              container.find('.js-notifications').addClass('empty');
            }
          };

          item[0].addEventListener(cssTransitionEnd, removeItem, false);
          item.addClass('dismissed');
          return true;
        });
    }

    function generateItems() {
      return [
        { id: 1, title: 'Admin upvoted your comment', dateEvent: '9 hours', phone: '9317298158' , commentID: '720' },
        { id: 2, title: 'Admin upvoted your comment', dateEvent: '9 hours', phone: '9317298158' , commentID: '721' },
        { id: 3, title: 'Admin upvoted your comment', dateEvent: '9 hours', phone: '9317298158' , commentID: '722' },

      ];
    }

    function getTransitionEnd() {
      var supportedStyles = window.document.createElement('fake').style;
      var properties = {
        'webkitTransition': { 'end': 'webkitTransitionEnd' },
        'oTransition': { 'end': 'oTransitionEnd' },
        'msTransition': { 'end': 'msTransitionEnd' },
        'transition': { 'end': 'transitionend' }
      };

      var match = null;
      Object.getOwnPropertyNames(properties).forEach(function(name) {
        if (!match && name in supportedStyles) {
          match = name;
          return;
        }
      });

      return (properties[match] || {}).end;
    }

            </script>

    <script>
    function updateNotificationCheckDate() {
        $.ajax({
            url: './updateDateNotificationChecked.php',
            type: 'GET',
            dataType: "json",
            data: {
                memberID: 1        }
        })
    }
    </script>

CSS

    @import url(http://fonts.googleapis.com/css?family=Lato:700);
    *,
    *:after,
    *:before {
      -moz-box-sizing: border-box;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
    }
    /*html,
    body {
      background: #fefefe;
      color: #fefefe;
      font-family: 'Lato';
      font-size: 14px;
      padding: 10px;
      position: relative;
    }*/
    .button-default {
      -webkit-transition: 0.25s ease-out 0.1s color;
      -moz-transition: 0.25s ease-out 0.1s color;
      -o-transition: 0.25s ease-out 0.1s color;
      transition: 0.25s ease-out 0.1s color;
      background: transparent;
      border: none;
      cursor: pointer;
      margin: 0;
      outline: none;
      position: relative;
    }
    .show-notifications {
      position: relative;
    }
    .show-notifications:hover #icon-bell,
    .show-notifications:focus #icon-bell,
    .show-notifications.active #icon-bell {
      fill: #34495e;
    }
    .show-notifications #icon-bell {
      fill: #7f8c8d;
    }
    .show-notifications .notifications-count {
      -moz-border-radius: 50%;
      -webkit-border-radius: 50%;
      border-radius: 50%;
      -moz-background-clip: padding-box;
      -webkit-background-clip: padding-box;
      background-clip: padding-box;
      background: #FF0000;
      color: #fefefe;
      font: normal 0.85em 'Lato';
      height: 16px;
      line-height: 1.75em;
      position: absolute;
      right: 2px;
      text-align: center;
      top: -2px;
      width: 16px;
    }
    .show-notifications.active ~ .notifications {
      opacity: 1;
      top: 60px;
    }
    .notifications {
      -moz-border-radius: 2px;
      -webkit-border-radius: 2px;
      border-radius: 2px;
      -moz-background-clip: padding-box;
      -webkit-background-clip: padding-box;
      background-clip: padding-box;
      -webkit-transition: 0.25s ease-out 0.1s opacity;
      -moz-transition: 0.25s ease-out 0.1s opacity;
      -o-transition: 0.25s ease-out 0.1s opacity;
      transition: 0.25s ease-out 0.1s opacity;
      background: #ecf0f1;
      border: 1px solid #bdc3c7;
      right: 150px;
      opacity: 0;
      position: absolute;
      top: -999px;
    }
    .notifications:after {
      border: 10px solid transparent;
      border-bottom-color: #3498db;
      content: '';
      display: block;
      height: 0;
      left: 10px;
      position: absolute;
      top: -20px;
      width: 0;
    }
    .notifications h3,
    .notifications .show-all {
      background: #3498db;
      color: #fefefe;
      margin: 0;
      padding: 10px;
      width: 350px;
    }
    .notifications h3 {
      cursor: default;
      font-size: 1.05em;
      font-weight: normal;
    }
    .notifications .show-all {
      display: block;
      text-align: center;
      text-decoration: none;
    }
    .notifications .show-all:hover,
    .notifications .show-all:focus {
      text-decoration: underline;
    }
    .notifications .notifications-list {
      list-style: none;
      margin: 0;
      overflow: hidden;
      padding: 0;
    }
    .notifications .notifications-list .item {
      -webkit-transition: -webkit-transform 0.25s ease-out 0.1s;
      -moz-transition: -moz-transform 0.25s ease-out 0.1s;
      -o-transition: -o-transform 0.25s ease-out 0.1s;
      transition: transform 0.25s ease-out 0.1s;
      border-top: 1px solid #bdc3c7;
      color: #7f8c8d;
      cursor: default;
      display: block;
      padding: 10px;
      position: relative;
      white-space: nowrap;
      width: 350px;
    }
    .notifications .notifications-list .item:before,
    .notifications .notifications-list .item .details,
    .notifications .notifications-list .item .button-dismiss {
      display: inline-block;
      vertical-align: middle;
    }
    .notifications .notifications-list .item:before {
      -moz-border-radius: 50%;
      -webkit-border-radius: 50%;
      border-radius: 50%;
      -moz-background-clip: padding-box;
      -webkit-background-clip: padding-box;
      background-clip: padding-box;
      background: #3498db;
      content: '';
      height: 8px;
      width: 8px;
    }
    .notifications .notifications-list .item .details {
      margin-left: 10px;
      white-space: normal;
      width: 280px;
    }
    .notifications .notifications-list .item .details .title,
    .notifications .notifications-list .item .details .date {
      display: block;
    }
    .notifications .notifications-list .item .details .date {
      color: #95a5a6;
      font-size: .85em;
      margin-top: 3px;
    }
    .notifications .notifications-list .item .button-dismiss {
      color: #bdc3c7;
      font-size: 2.25em;
    }
    .notifications .notifications-list .item .button-dismiss:hover,
    .notifications .notifications-list .item .button-dismiss:focus {
      color: #95a5a6;
    }
    .notifications .notifications-list .item.no-data {
      display: none;
      text-align: center;
    }
    .notifications .notifications-list .item.no-data:before {
      display: none;
    }
    .notifications .notifications-list .item.expired {
      color: #bdc3c7;
    }
    .notifications .notifications-list .item.expired:before {
      background: #bdc3c7;
    }
    .notifications .notifications-list .item.expired .details .date {
      color: #bdc3c7;
    }
    .notifications .notifications-list .item.dismissed {
      -webkit-transform: translateX(100%);
      -moz-transform: translateX(100%);
      -ms-transform: translateX(100%);
      -o-transform: translateX(100%);
      transform: translateX(100%);
    }
    .notifications.empty .notifications-list .no-data {
      display: block;
      padding: 10px;
    }
    /* variables */
    /* mixins */

我丑陋的不工作实现是here

1 个答案:

答案 0 :(得分:3)

查看您的测试页,问题是您的container对象使用了错误的选择器,它必须是$('#head-button')(请注意#)。我还将通知面板css调整为left:0而不是right:0。更新了小提琴here