为什么设置css left属性会导致它在8之前关闭
Why does setting css left property result in it going off by 8?
这是一把小提琴。http://jsfiddle.net/p31L86wg/4/
理想情况下,绿色框应该始终位于容器的中心,但由于某种原因,当我设置左侧属性时,它选择在我告诉它假设的像素值之前停止8个像素。
angular.module('website', ['ngAnimate'])
.controller('MainCtrl', function ($scope) {
$scope.products = [
{name: 'p1'},
{name: 'p2'},
{name: 'p3'},
{name: 'p4'},
{name: 'p5'}
];
$scope.currentIndex = 0;
$scope.setCurrentSlideIndex = function (index) {
$scope.currentIndex = index;
};
$scope.isCurrentSlideIndex = function (index) {
return $scope.currentIndex === index;
};
})
.directive('pan', function(panBuckets) {
return function(scope, elm, attr) {
elm.css('position', 'relative');
var parentWidth = elm.parent().width();
elm.css('left', Math.floor(parentWidth/2)-(70/2)+'px');
scope.pan = function(vector) {
var bucket = panBuckets[attr['pan']];
if (bucket) {
var result = bucket.selectNewItem(bucket.selectedIndex-vector);
var rect = elm[0].getBoundingClientRect();
console.log('amount moved',rect.left, (vector*70)+'px',rect.left+(vector*70)+'px');
if (result!==false) elm.css('left', rect.left+(vector*70)+'px');
console.log(bucket.selectedItem[0].getBoundingClientRect().left, rect.left);
}
};
};
})
.service('panBuckets', function() {
return {};
})
.directive('panItem', function(panBuckets) {
var itemBuckets = panBuckets;
return function(scope, elm, attr) {
var bucket = itemBuckets[attr['panItem']];
if (!bucket) {
itemBuckets[attr['panItem']] = [];
bucket = itemBuckets[attr['panItem']];
elm.addClass('product-active');
bucket.selectedItem = elm;
bucket.selectNewItem = function(idx) {
if (idx < 0) idx = 0;
if (bucket.selectedIndex==idx) return false;
if (!bucket[idx]) return false;
bucket.selectedItem.removeClass('product-active');
bucket.selectedItem = bucket[idx];
bucket.selectedItem.addClass('product-active');
bucket.selectedIndex = idx;
return idx;
};
bucket.selectedIndex = 0;
}
bucket.push(elm);
scope.panBucket = bucket;
};
})
;
当试图实现这样的定位时,相对位置有点奇怪,因为它会将项目保持在"原位",然后重新定位,它可能会产生一些奇怪的行为。
一个有效且简单的解决方案是将盒子容器的位置更改为绝对位置,将容器更改为相对位置。这样就能保证精度。
附言:有点偏离主题,但这种方式的动画(四处移动元素)最好通过转换转换来完成,它要快得多(处理尽可能转移到GPU,并进行更多优化)。
angular.module('website', ['ngAnimate'])
.controller('MainCtrl', function ($scope) {
$scope.products = [
{name: 'p1'},
{name: 'p2'},
{name: 'p3'},
{name: 'p4'},
{name: 'p5'}
];
$scope.currentIndex = 0;
$scope.setCurrentSlideIndex = function (index) {
$scope.currentIndex = index;
};
$scope.isCurrentSlideIndex = function (index) {
return $scope.currentIndex === index;
};
})
.directive('pan', function(panBuckets) {
return function(scope, elm, attr) {;
elm.css('position', 'relative');
var parentWidth = elm.parent().width();
elm.css('left', Math.floor(parentWidth/2)-(70/2)+'px');
scope.pan = function(vector) {
var bucket = panBuckets[attr['pan']];
if (bucket) {
var result = bucket.selectNewItem(bucket.selectedIndex+vector);
var rect = elm[0].getBoundingClientRect();
var bucketDimensions = bucket.selectedItem[0].getBoundingClientRect();
console.log(bucketDimensions);
if (result !== false) elm.css('left', Math.floor(parentWidth/2)-parseInt(bucket.selectedIndex * 70)-(70/2)+'px');
}
};
};
})
.service('panBuckets', function() {
return {};
})
.directive('panItem', function(panBuckets) {
var itemBuckets = panBuckets;
return function(scope, elm, attr) {
var bucket = itemBuckets[attr['panItem']];
if (!bucket) {
itemBuckets[attr['panItem']] = [];
bucket = itemBuckets[attr['panItem']];
elm.addClass('product-active');
bucket.selectedItem = elm;
bucket.selectNewItem = function(idx) {
if (idx < 0) idx = 0;
if (bucket.selectedIndex==idx) return false;
if (!bucket[idx]) return false;
bucket.selectedItem.removeClass('product-active');
bucket.selectedItem = bucket[idx];
bucket.selectedItem.addClass('product-active');
bucket.selectedIndex = idx;
return idx;
};
bucket.selectedIndex = 0;
}
bucket.push(elm);
scope.panBucket = bucket;
};
})
;
.container {
width: 100%;
position: relative;
}
.product-active {
background: green !important;
}
.square {
width: 50px;
height: 50px;
display: inline-block;
margin: 0 10px 0 10px;
background: blue;
}
.slider {
width:492px;
margin:0;
transition-property: left;
transition-duration: 0.4s;
transition-timing-: function: linear;
}
body {
overflow: hidden;
padding: 0;
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.10.3/TweenMax.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-animate.js"></script>
<div ng-app="website" ng-controller="MainCtrl">
<div class="container">
<div class="slider animated zoomIn" pan="one">
<div ng-repeat="p in products" class="square product" pan-item="one">{{p.name}} </div>
</div>
</div>
<button ng-click="pan(-1)"><</button>
<button ng-click="pan(1)">></button>
</div>
http://jsfiddle.net/2u29LL3L/1/
有一些不一致之处,请检查差异,我认为这就是你试图实现的目标。
我不明白为什么你的数学中有70
而不是50
,但后来我发现这是因为边际。
我基本上改变了滑块左侧位置的计算:
if (result !== false) elm.css('left', Math.floor(parentWidth/2)-parseInt(bucket.selectedIndex * 70)-(70/2)+'px');
因此,每次Math.floor(parentWidth/2)
都会将滑块居中,然后将选定的bin与-parseInt(bucket.selectedIndex * 70)
一起放在左侧,然后将当前bin的一半放在左侧。
我去掉了body
的边距和填充,检查一下。
编辑
我还改变了平移的方向,现在看起来更像是
乍一看,绿色框同时有左右边距。
.square:first-child {margin-left:0px;}
这将删除左侧的边距,并允许框向左调整。
相关文章:
- 如何使用CSS设置所选选项的样式,而不设置所有其他选项的样式
- 使用CSS设置HTML5自动对焦属性
- 使用jQuery/CSS设置的鼠标光标在鼠标移动之前不会更改
- 在jquery中使用css设置背景大小
- 将所有访问过的网站颜色重置为所有最新浏览器和所有doctype(xhtml,html,html5)的默认颜色css设置
- IE11 style.maxHeight未从css设置
- 使用css设置背景的宽度和高度
- slideDown() 在 css 设置为 display:none 时不起作用
- 通过在运行时使用 CSS 设置其高度/宽度来拉伸 img 会产生奇怪的渐变
- 如何调整从其他用户加载的图像的大小,以便保持尺寸,同时使用 css 设置最大宽度和高度?(HTML/JS/CSS)
- 你能用CSS设置一个断开的链接的样式吗?
- 如何使用 CSS 设置表单样式
- 如何直接从 CSS 设置自定义元素的样式
- CSS-设置固定(或绝对)位置时转换宽度中断
- 为什么我们可以't使用css设置画布的宽度和高度
- 如何在jsviews中将css设置为自定义标记(日期选择器)
- 如何在页面加载前使用CSS设置响应滑块的高度
- 使用CSS设置表格样式
- RaphaelJS/CSS-设置文本/数字动画
- 当javascript事件的大小通过css设置时,我如何在其上放大图像