代码之家  ›  专栏  ›  技术社区  ›  gargantuan

为什么jquery.position()在webkit和firefox/msie之间的行为不同?

  •  1
  • gargantuan  · 技术社区  · 15 年前

    这是一个长的。我正在尝试在我的站点中实现水平滚动。它在Safari和Chrome中工作得很好,但在Firefox中却不行(我现在还不能开始讨论IE的问题)。

    据我所知,webkit使用的是滚动条抓取器div的相对位置,而firefox使用的是它相对于文档的位置。

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

    这是滚动条的CSS

    /* 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

    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);
    }
    

    有什么想法吗?我知道我应该知道这个问题的答案,但我盯着它看了这么久,我对它视而不见。

    干杯

    1 回复  |  直到 15 年前
        1
  •  1
  •   Mottie    15 年前

    我对你的代码有点乱,我想问题是 position.left 返回对象相对于窗口的位置,并返回滚动条位置。所以只要改变位置变量 #scrollbar #grabber 为我工作。

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

    因此,您不需要保存 grabberStart 位置

    最后,由于某种原因,我花了一段时间才弄明白 window 事件。所以我把它们换成 document 巴姆!我工作得很好。

    这是用我提到的更改更新的脚本。顺便说一下,这个网站看起来不错!

    // **********************************************
    // Throll: Toms Horizontal Scroll 
    // Developer: Tom Elders
    // Contact: him@tomelders.com
    // **********************************************
    // 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);
    }