这是小提琴。 https://jsfiddle.net/igor_g/ksjkpg0t/16/
我的目的是在一条颜色条上构建一个滚动条。颜色取自应该滚动的文本。基本上,条带是文本字体中使用的所有颜色的概述。文本是动态生成的,可能非常大而且非常小。我的目的是使滚动条的大小成比例,同时正确滚动。我已经尝试了使用jquery的各种组合,但我似乎无法使滚动条按我想要的方式工作。有时,滚动条似乎没有指向正确的文本段落。如何解决这个问题?
jquery代码如下:
/// here is our plugin declaration
(function ( $ ) {
$.fn.colorScroller = function( options ) {
var settings = $.extend({
replaceBlack: 'rgb(83, 84, 72)',
colorScrollClass: "color-map",
overlayClass: "overlay",
scrollSectionClass: "mapSection",
coloredTextClass: "passage"
}, options );
// assign this(the selector that is calling this function) to container
var container = this;
// getting the height of container
var containerHeight = container.outerHeight(true);
// creating overlay scrolling element
var $overlay = $('<div class="'+settings.overlayClass+'" ></div>')
//creating container for colored parts
var $colorScroll=$('<div class="'+settings.colorScrollClass+'" ></div>')
// appending colormap element after container in DOM
container.after($colorScroll);
// approximate total height of browser vertical scroll buttons
var browserScrollButtons = 26;
// setting height of colorscroll element to the height of container
$colorScroll.outerHeight(container.outerHeight()-browserScrollButtons );
var scrollerHandleMin = 31
// here we are calculating the total height of text elements of container
var totalHeight = 0;
container.children('.'+ settings.coloredTextClass).each(function(){
totalHeight = totalHeight + $(this).outerHeight(true);
});
// calculate height of text empty elements like br or <p></p>
var emptyHeight = 0;
container.children().not('.'+ settings.coloredTextClass).each(function(){
emptyHeight = emptyHeight + $(this).outerHeight(true);
});
// here we are calculating the ratio b/n total height of children of container and the height of color-scroll element
var ratio = totalHeight/$colorScroll.outerHeight();
// here we create a jquery object containing of small divs which will be colored, and associated with each passage div in container
var $mini = $('.'+settings.coloredTextClass, container).map(function(){
// getting the height of passage, setting the height of small div element by dividing by ratio
var heightPassage=$(this).outerHeight(true)/ratio+'px';
// getting the color of passage
var colorPassage=$(this).css('color');
// color change if color is black
if (colorPassage=='rgb(0, 0, 0)')
colorPassage = settings.replaceBlack;
var elem = $('<div class="'+settings.scrollSectionClass+'" style="height:'+heightPassage+'; background-color:'+colorPassage+'" ></div>').get(0)
// returning a jquery object element with class, height and color associated according to previous calculations
return elem
});
// get approximate height of browser scroll bar handle
var browserScrollBarHeight = (containerHeight*(containerHeight-browserScrollButtons ))/(totalHeight + emptyHeight )
browserScrollBarHeight = browserScrollBarHeight > scrollerHandleMin ? browserScrollBarHeight : scrollerHandleMin
// set overlay scroller height to browser scroll handle height
$overlay.outerHeight(browserScrollBarHeight);
var overlayHeight = $overlay.outerHeight();
// appending the minified elements into colorscroll element
$($mini).appendTo($colorScroll);
// appending overlay element into color-scroll element
$colorScroll.append($overlay);
// getting top position of container related to document top
var colorScrollTop = $colorScroll.offset().top+1+parseInt($colorScroll.css('margin-top').replace('px', ''))
// getting multiple to create algorithm for converting top positions
var k = (totalHeight + emptyHeight - containerHeight)/($colorScroll.innerHeight()-overlayHeight)
// attaching draggable to overlay scrolling element, so that it can be moved along color scroll element
$overlay.draggable({
// constrain movement to color-scroll element only
containment: "."+settings.colorScrollClass,
// what to do when overlay is dragged
drag: function() {
// getting top position of overlay related to document top
var top = $(this).offset().top;
container.animate({
// scroll container vertically to the point of overlay top (related to color-scroll element ) associated with text in container
scrollTop: (top-colorScrollTop)*k +'px'
}, 2)
},
});
/// when mouse on color-scroller unbind container scroll and enble draggable
/// when mouse leaves color-scroller bind container scroll and disable draggable
$colorScroll
.mouseenter(function() {
$overlay.draggable('enable')
container.off('scroll', scrollText)
})
.mouseleave(function() {
$overlay.draggable('disable')
container.on('scroll', scrollText)
});
// function triggered when container scrolled, basically scroll the overlay
function scrollText(){
$overlay.animate({
top: container.scrollTop()/k + 'px'
}, 1)
}
container.on('scroll', scrollText)
// when the color-scroll element is clicked
$colorScroll.on('click',function(e){
// calculate the position of click related to color-scroll itself
var topPosition = e.pageY-$(this).offset().top;
// and move overlay top to that position
$overlay.animate({
top: topPosition+'px'
}, 200)
// and scroll container to text associated with overlay top
container.animate({
scrollTop: (topPosition+overlayHeight)*ratio-containerHeight+'px'
}, 10)
})
return container;
};
}( jQuery ));
/// end plugin
$(document).ready(function() {
var passes = [0, 1, 2, 3, 4, 5, 6]
for (var i in passes) {
col = document.getElementById('pass' + i).style.color;
var element = document.createElement("section");
element.style.background = col;
document.getElementById("left").appendChild(element);
}
canvas = document.createElement("canvas");
canvas.id = 'canvas';
canvas.style = 'height:700px;width:50px;';
/// here we init plugin function
$('#document_content').colorScroller({replaceBlack: 'rgb(0,0,0)'});
/// the other option with defaults are :
// colorScrollClass: "color-map", css class of colored scrollbar
// overlayClass: "overlay", css class of the custom scrollbar
// scrollSectionClass: "mapSection", css class of the small colored sections in colored scroll bar
// coloredTextClass: "passage" css class of the original text part
///
});