为什么jQuery.position()在webkit和firefox/MSIE之间的行为不同

问题描述:

这是一个很长的例子。我试图在我的网站中实现水平滚动。它在Safari和Chrome中运行良好,但在Firefox中无法运行(我还没有开始讨论IE的问题)。为什么jQuery.position()在webkit和firefox/MSIE之间的行为不同

从我所知道的情况来看,Webkit使用的是滚动条抓取器div的相对位置,而firefox则是将其相对于文档的位置。

You can test it here看看发生了什么。

这里的滚动条

/* The Scrollbar */ 
#scrollbar 
{ 
    position: relative; 
    width: 70%; 
    display: block; 
    margin: 0px auto; 
    border: #444444 1px solid; 
    border-width: 0 0 1px 0; 
    overflow: visible; 
} 

#grabber 
{ 
    position: relative; 
    top: 8px; 
    left: 0px; 
    height: 20px; 
    display: block; 
    background: url(assets/grabber-left.png) no-repeat; 
} 

#grabber-end 
{ 
    height: inherit; 
    width: 50%; 
    background: url(assets/grabber-right.png) no-repeat; 
    background-position: 100% 0; 
    float: right; 
} 

而jQuery的CSS的是权力,它

var grabberClicked = false; 
var dragStart; 
var grabberStart; 
var ratio; 
var scrollBound; 
var totalWidth = 0; 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

$(document).ready(function(){ 

    $("#projects").width(getTotalWidth()); 
    setup(); 
    $("#grabber").mousedown(startScroll); 
    $(window).mouseup(endScroll); 
    $("#viewport").scroll(positionGrabber); 
    $(window).resize(setup); 


}); 

function getTotalWidth(){ 

    $(".project").each(function(){ 

     totalWidth += $(this).width(); 
     totalWidth += parseInt($(this).css("marginLeft")) * 2; 

    }) 

    return totalWidth; 

} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function setup(){ 
    ratio = $("#viewport").width()/$("#projects").width(); 

    // grabber width 
    $("#grabber").width($("#scrollbar").width() * ratio); 
    scrollBound = $("#scrollbar").width() - $("#grabber").width(); 

    // incase the user resizes the window, position the grabber accordingly 
    positionGrabber(); 
} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function startScroll(event){ 
    $(window).bind('mousemove', scroll); 
    var position = $("#scrollbar").position(); 
    dragStart = event.pageX - position.left; 
    grabberStart = parseInt($("#grabber").css("left")); 
    $("#feedback").html($("#grabber").position().left); 
} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function endScroll(event){ 
    $(window).unbind('mousemove', scroll); 
} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function scroll(event){ 
    var newPos = grabberStart + (event.pageX - dragStart); 
    //$("#feedback").html($("#grabber").position().left +" // "+ newPos); 

    // bounds 
    newPos = (newPos > 0) ? newPos : 0; 
    newPos = (newPos < scrollBound) ? newPos : scrollBound; 

    viewportPos = ($("#projects").width() * (newPos/$("#scrollbar").width())); 
    $("#viewport").scrollLeft(viewportPos); 
    $("#grabber").css("left", newPos); 

} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function positionGrabber(event){ 
    var grabberPos = $("#scrollbar").width() * ($("#viewport").scrollLeft()/$("#projects").width()); 
    $("#grabber").css("left", grabberPos); 
} 

任何想法?我知道我应该知道这个答案,但是我一直盯着它,只是我对此一窍不通。

欢呼

我搞砸周围的代码了一下,我觉得这个问题是position.left返回相对于窗口对象的位置,这是返回滚动条位置。所以只需将位置变量从#scrollbar更改为#grabber就可以了。

var position = $("#grabber").position(); 

也正因为如此,你并不需要保存grabberStart位置

最后,出于某种原因,这花了我一段时间来弄清楚,IE不喜欢结合window事件。所以我将它们切换到document和BAM! IE正在完美工作。

这里是你脚本更新我提到的变化。顺便看看漂亮的网站!

// ********************************************** 
// Throll: Toms Horizontal Scroll 
// Developer: Tom Elders 
// Contact: [email protected] 
// ********************************************** 
// File: throll.1.0.js 
// Description: 
// CSS and JS horizontal scriolling that doesn't 
// break the browers native functionality. 
// 
// Copyright 2010, Tom Elders 
// 
// ********************************************** 

var grabberClicked = false; 
var dragStart; 
var ratio; 
var scrollBound; 
var totalWidth = 0; 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

$(document).ready(function(){ 

    $("#projects").width(getTotalWidth()); 
    setup(); 
    $("#grabber").mousedown(startScroll); 
    $(document).mouseup(endScroll); 
    $("#viewport").scroll(positionGrabber); 
    $(window).resize(setup); 


}); 

function getTotalWidth(){ 

    $(".project").each(function(){ 

     totalWidth += $(this).width(); 
     totalWidth += parseInt($(this).css("marginLeft")) * 2; 

    }) 

    return totalWidth; 

} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function setup(){ 
    ratio = $("#viewport").width()/$("#projects").width(); 

    // grabber width 
    $("#grabber").width($("#scrollbar").width() * ratio); 
    scrollBound = $("#scrollbar").width() - $("#grabber").width(); 

    // incase the user resizes the window, position the grabber accordingly 
    positionGrabber(); 
} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function startScroll(event){ 
    $(document).bind('mousemove', scroll); 
    var position = $("#grabber").position(); 
    dragStart = event.pageX - position.left; 
} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function endScroll(event){ 
    $(document).unbind('mousemove', scroll); 
} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function scroll(event){ 
    var newPos = event.pageX - dragStart; 

    // bounds 
    newPos = (newPos > 0) ? newPos : 0; 
    newPos = (newPos < scrollBound) ? newPos : scrollBound; 

    viewportPos = ($("#projects").width() * (newPos/$("#scrollbar").width())); 
    $("#viewport").scrollLeft(viewportPos); 
    $("#grabber").css("left", newPos); 

} 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function positionGrabber(event){ 
    var grabberPos = $("#scrollbar").width() * ($("#viewport").scrollLeft()/$("#projects").width()); 
    $("#grabber").css("left", grabberPos); 
}