通过更改 css top 在 div 动画中垂直滚动
Vertical scrolling in div animation by changing css top
我正在尝试设置水平滑块。我有 div 和 overflow: hidden
,里面有 16 个 div,高度为 60px。 Parent div 有身高所以你当时只能看到 4 个孩子。
现在我想改变孩子 top:
css 让他们向上滑动,4 个新的来自底部。
这是我到目前为止所做的
lastAddedService.getLastAdded()
.then(function (response) {
$scope.lastAddedElements = response.data;
var i = 0, g = 0, c = 0, p = 0;
var k = 1, b = 1, h = 1;
var slider = {
step: 1,
positionTop: 0,
init: function (step) {
var that = this;
el[0].querySelectorAll('.a').forEach(function (element) {
if(step === 1) {
if(i < 16) {
that.positionTop = i * 60;
i++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 2) {
if(i < 4) {
that.positionTop = k * 60 * -1;
i++; k++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 4) {
k = 0;
that.positionTop = g * 60;
i++; g++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 3) {
if(i < 8) {
that.positionTop = b * 60 * -1;
i++; b++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 8) {
that.positionTop = c * 60;
i++; c++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 4) {
if(i < 12) {
that.positionTop = h * 60 * -1;
i++; h++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 12) {
that.positionTop = p * 60;
i++; p++;
return angular.element(element).css('top', that.positionTop);
}
}
});
},
changeSlide: function (step) {
this.step = step;
this.init(this.step);
}
};
$timeout(function () {
slider.changeSlide(1);
});
setTimeout(function () {
setInterval(function () {
var q = 1;
q++;
slider.changeSlide(q);
if(q === 4) {
q = 1;
}
}, 5000);
}, 5000);
}, function (err) {
console.log('error getting last added');
});
}
所以我从后端收集记录,然后有这个滑块 object,它具有我上面解释的逻辑。
后端调用工作正常,我做了控制台响应,它是 16 条记录,稍后我在布局层中显示。问题主要是这个滑动的逻辑object.
我正在使用 $timeout
开始代码工作,因为这段代码确实在 angularJS 指令中,而我通过 querySelectorAll
获得的 NodeList 将是空的,否则因为它是在异步之后计算的后端调用完成,然后 DOM 已完全加载。但它与此脚本的实际逻辑并不真正相关,它只是附加信息。
- 我觉得这段代码很糟糕。我该如何改进它?
- 它在大约 20 秒后开始更新顶部,1 div 有 960px 我不知道为什么。
- 它不会重置此变量值,因此它不会循环,但它会越来越大
top
。
如果有人想重现问题,我会在我的指令中添加 HTML
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
<div class="row u-no-margin">
<div class="col-lg-11 col-xs-11">
<h2 class="main__heading">
Ostatnio dodane
</h2>
<div class="main__last-added-field">
<div class="main__last-added a" data-ng-repeat="n in lastAddedElements">
<div class="row u-no-margin main__last-added-container">
<div class="col-lg-3 col-md-2 col-sm-2 col-xs-2">
<h4 class="main__last-added-heading">
{{ n.data.attributes.price }}
</h4>
</div>
<div class="col-lg-7 col-xs-8 u-no-padding">
<h4 class="main__last-added-heading u-no-padding">
{{ n.data.attributes.name }}
</h4>
</div>
<div class="col-lg-2 col-xs-2">
<button type="button" class="btn btn__primary">
Zobacz
</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-1 col-xs-1">
<div class="main__last-added-dot-container">
<span class="main__last-added-dot main__last-added-dot--active"></span>
<span class="main__last-added-dot"></span>
<span class="main__last-added-dot"></span>
<span class="main__last-added-dot"></span>
</div>
</div>
</div>
</div>
JS 代码在指令 link: function
内,templateUrl 在 HTML 代码之上。
** 编辑 **
我更新了问题,我添加了 plunker 显示问题,我再解释一个,一步一步地完成我想要完成的事情。
- 第 1 步:所有元素都有
top: x
css,因此它们垂直对齐。我在 parent 上使用 overflow: hidden
所以你看到只有 4 和 12 像这样隐藏在下面
Step2 我将前 4 个元素移动到 top: -x
这样您就看不到前 4 个元素,而元素 5、6、7、8 取代了它们的位置,因此元素 5、6、7、 8 个现在滑到顶部,前 4 个被隐藏。
第 3 步与第 2 步相同:元素 5、6、7、8 移动到负顶部,您现在看到元素 9、10、11、12
第 4 步与第 3 步相同:元素 9、10、11、12 移动到负顶部,您现在看到元素 13、14、15、16
我不知道为什么,但在 plunker 中它根本不会更新 css 元素的顶部。
首先,我建议您为 html/css 视图使用仅 bootstrap 的解决方案,因为它响应迅速,经过测试,您将拥有更清晰的代码。
我对您的滑块逻辑进行了一些修改,使该逻辑就好像您的滑块是一个分页指令一样。
基本上,您将数据分成页面,然后跟踪要在视图上显示的当前页面。
在您的元素指令中,您对数据使用了两个过滤器(startFrom、limitTo)。 'limitTo' 是 Angular 中的内置过滤器,'startFrom' 是您必须创建的自定义过滤器。
<div class="" data-ng-repeat="n in elements | startFrom:currentPage*pageSize | limitTo:pageSize">
这只是一个想法,可以帮助您重构代码,这样您就不需要 css 定位来确定要显示的项目。这是我的演示:
https://plnkr.co/edit/IROsQWr5z4oYgZzmR2GF?p=preview
希望对您有所帮助!
我已经用这段代码完成了:
<div class="main__last-added a"
data-ng-repeat="n in lastAddedElements"
data-order="{{ $index+1 }}">
(function () {
'use strict';
angular
.module('igt')
.directive('lastAdded', Directive);
Directive.$inject = ['$timeout', 'lastAddedService'];
function Directive($timeout, lastAddedService) {
return {
restrict: 'E',
scope: {
destiny: '='
},
templateUrl: 'html/directives/lastAdded.html',
link: function ($scope, el) {
lastAddedService.getLastAdded()
.then(function (response) {
$scope.lastAddedElements = response.data;
$scope.slider = {
increment: 0,
step: 1,
positionTop: 0,
init: function (step) {
var that = this;
var elements = el[0].querySelectorAll('.a');
if(step === 1) {
console.log('run step 1 ..............');
this.step = 1;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if(order <= 16) {
that.positionTop = order * 60 - 60;
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 2) {
console.log('run step 2 ..............');
this.step = 2;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 4) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 4) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 12) {
that.increment = 0;
console.log('reset inc in step 2');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 3) {
console.log('run step 3 ..............');
this.step = 3;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 8) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 8) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 8) {
that.increment = 0;
console.log('reset inc in step 3');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 4) {
console.log('run step 4 ..............');
this.step = 4;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 12) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 12) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 4) {
that.increment = 0;
console.log('reset inc in step 4');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
},
changeSlide: function (step) {
this.step = step;
this.init(this.step);
}
};
$timeout(function () {
var i = 1;
$scope.slider.changeSlide(i);
setInterval(function () {
i++; if(i === 5) i = 1;
$scope.slider.changeSlide(i);
}, 5000);
});
}, function (err) {
console.log('error getting last added: ' + err);
});
}
}
}
})();
虽然比第一个版本好一点,但这段代码看起来仍然很蹩脚。我觉得它可以用更简单的方式完成。
我正在尝试设置水平滑块。我有 div 和 overflow: hidden
,里面有 16 个 div,高度为 60px。 Parent div 有身高所以你当时只能看到 4 个孩子。
现在我想改变孩子 top:
css 让他们向上滑动,4 个新的来自底部。
这是我到目前为止所做的
lastAddedService.getLastAdded()
.then(function (response) {
$scope.lastAddedElements = response.data;
var i = 0, g = 0, c = 0, p = 0;
var k = 1, b = 1, h = 1;
var slider = {
step: 1,
positionTop: 0,
init: function (step) {
var that = this;
el[0].querySelectorAll('.a').forEach(function (element) {
if(step === 1) {
if(i < 16) {
that.positionTop = i * 60;
i++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 2) {
if(i < 4) {
that.positionTop = k * 60 * -1;
i++; k++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 4) {
k = 0;
that.positionTop = g * 60;
i++; g++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 3) {
if(i < 8) {
that.positionTop = b * 60 * -1;
i++; b++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 8) {
that.positionTop = c * 60;
i++; c++;
return angular.element(element).css('top', that.positionTop);
}
}
if(step === 4) {
if(i < 12) {
that.positionTop = h * 60 * -1;
i++; h++;
return angular.element(element).css('top', that.positionTop);
}
if(i >= 12) {
that.positionTop = p * 60;
i++; p++;
return angular.element(element).css('top', that.positionTop);
}
}
});
},
changeSlide: function (step) {
this.step = step;
this.init(this.step);
}
};
$timeout(function () {
slider.changeSlide(1);
});
setTimeout(function () {
setInterval(function () {
var q = 1;
q++;
slider.changeSlide(q);
if(q === 4) {
q = 1;
}
}, 5000);
}, 5000);
}, function (err) {
console.log('error getting last added');
});
}
所以我从后端收集记录,然后有这个滑块 object,它具有我上面解释的逻辑。
后端调用工作正常,我做了控制台响应,它是 16 条记录,稍后我在布局层中显示。问题主要是这个滑动的逻辑object.
我正在使用 $timeout
开始代码工作,因为这段代码确实在 angularJS 指令中,而我通过 querySelectorAll
获得的 NodeList 将是空的,否则因为它是在异步之后计算的后端调用完成,然后 DOM 已完全加载。但它与此脚本的实际逻辑并不真正相关,它只是附加信息。
- 我觉得这段代码很糟糕。我该如何改进它?
- 它在大约 20 秒后开始更新顶部,1 div 有 960px 我不知道为什么。
- 它不会重置此变量值,因此它不会循环,但它会越来越大
top
。
如果有人想重现问题,我会在我的指令中添加 HTML
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
<div class="row u-no-margin">
<div class="col-lg-11 col-xs-11">
<h2 class="main__heading">
Ostatnio dodane
</h2>
<div class="main__last-added-field">
<div class="main__last-added a" data-ng-repeat="n in lastAddedElements">
<div class="row u-no-margin main__last-added-container">
<div class="col-lg-3 col-md-2 col-sm-2 col-xs-2">
<h4 class="main__last-added-heading">
{{ n.data.attributes.price }}
</h4>
</div>
<div class="col-lg-7 col-xs-8 u-no-padding">
<h4 class="main__last-added-heading u-no-padding">
{{ n.data.attributes.name }}
</h4>
</div>
<div class="col-lg-2 col-xs-2">
<button type="button" class="btn btn__primary">
Zobacz
</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-1 col-xs-1">
<div class="main__last-added-dot-container">
<span class="main__last-added-dot main__last-added-dot--active"></span>
<span class="main__last-added-dot"></span>
<span class="main__last-added-dot"></span>
<span class="main__last-added-dot"></span>
</div>
</div>
</div>
</div>
JS 代码在指令 link: function
内,templateUrl 在 HTML 代码之上。
** 编辑 **
我更新了问题,我添加了 plunker 显示问题,我再解释一个,一步一步地完成我想要完成的事情。
- 第 1 步:所有元素都有
top: x
css,因此它们垂直对齐。我在 parent 上使用overflow: hidden
所以你看到只有 4 和 12 像这样隐藏在下面
Step2 我将前 4 个元素移动到
top: -x
这样您就看不到前 4 个元素,而元素 5、6、7、8 取代了它们的位置,因此元素 5、6、7、 8 个现在滑到顶部,前 4 个被隐藏。第 3 步与第 2 步相同:元素 5、6、7、8 移动到负顶部,您现在看到元素 9、10、11、12
第 4 步与第 3 步相同:元素 9、10、11、12 移动到负顶部,您现在看到元素 13、14、15、16
我不知道为什么,但在 plunker 中它根本不会更新 css 元素的顶部。
首先,我建议您为 html/css 视图使用仅 bootstrap 的解决方案,因为它响应迅速,经过测试,您将拥有更清晰的代码。
我对您的滑块逻辑进行了一些修改,使该逻辑就好像您的滑块是一个分页指令一样。
基本上,您将数据分成页面,然后跟踪要在视图上显示的当前页面。
在您的元素指令中,您对数据使用了两个过滤器(startFrom、limitTo)。 'limitTo' 是 Angular 中的内置过滤器,'startFrom' 是您必须创建的自定义过滤器。
<div class="" data-ng-repeat="n in elements | startFrom:currentPage*pageSize | limitTo:pageSize">
这只是一个想法,可以帮助您重构代码,这样您就不需要 css 定位来确定要显示的项目。这是我的演示:
https://plnkr.co/edit/IROsQWr5z4oYgZzmR2GF?p=preview
希望对您有所帮助!
我已经用这段代码完成了:
<div class="main__last-added a"
data-ng-repeat="n in lastAddedElements"
data-order="{{ $index+1 }}">
(function () {
'use strict';
angular
.module('igt')
.directive('lastAdded', Directive);
Directive.$inject = ['$timeout', 'lastAddedService'];
function Directive($timeout, lastAddedService) {
return {
restrict: 'E',
scope: {
destiny: '='
},
templateUrl: 'html/directives/lastAdded.html',
link: function ($scope, el) {
lastAddedService.getLastAdded()
.then(function (response) {
$scope.lastAddedElements = response.data;
$scope.slider = {
increment: 0,
step: 1,
positionTop: 0,
init: function (step) {
var that = this;
var elements = el[0].querySelectorAll('.a');
if(step === 1) {
console.log('run step 1 ..............');
this.step = 1;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if(order <= 16) {
that.positionTop = order * 60 - 60;
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 2) {
console.log('run step 2 ..............');
this.step = 2;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 4) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 4) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 12) {
that.increment = 0;
console.log('reset inc in step 2');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 3) {
console.log('run step 3 ..............');
this.step = 3;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 8) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 8) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 8) {
that.increment = 0;
console.log('reset inc in step 3');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
if(step === 4) {
console.log('run step 4 ..............');
this.step = 4;
elements.forEach(function (e) {
var order = angular.element(e).attr('data-order');
if (order <= 12) {
that.positionTop = order * 60 * -1;
return angular.element(e).css('top', that.positionTop);
}
if (order > 12) {
that.positionTop = that.increment * 60;
that.increment++;
console.log(that.increment);
if (that.increment === 4) {
that.increment = 0;
console.log('reset inc in step 4');
}
return angular.element(e).css('top', that.positionTop);
}
});
}
},
changeSlide: function (step) {
this.step = step;
this.init(this.step);
}
};
$timeout(function () {
var i = 1;
$scope.slider.changeSlide(i);
setInterval(function () {
i++; if(i === 5) i = 1;
$scope.slider.changeSlide(i);
}, 5000);
});
}, function (err) {
console.log('error getting last added: ' + err);
});
}
}
}
})();
虽然比第一个版本好一点,但这段代码看起来仍然很蹩脚。我觉得它可以用更简单的方式完成。