为什么设置css left属性会导致它在8之前关闭

Why does setting css left property result in it going off by 8?

本文关键字:css 设置 left 属性 为什么      更新时间:2023-09-26

这是一把小提琴。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;} 

这将删除左侧的边距,并允许框向左调整。