У объекта есть метод, записанный в прототип:
ServisePlate.prototype.disclose = function() {
console.log('запустилась функция disclose');
function showBody() {
if(this.elem.offsetHeight < (this.body.offsetHeight + this.initialSize)) {
this.elem.style.height = this.elem.offsetHeight + this.settings.step + 'px';
setTimeout(showBody.call(this), this.settings.speed);
}
}
function hideBody() {
if(this.elem.offsetHeight > this.initialSize) {
this.elem.style.height = this.elem.offsetHeight - this.settings.step + 'px';
setTimeout(hideBody.call(this), this.settings.speed);
}else {
this.elem.style.height = '';
}
}
if(this.elem.offsetHeight == this.initialSize || this.elem.offsetHeight >= (this.body.offsetHeight + this.initialSize)) {
if(this.elem.offsetHeight == this.initialSize) {
console.log('Сработало условие 1');
showBody.call(this);
} else {
console.log('Сработало условие 2')
hideBody.call(this);
}
}
}
У него есть две внутренние функции hideBody и showBody.
Как правильно привязать к ним контекст объекта? Через call(this), как в коде выше все функции запускаются и отрабатывают за исключением переменных объявленных в конструкторе - это объект:
this.settings = {
step: 30,
speed: 1000
}
его свойства задают шаг наращивания пикселей и таймаут повторного запуска.
Так вот функции отрабатываю так, словно их нет..... хотя из этих функций выводятся их значения через console.log.
По идее с такими значениями каждую секунду к свойству height должно прибавляться 30px, но нужная высота получается моментально, без плавного прибавления.
Через apply все происходит точно так же, а через bind вовсе не запускаются функции.
Как быть?
Налицо неверное использование технологии.
Самое просто решение: перенести эти функции в прототип объекта - нет нужды менять контекст, нет проблем с неправильным использованием call.
Конкретно в данном коде проблема заключается в том, что setTimeout, первым параметром ожидает функцию. Применение же call - сразу вызывает функцию.
То есть, в данном случае надо было использовать bind
Еще один вариант избежать проблем со сменой контекста, использовать стрелочные функции
Например:
var showBody = ()=>{
...
setTimeout(showBody, this.settings.speed)
}
Продвижение своими сайтами как стратегия роста и независимости