Задать вопрос
  • Как обновлять таймер по клику?

    Genri_Rus, пользуйтесь любой удобной для вас, но имхо, это тяжелые паровозы, вполне достаточно той что приводил выше:
    https://www.queness.com/code-snippet/6523/generate...

    или вам обязательно надо с CDN тянуть??
  • Как обновлять таймер по клику?

    добавьте к обьекту Items поле в котором вы будете хранить таймер, и через это поле получайте доступ к нему. Тогда идентификатор не будет нужен


    И об этом я тоже писал:
    а если без id, то необходимо составлять сложный объект , хранить ссылки на DOM блоков-контейров сообщений и работать с этим объектом, как-то так.


    Но от "идентификатора" все равно никуда не деться, в данном контексте это не id товара, это некий идентификатор DOM элементов, за который выступает либо сам текст, либо его хэш, так же этот идентификатор используется И в списке объектов (элементов массива) выводимых сообщений.

    вот примерно как-то так.
    в получаемом HTML (перменная data) вообще никаких изменений не делается. ссылка на таймер заносится в массив и из него же достается по ключу-хешу от текста сообщения.
    let Item = function(name, timer) {
      this.name = name;
      this.timer = timer;
    }
    
    const items = [];
    
    // ....
    // ....
    
    // создаем JQuery объект из полученного HTML
    let $html = $(data);
    
    // подключите библиотеку отсюда
    // https://www.queness.com/code-snippet/6523/generate-md5-hash-with-javascript
    
    // получаем имя = текст из блока .inline-block.-notification-text
    let name = calcMD5($html.find('.inline-block.-notification-text').text());
    
    // передаем в объект Item хэш текста сообщения и ссылку НА таймер
    items[name] = new Item(name, $html.find('.-notification-timer'));
    
    // либо просто в массиве
    items[name] = $html.find('.-notification-timer');
    
    // ...
    
    // соответственно по тексту сообщения/хеша,
    // получаем элемент из списка объектов, хотя не знаю зачем так можно вообще просто:
    // items[name] = $html.find('.-notification-timer');
    // т.е. опять голый массив.
    
    function startTimer(name) {
      let $timer =  items[name]; // либо если объект - items[name].timer
      $timer.stop();
      $timer.css("width", "100%");
      $timer.animate(
        {width: 0},
        {duration: 10000,
         complete: function() {
           $(this).closest('.notice__info').remove();
           delete items[name];
           console.log(`Удален ${name}`);
         }
        }
      );
    }
    
    
    
    $(document).on('click', '.notice__delete', function() {
      let $timer = $(this).siblings().find('.notice__timer');
      let name = calcMD5($(this).siblings().find('.inline-block.-notification-text').text());
      $timer.stop();
      $(this).parent().remove();
      delete items[name];
    });
  • Как обновлять таймер по клику?

    Genri_Rus, я же говорю, идентификаторы навешиваются после получения сообщения, на шаблон, что на той странице, что у меня (я писал в комментарии как) и в обоих случаях как идентификатор выступает собственно сам текст сообщения, только на той стронице он прогоняется через sha1 и хранится как hash (просто hash короче всего сообщения и в нем только латинские буквы и цифры) все это делается на js и снаружи вообще пофиг, есть они нет. в аякс можете передавать все что и передавали и как передавали раньше.

    // создаем JQuery объект из полученного HTML
    let $html = $(data);
    
    // получаем имя = текст из блока .inline-block.-notification-text
    let name = $html.find('.inline-block.-notification-text').text();
    // добавляем в items данный name
    items[name] = 1;
    // устанавливаем аттрибут data-name в полученном "таймере"
    $html.find('.-notification-timer').data('name', name);
    
    // ...
    // добавляем "таймер" в контейнер
    $('.timers_container').append($html);
    
    // стартуем таймер


    можно так же хешировать текс и писать в name его хеш, но тогда надо подключать внешние библиотеки для хеширования.
  • Как обновлять таймер по клику?

    Genri_Rus, а оно работает? чем не устраивает работающий вариант?
    и что вы уперлись в эти id? я вам представил различные варианты, дальше развивайте.
    а если без id, то необходимо составлять сложный объект , хранить ссылки на DOM блоков-контейров сообщений и работать с этим объектом, как-то так.
    Как еще находить то DOM элементы , если у них одинаковые классы и пр.???

    Вам надо сложнее?

    вот объект работающий с сообщениями с той страницы:
    spoiler
    var ntNotification = {
      templates: {},
      notifications: [],
      getTemplate: function(e, t) {
        var i = this;
        this.templates[e] ? t(i.templates[e]) : $.get("/html/ru_RU/utils/notification.html", function(n) {
          i.templates[e] = n, t(i.templates[e])
        })
      },
      getTop: function(e) {
        return parseInt(e.css("top").replace("px", ""))
      },
      moveAll: function(e, t) {
        var i = this;
        _.forEach(i.notifications, function(n, o) {
          if (o >= e)
            if (e != o) {
              var a = i.notifications[o - 1].elm;
              t = t + a.outerHeight() + 5, n.elm.animate({
                top: t + "px"
              }, 200)
            } else n.elm.animate({
              top: t + "px"
            }, 200)
        })
      },
      deleteNotification: function(e, t) {
        var i = this,
          n = _.indexOf(i.notifications, e),
          o = i.getTop(e.elm);
        e.timeout && clearTimeout(e.timeout), i.notifications = _.without(i.notifications, e), e.elm.stop(!0, !0), t ? e.elm.animate({
          left: e.elm.width() + "px",
          opacity: 0
        }, 200, function() {
          e.elm.remove(), i.moveAll(n, o)
        }) : e.elm.animate({
          top: o - e.elm.outerHeight() + "px",
          opacity: 0
        }, 200, function() {
          e.elm.remove(), i.moveAll(n, o)
        })
      },
      shake: function(e) {
        for (var t = 0; t < 6; t++) $(e).animate({
          "margin-left": t % 2 == 0 ? 5 : -5
        }, {
          duration: 70,
          queue: !0
        });
        $(e).animate({
          "margin-left": 0
        }, 70)
      },
      getPageX: function(e) {
        var t = 0;
        if ("touchstart" == e.type || "touchmove" == e.type || "touchend" == e.type || "touchcancel" == e.type) {
          t = (e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]).pageX
        } else "mousedown" != e.type && "mouseup" != e.type && "mousemove" != e.type && "mouseover" != e.type && "mouseout" != e.type && "mouseenter" != e.type && "mouseleave" != e.type || (t = e.pageX);
        return t
      },
      show: function(e, t, i) {
        var n = this,
          o = CryptoJS.SHA1(t).toString(),
          a = _.findWhere(n.notifications, {
            id: o
          }),
          r = !_.isUndefined(i) && i;
        if (a) {
          if (a.elm.stop(!0, !0), n.shake(a.elm), a.timeout) {
            clearTimeout(a.timeout);
            var s = a.elm.find(".-notification-timer");
            s.stop(!0, !0), s.css({
              width: ""
            }), s.animate({
              width: 0
            }, a.time), a.timeout = setTimeout(function() {
              n.deleteNotification(a)
            }, a.time)
          }
        } else this.getTemplate(e, function(a) {
          window.view && window.view.translate && (t = window.view.translate(t));
          var s = {
            id: o,
            elm: $(_.template(a)({
              type: e,
              message: t,
              hasTimer: r
            }))
          };
          if (s.elm.data("id", o), n.notification_box || (n.notification_box = $('<div class="-notification-box"></div>'), $(document).on("click", ".-notification-close, .-notification-box .-notification-icon", function() {
              var e = _.findWhere(n.notifications, {
                id: $(this).parent().eq(0).data("id")
              });
              e && n.deleteNotification(e)
            }), $(document).on("touchstart", ".-notification", function(e) {
              var t = _.findWhere(n.notifications, {
                id: $(this).data("id")
              });
              t.elm.css("left", 0);
              var i = n.getPageX(e),
                o = t.elm.offset();
              $(document).on("touchmove.notification", function(e) {
                var a = n.getPageX(e),
                  r = a - i;
                r > 0 ? t.elm.css({
                  left: r + "px"
                }) : o.left < a ? i = a : $(document).off("touchmove.notification touchend.notification"), r > 100 && ($(document).off("touchmove.notification touchend.notification"), n.deleteNotification(t, !0))
              }), $(document).on("touchend.notification", ".-notification", function() {
                t.elm && t.elm.css({
                  left: 0
                }), $(document).off("touchmove.notification touchend.notification")
              })
            }), n.notification_box.css({
              top: 0
            }), $("body").append(n.notification_box)), s.elm.css({
              opacity: 0,
              top: 0
            }), n.notification_box.append(s.elm), 0 != n.notifications.length) {
            5 == n.notifications.length && n.deleteNotification(n.notifications[n.notifications.length - 1]);
            var c, d = function() {};
            _.forEach(n.notifications, function(e, t) {
              if (t == n.notifications.length - 1 && (d = function() {
                  s.elm.animate({
                    opacity: 1
                  }, {
                    duration: 100,
                    queue: !0
                  })
                }), 0 != t) {
                var i = n.notifications[t - 1].elm;
                c = c + i.outerHeight() + 5, e.elm.animate({
                  top: c + "px"
                }, 100, d)
              } else c = s.elm.outerHeight() + 5, e.elm.animate({
                top: c + "px"
              }, 100, d)
            })
          } else s.elm.animate({
            opacity: 1
          }, 100);
          n.notifications.unshift(s), r && (s.time = i, s.elm.find(".-notification-timer").animate({
            width: 0
          }, i), s.timeout = setTimeout(function() {
            n.deleteNotification(s)
          }, s.time))
        })
      },
      showError: function(e, t) {
        t = _.isUndefined(t) ? 5e3 : t, this.showMessage(e, "error", t)
      },
      showWarning: function(e, t) {
        t = !0 === t && 5e3 || t, this.showMessage(e, "warning", t)
      },
      showSuccess: function(e, t) {
        t = _.isUndefined(t) ? 5e3 : t, this.showMessage(e, "success", t)
      },
      showMessage: function(e, t, i) {
        var n = this;
        if (t = t || "error", i = _.isUndefined(i) ? "warning" == t ? 0 : 5e3 : i, /^\/[a-z]+/.test(e)) {
          var o = $("body").data("lang");
          $.get("/html/" + o + e, function(e) {
            n.show(t, e, i)
          })
        } else n.show(t, e, i)
      }
    };


    и кстати Idшники там формируются - Это SHA1 от текста сообщения:

    //........
          o = CryptoJS.SHA1(t).toString(),
          a = _.findWhere(n.notifications, {
            id: o
          })
    //........ потом навешиваются
           s.elm.data("id", o)
    // далее использование:
    $(document).on("click", ".-notification-close, .-notification-box .-notification-icon", function() {
              var e = _.findWhere(n.notifications, {
                id: $(this).parent().eq(0).data("id")
              });
    // ...
    $(document).on("touchstart", ".-notification", function(e) {
              var t = _.findWhere(n.notifications, {
                id: $(this).data("id")
              });


    в принципе у меня почти тоже самое, только гораздо проще см. мой комментарий:
    const items = [];
    
    // ...............
    // ...............
    
    // добавляем контейнер для таймеров в DOM если его не существует
    if (!$('.timers_container').length) {
      $('body').append('<div class="timers_container"></div>');
    }
    
    // создаем JQuery объект из полученного HTML
    let $html = $(data);
    
    // получаем имя = текст из блока .inline-block.-notification-text
    let name = $html.find('.inline-block.-notification-text').text();
    // добавляем в items данный name
    items[name] = 1;
    // устанавливаем аттрибут data-name в полученном "таймере"
    $html.find('.-notification-timer').data('name', name);
    
    // ...
    // добавляем "таймер" в контейнер
    $('.timers_container').append($html);
    
    // стартуем таймер
    // ...


    текст сообщения как идентификатор в data-name, можно его в sha1 прогонять.
    можно не хранить так называемый "идентификатор" (прямой ли текст сообщения или sha1) в аттрибутах элемента, НО тогда искать надо по textContent елемента, что просто УСЛОЖНЯЕТ операцию поиска, а зачем??

    PS: вам надо сложнее? напишите сами...
  • Как обновлять таймер по клику?

    Genri_Rus, ну, вы сами решите как его использовать, пример я показал (не обязательно парметр data-name, можно и id, какой угодно ), для чего тоже объяснил (таймеры необходимо идентифицировать, иначе как их перезапускать?)
  • Как обновлять таймер по клику?

    Genri_Rus, не знаю как вы смотрели, но...

    карточка товара там выглядит так:
    <div class="product-item preview-size-250" id="item43132612">
      <div class="background"></div>
      <div class="wrapper" style="width:250px"><a href="http://vintagetechnics.ru/products/43132612">
          <div class="-relative item-image" style="height:190px"><img
              src="//i.siteapi.org/LetPQXB1TG_5FEafDIx2LhOg49s=/0x0:1619x1080/fit-in/250x190/center/top/filters:fill(transparent):format(png)/8292488b394caa9.s.siteapi.org/img/1xdusdzfulgk0okok4c0ogg4ocgow4" class="product-preview-img"
              alt="Проигрыватель винила Sony TTS-6000 + Sony PUA-7" title="Проигрыватель винила Sony TTS-6000 + Sony PUA-7" width="250" height="190"></div>
        </a>
        <div class="product-link -text-center"><a href="http://vintagetechnics.ru/products/43132612">Проигрыватель винила Sony TTS-6000 + Sony PUA-7</a><a href="#" class="cart-btn">
            <div class="overlay"></div>
            <div class="grid-7-sprite-cart-product cart-product"></div>
          </a></div>
        <div class="-text-center ">
          <div class="product-price"><span class="price"><span class="product-price-data" data-cost="200000">
                200&nbsp;000&nbsp;руб.
              </span></span></div>
        </div>
      </div>
    </div>


    уже сразу видно, что ID там есть! и в нескольких местах
    начиная отсюда
    <div class="product-item preview-size-250" id="item43132612">

    и почти в каждой ссылке...

    далее...
    на ссылке
    <a href="#" class="cart-btn">

    висит обработчик
    function() {
      return e.addToCart(this, !0)
    }


    смотрим js и находим этот метод некоего объекта:
    addToCart: function(e, t, i) {
        var n = 1 == t ? $(e).parents(".product-item") : $(e).parents(".item-content"),
          o = i || [];
        if (n.length > 0) {
          var a = $(n).attr("id").replace("item", "") || 0,
            r = t && !$(e).hasClass("js-cart-btn") ? void 0 : e;
          this.push({
            itemId: a,
            num: 1,
            getcart: 1,
            button: r,
            productParams: o
          })
        }
        return !1
      }


    итак при клике на ссылку в метод передается сама ссылка this и !0 что равно true
    далее в методе addToCart выбирается родительский элемент ссылки с селектором ".product-item"
    потому что 1 == true результат true
    n = 1 == t ? $(e).parents(".product-item") : $(e).parents(".item-content")

    т.е. в итого n = $(e).parents(".product-item")

    а это есть верхний, родительский элемент всей карточки:
    <div class="product-item preview-size-250" id="item43132612">


    из него и берется id
    var a = $(n).attr("id").replace("item", "") || 0,

    и т.д. и т.д.
    ....
  • Как обновлять таймер по клику?

    Genri_Rus, смотрите страницу в режиме отладки в браузере.
  • Как обновлять таймер по клику?

    Genri_Rus,
    тогда наверно проще формировать просто текст на сервере и вставлять его в вёрстку в js уже ?


    попробуйте то что описал выше, ничего не надо никуда добавлять, все в JS
  • Как обновлять таймер по клику?

    Genri_Rus, не знаю, у меня так не получалось, только если удалять...
    переписал удаление таймера по клику на X, вроде сейчас не повторяется глюк.
  • Как обновлять таймер по клику?

    Genri_Rus, честно говоря не знаю и не очень интересно разбирать их код (это уже работа), предложил свою реализацию исходя из поставленного вопроса.

    идентификаторы можно вставить потом, после вставки полученного HTML
    либо как-то еще.

    можно сделать так:
    const items = [];
    
    // ...............
    // ...............
    
    // добавляем контейнер для таймеров в DOM если его не существует
    if (!$('.timers_container').length) {
    	$('body').append('<div class="timers_container"></div>');
    }
    
    // создаем JQuery объект из полученного HTML
    let $html = $(data);
    
    // получаем имя = текст из блока .inline-block.-notification-text
    let name = $html.find('.inline-block.-notification-text').text();
    // добавляем в items данный name
    items[name] = 1;
    // устанавливаем аттрибут data-name в полученном "таймере"
    $html.find('.-notification-timer').data('name', name);
    
    // ...
    // добавляем "таймер" в контейнер
    $('.timers_container').append($html);
    
    // стартуем таймер
    // ...
  • Как правильно вывести объект в html?

    Иван Симонов, какая вообще связь между календарем, который вы теперь вставили и массивом:
    let arr = [2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6];

    ??
    дни недели - пнд - 1, втн -2 .... вск - 7 ???

    и убрали значение: количество из строк str
    str += `${result[key]}, `;

    поэтому как теперь идентифицировать какое количество чему соответствует??
  • Как обновлять таймер по клику?

    Это
    `<div class="notice__timer" data-name="${name}"></div>`


    такая разновидность javascript строки и вместо ${name} подставляется значение javascript переменной name
    см - https://learn.javascript.ru/es-string

    мне не было известно, что в качестве идентификатора в items используется целая лапша из html пришедшая по ajax
    в чем трудность передать ID ??
    или JSON Объект:
    {
    id: SOME_ID,
    html: '<div class="-notification -f-medium error" style="opacity: 1; top: 0px;">
            <div class="-notification-close site-icons-close"></div>
            <div class="-icon-font- -f-large -notification-icon inline-block"></div>
            <div class="inline-block -notification-text">Товара "<?php echo $product_data->get_name(); ?>" нет в наличии в количестве 2 шт.</div>
            <div class="-notification-timer"></div>
          </div>'
    }


    либо в качестве идентификатора брать текст из тега
    <div class="inline-block -notification-text">Товара "<?php echo $product_data->get_name(); ?>" нет в наличии в количестве 2 шт.</div>


    лучше конечно же наименование самого товара, но как парсить строку пока не ясно же...

    это:
    `<div class="notice__timer" data-name="${name}"></div>`


    я ввел для того чтобы таймеры:
    различались и чтобы его можно было легко идентифицировать и найти.

    можно и иначе решить, но таймеры необходимо как-то идентифицировать.
  • Как обновлять таймер по клику?

    Genri_Rus, ну так перепишите, я же вам даже пример написал.
    и все свои комментарии по этому куску кода.
  • Как добавить одинаковые обработчики событий на разные элементы?

    в функцию вы передаете строковое наименование у которого нет метода addEventListener
  • Как обновлять таймер по клику?

    setTimeout тут вообще не используется, тут JQuery метод .animate
  • Как сделать поиск по всей таблице по одному ключевому запросу?

    если в field1 = 111 а field = 333
    то такой запрос выберет данную запись, что не верно.
    либо конкатенировать через какой либо разделитель, которого не будет в искомой строке либо фильтр по всем полям таблицы, что скорее всего будет возможно быстрее.
  • Как подключить WinSCP к sftp используя командную строку?

    не дает мне посмотреть что там за проблемы, pause не помогает

    выполните эту команду в командной строке, а не из бат файла, увидите.