Jquery 为什么绝对位置和固定位置给出不同的读数?

Jquery 为什么绝对位置和固定位置给出不同的读数?,jquery,css,collision-detection,Jquery,Css,Collision Detection,我正在编写一个简单的jQuery脚本,它允许我根据项目在视口外的距离来偏移它。换句话说,对象(div)与视口的碰撞。到目前为止,我用position:fixed拼凑的东西效果很好,但是如果使用position:absolute,它会被禁用34像素,我认为这是由于浏览器的垂直滚动条*2。不管是不是这样,我不知道如何补偿 也许有人知道我如何修正这种不同的解读 我整理了一个JSFIDLE,可以在这里查看: 在JSFIDLE中,您可以在视图窗格中看到“屏幕外X:-133”。该值应为-150。如果将第13

我正在编写一个简单的jQuery脚本,它允许我根据项目在视口外的距离来偏移它。换句话说,对象(div)与视口的碰撞。到目前为止,我用
position:fixed
拼凑的东西效果很好,但是如果使用
position:absolute,它会被禁用34像素,我认为这是由于浏览器的垂直滚动条*2。不管是不是这样,我不知道如何补偿

也许有人知道我如何修正这种不同的解读

我整理了一个JSFIDLE,可以在这里查看:

在JSFIDLE中,您可以在视图窗格中看到“屏幕外X:-133”。该值应为-150。如果将第13行的css for.box更改为fixed,您将看到红色框的位置正确,并与屏幕的底部和右侧齐平,屏幕外的X值将为-150

也许有一些关于固定与绝对的原理,我没有或忘记了

elemCollision($('.box'));

function elemCollision(el) {

  // Viewport Width and Height
  var viewportW = window.innerWidth;
  var viewportH = window.innerHeight;

  // Element Width and Height
  var width = el.innerWidth();
  var height = el.innerHeight();

  // Element Position: top, right, bottom, left
  var top = el.offset().top;
  var left = el.offset().left;
  var right = (viewportW - left) + viewportW;
  var bottom = (viewportH - top) + viewportH;

  // Amount Element is Off Screen
  var offScreenX = (viewportW - left) - width;
  var offScreenY = (viewportH - top) - height;

  // Position Element 100% on Screen
  var placementX = (viewportW - left) - Math.abs(offScreenX);
  var placementY = (viewportH - top) - Math.abs(offScreenY);

  // Assign New X and Y Placement Values
  $('.box').css({ bottom: placementY, right: placementX });

  $('body').append(
    '<div style="padding: 10px; font-size: 0.80em; line-height: 1.25em;">-----' + '<br/>' +
        'Placement Top: ' + top + '<br/>' +
    'Placement Right: ' + right + '<br/>' +
    'Placement Bottom: ' + bottom + '<br/>' +
    'Placement Left: ' + left + '<br/>' +
    'Box Width: ' + width + '<br/>' +
    'Box Height: ' + height + '<br/>' +
    'Viewport Width: ' + viewportW + '<br/>' +
    'Viewport Height: ' + viewportH + '<br/>' +
    'Off-screen X: ' + offScreenX + '<br/>' +
    'Off-screen Y: ' + offScreenY + '<br/>' +
    'New Placement X: ' + placementX + '<br/>' +
    'New Placement Y: ' + placementY + '<br/>' +
    '-----</div>'
  );
}
elemCollision($('.box'));
功能电子碰撞(el){
//视口宽度和高度
var viewportW=window.innerWidth;
var viewportH=window.innerHeight;
//元素宽度和高度
var width=el.innerWidth();
变量高度=el.innerHeight();
//元素位置:顶部、右侧、底部、左侧
var top=el.offset().top;
var left=el.offset().left;
var right=(viewportW-left)+viewportW;
var bottom=(视口-顶部)+视口;
//金额元素不在屏幕上
var offScreenX=(视口W-左)-宽度;
var offScreenY=(视口-顶部)-高度;
//将元件100%定位在屏幕上
VarPlacementX=(视口W-左)-Math.abs(offScreenX);
var placementY=(视口-顶部)-Math.abs(offScreenY);
//指定新的X和Y放置值
$('.box').css({底部:placementY,右侧:placementX});
$('body')。追加(
'----'+'
+ '放置顶部:'+Top+'
'+ '放置权限:'+Right+'
'+ '放置底部:'+Bottom+'
'+ '左放置:'+Left+'
'+ '框宽:'+Width+'
'+ '框高:'+Height+'
'+ '视口宽度:'+viewportW+'
'+ '视口高度:'+viewportH+'
'+ '屏幕外X:'+offScreenX+'
'+ '屏幕外Y:'+屏幕外+'
'+ '新位置X:'+placementX+'
'+ '新位置Y:'+placementY+'
'+ '-----' ); }
将窗口的宽度和高度从innerWidth修改为width和height

// Viewport Width and Height
  var viewportW = window.width;
  var viewportH = window.height;

将底部和左侧的css设置为
0px

这是正确的,因为它是滚动条(即使它看起来不可见)。如果运行此函数():

函数getScrollBarWidth(){ var$outer=$('').css({visibility:'hidden',width:100,overflow:'scroll'}).appendTo('body'), widthWithScroll=$('').css({width:'100%}).appendTo($outer.outerWidth(); $outer.remove(); 返回100-带croll的宽度; };
您将看到滚动条的宽度(是我添加函数的JSFIDLE)。如果在框中保留
position:absolute
,并添加
overflow-y:hidden

因此,为了回答您的问题,由于
绝对
定位相对于父对象(
主体
),并且
主体
的滚动条会影响宽度,因此您没有得到预期的结果。

我的
屏幕外X
的值与您所说的不同,但是滚动条的宽度应该可以弥补它应有的差异。谢谢你,尼克。你的解决方案给了我一个解释,也给了我一些可以帮助我实现我所需要的结果的东西。@Pegues很高兴帮助你!谢谢你的解决方案。这似乎有效,但有一个更好的答案,他们也提供了一些解释。非常感谢。我一定会投你一票。
function getScrollBarWidth () {
    var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
        widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
    $outer.remove();
    return 100 - widthWithScroll;
};