Вертикальные настраиваемые полосы прокрутки с JqueryTools RangeInput

Я пытаюсь заменить встроенную полосу прокрутки браузера с помощью функции rangeinput JqueryTools.

Вот пример страницы: http://conceptionkit.co.uk/ck/support

На странице есть несколько прокручиваемых div со следующей структурой html:

<div class="scrollwrap"><!-- scrollwrap doesn't move and has overflow:hidden -->

   <div class="scroll"><!- this is the scrollable pane --></div>

    <!-- this is the rangecontrol that is converted into a 
                            vertical scrollbar by the script -->
   <input class="hide" type="range" max="300" step="1" />

</div>

Для одного экземпляра на странице работает следующий код:

var scroll = jQuery(".scroll");

// initialize rangeinput
jQuery(":range").rangeinput({

  // slide the DIV along with the range using jQuery css() method
  onSlide: function(ev, step)  { scroll.css({bottom: -step});},

  // display progressbar
  progress: true,

  // initial value. also sets the DIV initial scroll position
  value: 100,

  // this is called when the slider is clicked. we animate the DIV
  change: function(e, i) { scroll.animate({bottom: -i}, "fast");},

  // disable drag handle animation when when slider is clicked
  speed: 0
}); 

Однако, когда я пытаюсь обобщить сценарий, он не работает. Я думаю, что проблема заключается в наличии нескольких экземпляров переменной с именем «прокрутка». Может они конфликтуют?

Вот моя попытка создать скрипт для размещения полос прокрутки на всех экземплярах прокрутки на странице. Поскольку мне нужно сопоставить каждый ввод диапазона с правильной панелью, он перебирает jQuery(".scrollwrap").each() и находит панель прокрутки и элемент управления диапазоном в каждой из них:

// default style for .scroll is overflow:auto for no-js browsers.
// must turn that off first
jQuery(".scroll").css('overflow','hidden');

jQuery(".scrollwrap").css('overflow','hidden').each(function(index){

    // Inject range control element
    jQuery(this).append('<input class="hide" type="range" max="300" step="1" />');

    var scroll = jQuery(".scroll",this);

    // initialize rangeinput
    jQuery(":range", this).rangeinput({

      // slide the DIV along with the range using jQuery css() method
      onSlide: function(ev, step)  { scroll.css({top: -step});},

      // display progressbar
      progress: true,

      // initial value. also sets the DIV initial scroll position
      value: 100,

      // this is called when the slider is clicked. we animate the DIV
      change: function(e, i) { scroll.animate({top: -i}, "fast");},

      // disable drag handle animation when when slider is clicked
      speed: 0
    });             

});

Приведенный выше сценарий не генерирует никаких ошибок, он создает элемент управления ползунком, но перемещение слайда не приводит к перемещению соответствующего элемента div .scroll.

Что я здесь делаю неправильно?


person Ken Griffith    schedule 21.01.2012    source источник


Ответы (1)


Приведенный выше код javascript действительно работал, проблема была в css. Вот необходимый css, чтобы заставить его работать. Примечание: этот css устанавливает div .scroll для использования полосы прокрутки браузера по умолчанию. Если js включен, то мы изменим стили, чтобы он работал.

    .scrollwrap, .panes > div.scrollwrap {
        position:relative;
        overflow:hidden;
        padding-right:50px;
        height:250px;
    }

    .scroll {
        height:250px;
        overflow:auto;
        position:relative;
        width:610px;
    }

/* height is now larger than width  */
.slider {
    background:#ccc; 
    cursor:pointer;
    border:none;
    margin-top:10px;
    border-radius:5px; 
    height:220px;
    width:9px;
    margin:0 0 0 60px;

    position:absolute;
    right:18px;
    top:10px;
}

    /* tweak drag handle position */
.handle {
    background:#09C; 
    height:28px;
    width:8px;
    position:absolute; 
    display:block; 
    margin-top:1px;
    cursor:move;
    border-radius:3px;
    box-shdow:2px 0px 2px rgba(0,0,0,0.5);

    top:0;
    left:1px;       
}

/* position progressbar on the bottom edge */
.progress {
        width:9px; 
        position:absolute;
        bottom:0;   
}

Вот важные элементы:

  1. Элемент div .scrollwrap должен иметь заданную высоту, скрытое переполнение и позицию (относительную или абсолютную). Это «окно», через которое вы смотрите, чтобы увидеть прокручиваемый div за ним.

  2. Div .scroll должен иметь положение (относительное или абсолютное), и изначально вы устанавливаете для него заданную высоту и переполнение: авто, поэтому он будет работать с отключенным javascript.

  3. Как только ваш скрипт загрузится, первое, что вы сделаете, это измените свойства .scroll так, чтобы высота:авто и переполнение:скрыто. Это заставит div занять всю длину.

Вот переработанный скрипт Initialize, который мне подходит:

jQuery(".scrollwrap").each(function(index){

    var scroll = jQuery(".scroll",this);

    vheight = scroll.css({overflow:'hidden', height:'auto'}).height();

        // Inject range control element
        jQuery(this).append(
               '<input class="hide" type="range" max="' + vheight + '" step="' 
                  + (vheight/220) + '" />');

        // initialize rangeinput
        jQuery(":range", this).rangeinput({

          // slide the DIV along with the range using jQuery css() method
          onSlide: function(ev, step)  { scroll.css({top: step});},

          // display progressbar
          progress: true,

          // initial value. also sets the DIV initial scroll position
          value: 0,

          // this is called when the slider is clicked. we animate the DIV
          change: function(e, i) { scroll.animate({top: i}, "fast");},

          // disable drag handle animation when when slider is clicked
          speed: 0
        });             

});

Примечание. У меня все еще возникают проблемы с использованием переменной vheight для измерения высоты слайда, чтобы правильно масштабировать полосу прокрутки. Если содержимое загружено не полностью или если javascript заполняет контейнер слайдов, скажем, с помощью аккордеона переменной высоты, этот метод, похоже, неправильно вычисляет высоту. Его нужно поставить в очередь, чтобы запустить последним.

Кроме того, я делю vheight на 220, что является высотой элемента ползунка, чтобы получить размер шага.

Также было бы хорошо прикрепить функцию к div, если размер изменится, чтобы пересчитать высоту, а затем соответствующим образом обновить полосу прокрутки.

Я буду публиковать улучшения по мере их разработки.

person Ken Griffith    schedule 24.01.2012
comment
Привет, ваш код помог мне создать пользовательскую полосу прокрутки, как я и хотел, спасибо. Удалось ли вам внести эти улучшения в свой код? Если да, то будет здорово, если вы поделитесь ими ;) - person Metafaniel; 19.04.2013