【问题标题】:jQuery .position() strangeness while using CSS3 rotate attribute使用 CSS3 旋转属性时 jQuery .position() 奇怪
【发布时间】:2011-07-02 00:33:03
【问题描述】:

我使用 jQuery .position() 方法获得绝对定位的旋转元素位置,然后使用 jQuery .css(pos) 设置与位置相关的属性(顶部、左侧),其中 pos.position() 返回的数据。我认为它会将元素留在原处,但元素的位置正在改变。

如何使用设置旋转元素位置,以便按预期放置?也许有一个取决于改变位置的角度的系数?

我正在 Google Chrome v.9、Windows XP 中进行测试。

HTML

<div id="container">
  <div id="element"> 
    <img src="http://t0.gstatic.com/images?q=tbn:ANd9GcS0Fawya9MVMez80ZusMVtk_4-ScKCIy6J_fg84oZ37GzKaJXU74Ma0vENc"/>
  </div>
</div> 

CSS

#container {
    position: relative;   
    border: 1px solid #999;
    padding: 5px;
    height: 300px;
    width:300px;
}    
#element {
    position: absolute;
    top:50px;
    left: 60px;
    width: auto;
    border: 1px solid #999;
    padding: 5px;
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
}

JS

$(document).ready(function(){
    var $el = $('#element'),
    // getting position    
        pos = $el.position();
    alert(pos.left + '/' + pos.top);
    // alerts 37/11

    // setting css position attributes equal to pos
    $el.css(pos);
    // re-getting position
    pos = $el.position();
    alert(pos.left + '/' + pos.top);
    // alerts 14/-28
});    

查看http://jsfiddle.net/Antaranian/2gVL4/

【问题讨论】:

  • 一个明显的解决方案是在您读/写其位置属性时临时拉直图像...
  • 感谢@Šime 的回答,我也想过,但是会对整个应用的生产力产生很大的影响,而且用户会在视觉上感受到,所以我正在寻找更智能的方法来解决它。
  • 它可以在 Opera 和 Firefox 中使用,同时提醒 50/60
  • @Poetro 它可以在 Opera 中使用,因为图像在该浏览器中没有旋转。将-o-transform: rotate(45deg); 添加到#element CSS 规则中,它在Opera 中也不起作用。
  • 对不起,我忘了说我是关于谷歌浏览器的。

标签: javascript jquery css css-position


【解决方案1】:
// Needed to read the "real" position
$.fn.adjustedPosition = function() {
    var p = $(this).position();
    return {
        left: p.left - this.data('dx'),
        top: p.top - this.data('dy')
    }
};

$(function() { 

    var img = $('img'),
        pos;

    // Calculate the delta
    img.each(function() {
        var po = $(this).position(), // original position
            pr = $(this).addClass('rot').position(); // rotated position

        $(this).data({
            dx: pr.left - po.left, // delta X
            dy: pr.top - po.top // delta Y
        });
    });

    // Read the position
    pos = img.adjustedPosition();    
    alert(pos.left + '/' + pos.top);     

    // Write the position
    img.css(pos);

    // Read the position again
    pos = img.adjustedPosition();    
    alert(pos.left + '/' + pos.top);

});

现场演示: http://jsfiddle.net/2gVL4/4/

那么这里发生了什么:

  1. 旋转图像的 CSS 代码存储在一个特殊的 CSS 类中。我这样做是因为我想读取图像的原始位置(旋转之前)。读取原始位置后,我应用 .rot 类,然后再次读取位置以计算差异(增量),该差异存储在元素的 data() 中。

  2. 现在,我可以通过自定义方法adjustedPosition(上面定义)读取位置。此方法将读取元素的位置,然后减去存储在元素的 data() 中的 delta 值。

  3. 要写入位置,只需像往常一样使用css(pos) 方法。

【讨论】:

  • 这里可能存在浏览器问题(使用 firefox),但在更新小提琴以使用 transform:rotate() 后,旋转后无法获得新位置。
【解决方案2】:

有类似的问题。有一个简单的解决方案(不优雅,但有效):

  • 将当前角度设置为 0
  • 读取 X/Y 位置
  • 将角度恢复到原来的值

    var temp = $(this).position();
    temp.angle = getRotationDegrees( $(this) );            // remember current angle
    rotateObject($(this), 0);                              // set angle to 0
    temp.left = Math.round($(this).position().left);       // proper value
    temp.top = Math.round($(this).position().top);         // proper value
    
    // revert back the angle
    rotateObject($(this), temp.angle); 
    

用到的函数:

    function rotateObject(obj, angle) {
        obj.css({ '-webkit-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-moz-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-ms-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ 'msTransform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-o-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-sand-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ 'transform': 'rotate(' + angle + 'deg)'});
    }

    function getRotationDegrees(obj) {
        var matrix = obj.css("-webkit-transform") ||
        obj.css("-moz-transform")    ||
        obj.css("-ms-transform")     ||
        obj.css("-o-transform")      ||
        obj.css("transform");
        if(matrix !== 'none') {
            var tr;
            if (tr = matrix.match('matrix\\((.*)\\)')) {
                tr = tr[1].split(',');
                if(typeof tr[0] != 'undefined' && typeof tr[1] != 'undefined') {
                    var angle = Math.round(Math.atan2(tr[1], tr[0]) * (180/Math.PI));
                }else{
                    var angle = 0; 
                }
            }else if(tr = matrix.match('rotate\\((.*)deg\\)')){
                var angle = parseInt(tr[1]); 
            }
        } else { var angle = 0; }
        return (angle < 0) ? angle + 360 : angle;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    相关资源
    最近更新 更多