通知小工具不会每隔一次开放

时间:2016-02-26 20:55:53

标签: javascript jquery mustache

我在网上有一些通知小部件的代码。我试图通过添加来自我的数据库的警报来自定义它。我没有问题将信息导入小部件,但由于某种原因,我有两个错误,我似乎无法弄清楚。

错误1.每隔一次点击“获取数据”将禁止隐藏或显示通知

错误2.单击通知上的x按钮时,通知的数量将会下降,当您单击获取数据时,通知的数量将最多返回5。但是一旦你再次击中x,计数器将再次回到x被点击的次数。

重新创建错误:点击获取数据,删除通知(点击x) - >下至4,点击获取数据 - >回到5,当它应该降到4时,单击X下降到3.现在单击获取数据,然后再次单击x,直到2。

以下代码+ JS小提琴链接

JS

var dataQueue = [];
var alertIds = [];
var items = [];

function addData(data){

    for(var i = 0; i < data.length; i++){


        if($.inArray(data[i].alertid, alertIds) == -1){
            // Id is not in the queue   
            dataQueue.push(data[i]);
            alertIds.push(data[i].alertid);
        }       
    }
    refreshNotifications();
}

function refreshNotifications() {


    for(i = items.length; i < 5; i++){
        items[i] = dataQueue.shift();
    }



    var cssTransitionEnd = getTransitionEnd();
    var container = $('div.alerts');

    // Remove old notification list
    $('div.notifications.js-notifications').remove();


    items.forEach(function(item) {   

        item.formattedDate = function() {     
            return this.date.getFullYear() + '-' +
                    strpad(this.date.getMonth() + 1) + '-' +
                    strpad(this.date.getDate()) + " " + timeToString(this.date);      
        };
    }); 


    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" data-id="{{id}}">' +
              '<div class="details">' +
                '<span class="title">{{title}}</span>' +
                '<span class="date">{{formattedDate}}</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;
        })
        .on('click', '.js-dismiss', function(event) {
            var item = $(event.currentTarget).parents('.js-item');
            console.log("Item removed id: " + item.alertid);
            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 timeToString(date) {
    if (date) {
        var hh = date.getHours();
        var mm = date.getMinutes();
        var ap = hh >= 12 ? 'PM' : 'AM';

        hh = (hh >= 12) ? (hh - 12) : hh;
        hh = (hh === 0) ? 12 : hh;

        return (hh < 10 ? '0' : '') + hh.toString() + ':' +
        (mm < 10 ? '0' : '') + mm.toString() + ' ' + ap;
    }
    return null;
}

function strpad(num) {
    if (parseInt(num) < 10) {
        return '0' + parseInt(num);
    } else {
        return parseInt(num);
    }
}

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

$(document).ready(function(){
    $('#get_db_data').click(function(){         

      var newData = [];
            for(var i = 0; i < 10; i++){
            var newDataArray = [];

          newDataArray.id = i + 1;  
          newDataArray.title = "IO ID " + Math.floor((Math.random() * 1000) + 1);
          newDataArray.date = new Date();
          newDataArray.alertid = Math.floor((Math.random() * 100) + 1);;
          newData[i] = newDataArray;
      }                 

            addData(newData);


    });
});

// mustache script would be below

HTML

<div>
  <input type="button" id="get_db_data" value="Get Data" />
</div>
<div class="alerts">
  <button type="button" class="button-default show-notifications active js-show-notifications">
    <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>
</div>

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,
div .alerts {
  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;
  top: 20px;
}

.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: #3498db;
  color: #fefefe;
  font: normal 0.85em 'Lato';
  height: 16px;
  line-height: 1.45em;
  position: absolute;
  right: 2px;
  text-align: center;
  top: -2px;
  width: 16px;
}

.show-notifications.active ~ .notifications {
  opacity: 1;
  top: 100px;
}

.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;
  left: 10px;
  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;
}

https://jsfiddle.net/sd7mrvza/2/

1 个答案:

答案 0 :(得分:2)

好的,我发现了问题。在重新添加div中的项目之前,我没有删除这些事件。

.off('click', '.js-show-notifications')
.on('click', '.js-show-notifications', function(event) {
    $(event.currentTarget).closest('.js-show-notifications').toggleClass('active').blur();
    console.log("hide/unhide notifications");
    return true;
})
.off('click', '.js-dismiss')
.on('click', '.js-dismiss', function(event) {...}