Почему jQuery.position () ведет себя по-разному между webkit и firefox / MSIE - PullRequest
1 голос
/ 05 февраля 2010

Вот длинный. Я пытаюсь реализовать горизонтальную прокрутку на моем сайте. Он отлично работает в Safari и Chrome, но не в Firefox (пока не начну с проблем IE).

Из того, что я могу сказать, Webkit использует относительное положение элемента захвата полосы прокрутки, в то время как firefox занимает свое положение относительно документа.

Вы можете проверить это здесь , чтобы увидеть, что происходит.

Вот 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 Ответ

1 голос
/ 05 февраля 2010

Я немного повозился с вашим кодом, думаю, проблема в том, что position.left возвращает положение объекта относительно окна, а оно возвращало положение полосы прокрутки. Так что просто изменение переменной позиции с #scrollbar на #grabber сработало для меня.

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

и из-за этого вам не нужно сохранять позицию grabberStart

Наконец, по какой-то причине, и мне потребовалось некоторое время, чтобы понять, что IE не любит привязку к window событиям. Поэтому я переключил их на document и БАМ! IE работает отлично.

Вот ваш скрипт, обновленный с упомянутыми мною изменениями. Кстати, красивый сайт!

// **********************************************
// 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...