2016-02-26 4 views
4

У меня есть код онлайн для виджета с уведомлением. Я попытался настроить его, добавив оповещения из моей базы данных для отображения. У меня нет проблем с получением информации в виджет, но по какой-то причине у меня есть две ошибки, которые, как мне кажется, не подходят.Notification Widget не открывается каждый второй раз

Ошибка 1. Каждый второй клик на «получить данные» отключит notifcations из прячась или показаны

Ошибка 2. Количество уведомлений будет идти вниз при нажатии кнопки х на уведомлениях, и он будет вернитесь до 5, когда вы нажмете «Получить данные». Но как только вы снова нажмете x, счетчик вернется к числу раз, когда щелкнул x.

Восстановить ошибку: нажмите «Получить данные», удалите уведомление (щелкните по x) -> до 4, нажмите «Получить данные» -> назад до 5, нажмите «X» до «3», когда оно должно быть до 4. Теперь нажмите получить данные, и х снова, вплоть до 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/

+0

Можете ли вы не опубликовать Bug 1 и Bug 2 как отдельные вопросы? И укажите, какой бит JavaScript не работает, как вы этого хотите. – rybo111

+0

Я понял проблему. Каждый раз, когда я получаю данные, он добавляет слушателей действий друг к другу. Я думал, что '.remove()' удалит прослушиватели действий? –

ответ

2

Ok я понял, проблема. Я не удалял события до повторного добавления элементов в 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) {...} 
+0

Просто вычислил это тоже;) - поэтому обратный вызов «removeItem» был вызван дважды, что объясняет уменьшение -2 ... – sjkm

+0

. То же самое со скрытой/скрытой для окна уведомлений, каждые два раза, когда оно было нажато, unhide/hide, и каждые 3 были скрыты/скрыты/отображены. –

Смежные вопросы