Задать вопрос
@Toliam

Ruby on Rails | JavaScript Скрипт работает только после перезагрузки, как изменить?

Ruby on Rails | JavaScript Скрипт работает только после перезагрузки, а когда переходишь локально по веткам сервера, и возвращаешься сюда - то он не запускается. вот код html(haml) и js
%canvas.canvas{"data-bg-color" => "#e4e4e4", "data-coloor" => "#222", "data-color" => "#16a6b6", "data-percent" => "40", :height => "120", :width => "120"}
%canvas.canvas{"data-bg-color" => "#e4e4e4", "data-coloor" => "#222", "data-color" => "#16a6b6", "data-percent" => "80", :height => "120", :width => "120"}
%canvas.canvas{"data-bg-color" => "#e4e4e4", "data-coloor" => "#222", "data-color" => "#16a6b6", "data-percent" => "57", :height => "120", :width => "120"}
%canvas.canvas{"data-bg-color" => "#e4e4e4", "data-coloor" => "#222", "data-color" => "#16a6b6", "data-percent" => "83", :height => "120", :width => "120"}
%canvas.canvas{"data-bg-color" => "#e4e4e4", "data-coloor" => "#222", "data-color" => "#16a6b6", "data-percent" => "90", :height => "120", :width => "120"}

/**
   * @class Circle
   * @constructor
   */
  var Circle = function (canvas, callback) {
    /**
     * @type {HTMLCanvasElement}
     * @private
     */
    this._canvas = canvas;
    /**
     * @type {CanvasRenderingContext2D}
     * @private
     */
    this._ctx = canvas.getContext('2d');
    /**
     * @type {number}
     * @private
     */
    this._animateSpeed = 20;
    /**
     * @type {number}
     * @private
     */
    this._endProgress = Number(this._canvas.getAttribute('data-percent'));
    /**
     * @type {string}
     * @private
     */
    this._bgColor = this._canvas.getAttribute('data-bg-color');
    /**
     * @type {string}
     * @private
     */
    this._color = this._canvas.getAttribute('data-color');
    this._coloor = this._canvas.getAttribute('data-coloor');
    /**
     * @type {Array<function>}
     * @private
     */
    this._onReadyCallbacks = [];
    /**
     * @type {boolean}
     * @private
     */
    this._isReady = false;
    /**
     * @type {function}
     * @private
     */
    this._onEndAnimation = callback;
    /**
     * @type {number}
     * @private
     */
    this._radius = this._canvas.width / 2 - 3;
    /**
     * @type {number}
     * @private
     */
    this._width = this._canvas.width;
    /**
     * @type {number}
     * @private
     */
    this._height = this._canvas.height;
    this._onScroll = this._onScroll.bind(this);
    this._initialize();
  };
  /**
   * @lends Circle#
   */
  Circle.prototype = {
    setReady: function () {
      this._isReady = true;
      this._onReadyCallbacks.forEach(function (callback) {
        callback.call(this);
      }, this);
      this._onReadyCallbacks = [];
    },
    /**
     * @param {function} callback
     * @private
     */
    _onReady: function (callback) {
        if (this._isReady) {
          callback.call(this);
        } else {
          this._onReadyCallbacks.push(callback);
        }
      },
      /**
       * @returns {boolean}
       * @private
       */
      _isVisible: function () {
        var scroll = this._getScrollTop();
        var offset = this._canvas.offsetTop;
        return (scroll < offset) && (scroll + innerHeight > offset + this._canvas.height);
      },
      /**
       * @returns {number}
       * @private
       */
      _getScrollTop: function () {
        return document.body.scrollTop || document.documentElement.scrollTop;
      },
      /**
       * @private
       */
      _animate: function () {
        var time = this._endProgress * this._animateSpeed;
        Circle._animate({
          duration: time,
          step: this._redraw.bind(this),
          complete: this._onEndAnimation
        });
        window.removeEventListener('scroll', this._onScroll, false);
      },
      /**
       * @private
       */
      _clear: function () {
        this._canvas.width = this._canvas.width;
      },
      /**
       * @param {number} progress
       * @private
       */
      _draw: function (progress) {
        var angleStart = - Math.PI / 2;
        var angleEnd = angleStart + (2 * Math.PI * this._endProgress / 100) * progress;
        this._ctx.beginPath();
        this._ctx.strokeStyle = this._bgColor;
        this._ctx.lineWidth = 2;
        this._ctx.arc(this._width / 2, this._height / 2, this._radius, 0, Math.PI * 2, false);
        this._ctx.stroke();
        this._ctx.beginPath();
        this._ctx.strokeStyle = this._color;
        this._ctx.lineWidth = 2;
        this._ctx.arc(this._width / 2, this._height / 2, this._radius, angleStart, angleEnd, false);
        this._ctx.stroke();
        this._ctx.fillStyle = this._coloor;
        this._ctx.font = "bold 32px Verdana";
        var text = Math.floor(this._endProgress * progress) + "%";
        var text_width = this._ctx.measureText(text).width;
        this._ctx.fillText(text, this._width / 2 - text_width / 2, this._height / 2 + 15);
      },
      /**
       * @param {number} progress
       * @private
       */
      _redraw: function (progress) {
        this._clear();
        this._draw(progress);
      },
      _setHandlers: function () {
        window.addEventListener('scroll', this._onScroll, false);
      },
      _onScroll: function () {
        if (this._isVisible()) {
          this._animate();
        }
      },
      /**
       * @private
       */
      _initialize: function () {
        this._onReady(function () {
          if (this._isVisible()) {
            this._animate();
          } else {
            this._setHandlers();
          }
        });
      this._draw(0);
      }
    };
  /**
   * @param {Object} options
   * @param {function} options.step
   * @param {number} options.duration
   * @param {function} options.complete
   * @param {function} [options.timeFunction]
   * @private
   * @static
   */
  Circle._animate = function (options) {
    var start = Date.now(); // сохранить время начала
      requestAnimationFrame(function tick() {
        var timePassed = Date.now() - start;
        var progress = timePassed / options.duration;
        var timeFunction = options.timeFunction || function (progress) {
          return progress;
        };
        progress = progress > 1 ? 1 : progress;
        options.step(timeFunction(progress));
          if (progress === 1) {
            options.complete();
          } else {
            requestAnimationFrame(tick);
          }
      });
  };
    window.onload = function () {
      var canvases = Array.prototype.slice.call(document.querySelectorAll('.canvas'));
      var circles = [];
      var animateEndCount = 0;
      var onEnd = function () {
        animateEndCount++;
        if (circles[animateEndCount]) {
          circles[animateEndCount].setReady();
        }
      };
      canvases.forEach(function (canvas) {
        circles.push(new Circle(canvas, onEnd));
      });
      circles[0].setReady();
    };
  • Вопрос задан
  • 477 просмотров
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
Freika
@Freika
Senior Ruby on Rails developer
Или поставьте гем jquery-turbolinks
Ответ написан
Комментировать
railsfun
@railsfun
Web Developer
Вместо window.onload используйте

$(document).on "page:change", ->

для турболинкса. И все будет нормально :)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы