powerange icon indicating copy to clipboard operation
powerange copied to clipboard

Chrome & Safari Crash when adding 'step'

Open danielravina opened this issue 11 years ago • 2 comments

My code is:

@$powerrange = @$('.js-range')
new Powerange(@$powerrange[0], { step: 10 })

I console.log all the functions and its crashing on line 1185

 ctor.prototype = Object.create(superCtor.prototype,
      { constructor: {
            value: ctor
          , enumerable: false
          , writable: true
          , configurable: true
        }
    });

Please help! I like this plugin and without step it wont work for me... Thanks!

danielravina avatar May 26 '14 04:05 danielravina

Well if the demo page is not crashing, then something is messed up with your code. I can take a look, but I'm going to need you to provide jsfiddle or something.

abpetkov avatar May 26 '14 16:05 abpetkov

If you apply Powerange to an element that is inside an element that has never been rendered; when the following code is called (https://github.com/abpetkov/powerange/blob/master/lib/horizontal.js#L30)

if (this.options.step) this.step(this.slider.offsetWidth, this.handle.offsetWidth);

this.slider.offsetWidth will return 0 this.handle.offsetWdith with return 0

Then these 2 zeros are passed to

Powerange.prototype.step = function(sliderSize, handleSize) {
  var dimension = sliderSize - handleSize
    , part = percentage.from(this.checkStep(this.options.step), this.options.max - this.options.min)
    , interval = percentage.of(part, dimension)
    , steps = [];

  for (i = 0; i <= dimension; i += interval) {
    steps.push(i);
  }

  this.steps = steps;

  return this.steps;
};

dimension is then set to 0. interval is then set to (part / 100) * dimension(0) = 0

Then your for loop does; for i = 0; i <= 0(dimension); 0(i) + 0(interval) basically for (i = 0; 0<=0; 0+0) Infinite loop. Browser crashes.

I don't know how you want to approach fixing this. Before you call the step() function you might do

  if (!this.slider.offsetWidth && !this.handle.offsetWidth)
    this.options.step = null
    console.warn("Powerange: step not applied because elm doesn't have width")

The code will run as though step was never provided (this is not a great solution).

One work around if you are calling Powerange against an element that is in a container that is yet to be rendered (ie. like in @danielravina case a backbone view) is to defer the powerange call until after the element has been rendered using setTimeout or equivalent like _.defer.

input = $('<input class="ranger" type="text"></input>')
div = $('<div>').append(input)
$('body').append(div)
// defer the below code until after render.
setTimeout((function(input){
  new Powerange(input, {step: 10})
})(input), 1)

startswithaj avatar Aug 20 '14 05:08 startswithaj