在页面中虽然可以通过CSS修改滚动条的样式,但是部分属性是无法自己修改和设置的,而且不同浏览器存在兼容问题,因此通过JS来实现滚动条在自定义滚动条 的环境下也是有必要的。
接下来,我们来实现上图两种情况下滚动条的实现。
一、页面搭建
1.1 创建index.html页面
首先创建html页面,代码如下:
滚动条
文章包括各种文体的著作、作品,如诗歌、戏剧、小说、科学论文,记叙文、议论文、说明文、应用文等等。“千古文章未尽才”“文章千古事”“文章憎命达”“板凳要坐十年冷、文章不写一字空”“积句而成章,积章而成篇”“言出为论,下笔成章”等,都是现在所说的文章的意思。更广义的文章,也包含“学问”“奥秘”等意思,如“洞明世事皆学问,人情练达即文章”就是。
“文章”的“章”字,是个会意字,从音从十。古代奏音乐,连奏十段才能结束(十,数之终也),这十段乐就是一章。所以,文章文章,也有段落。文章既从“音乐”里会意出来,应是用文字表达出来的东西,读起来如音乐一样美妙无穷、悦耳动听的文字,传诵开来,才配得上“文章”一词的真正含义。
释义
“文”即“纹”,指“纹路”、“纹样”。“章”本指“屏蔽”,转指“外表”。“文章”原义指“有纹样的表面”,诸如服装上绣绘的龙凤图样、皮肤上针刺的花卉图案,等等。即其原义是指直接构成视觉形象的图样。后指文字所描绘出来的事物图样,需要大脑“解码”才能完整呈现的间接的事物形象。
要素
文章的基本要素——主题、材料、结构、语言,是文章学的主要研究对象,以往各种写作论著论之甚详,但对其概念内涵的揭示似欠斟酌,定义并不严格。新近出版的写作论著,或沿用旧说,或虽有改动而仍值得商榷。本文拟从严格意义上的定义要求出发,结合有关知识,对这四个要素概念的种种“定义”质疑问难,并试提出自己的修正意见,以就教于写作界同行。
拟题中常用的修辞手法和语言技巧主要有以下九种。
1、引用法就是借用俗语、名言或他人诗句等现成的语言材料来拟制标题。引用法分直接引用和变形引用两种情况。
直接引用,就是把引用的语言材料不加改动地直接取来作拟题之用。如理由的《扬眉剑出鞘》,人民日报评论员文章《铁公鸡—一毛不拔》,廖沫沙的《教然后知困》等,都属于这种形式。直接引用比较简单,无须多说。变形引用则非常复杂,需要着重谈谈。
变形引用,就是把引用的语言材料经过加工改造,然后再作拟题之用。变形引用根据不同的加工方式又可分为“反叠式”、“悖论式”、“谐变式”、“镶嵌式”等不同形式。
反叠式变形引用,就是利用其他文章标题、俗语等进行反面重叠,造成一种反叠式的标题。如蒲鲁东曾写有《贫困的哲学》,马克思便利用它写了《哲学的贫困(答蒲鲁东先生的<贫困的哲学>)》,这就是反叠式变形引用。此外,诸如《“回头浪子”帮助浪子回头》,《伯乐相马与马相伯乐》等,也都属于这种形式。反叠式变形引用,内容上可以使标题产生新意,给人以新奇而幽默的感觉,形式上给人以对称的美感。
对常见的俗语、名言进行加工改造,取其反义而用之,形成一种貌似荒谬却又隐含着十分新颖而深刻的意义,这种引用方式叫“悖论式变形引用”。例如“班门弄斧”这句成语一般是用来讽刺那些在行家面前卖弄本事,没有自知之明的人。而一位作者在介绍华罗庚赴美讲学的一篇文章中却拟用了《弄斧必到班门》这样一个标题。为什么呢?因为华罗庚赴美讲学计划讲十个数学专题,为了与美国同行能在更高的层次上进行学术交流,他决定在美国各大学所讲的专题必须是该大学科研中的长项。华罗庚戏称自己这是“弄斧必到班门”,此文作者便取之为题。你看,这个标题与“班门弄斧”的本义正好相悖,却又含义深远,切合于文章内容。此外,诸如《近水楼台不得月》,《曲高未必合寡》,《要有“知人善免”的勇气》等,也都属于这种形式。
谐音式变形引用,就是利用语言的同音现象,将引用的俗语、名言中的个别字词加以替换,造成一种同音异义的语言效果,这种引用方式就叫“谐音式变形引用”。例如1987年1月25日《人民日报·海外版》登载的苏泰的文章《学而优则“侍”》,标题显然是从《论语·子张》中的“学而优则仕”一句变化而来。原来此文主题是赞扬大学生勤工助学,放下架子,课余时间去咖啡厅为顾客服务。此外,如《以“职”论价》与俗语“以质论价”谐音,《爱“才”如命》与成语“爱财如命”谐音,这些标题与原句虽然只是一字之差,却另出新意,醒人耳目。
镶嵌式变形引用,就是利用俗语、名言、古诗词等原有的语句框架,选择一些切合于文章内容的字词填嵌其中,使其另生新意。例如,有篇新闻报道,标题是《助人何必曾相识,精神文明谱新歌》,其中前半句显然出自唐代诗人白居易《琵琶行》诗中的“同是天涯沦落人,相逢何必曾相识”一句,将“助人”二字填嵌其中,便有了新的含义。又如有一篇市场调查,标题为《知否?知否?应是贱肥贵瘦》,显然,这是袭用了宋代诗人李清照《如梦令》词中“知否?知否?应是绿肥红瘦”一句将“贱”、“贵”二字填嵌其中,也使标题陡生新意。
变形引用虽然方式各异,但都能巧妙地利用俗语、名言及古诗词广泛的传播效应,给人一种似曾相识,却又颇含新意的感受,推陈出新,为我所用,使文章标题更具魅力。
2、叠加法所谓“叠加法”,就是在他人文章或言论的基础上,进一步深入研究探讨,以其相同的写作手法写成文章,其标题往往是以相同的语句叠加而成,故称“叠加法”。运用叠加法拟题最常见的一种形式,就是利用他人有关“批评”或“批判”而拟制新的驳论性文章标题。这种标题常常拟为《关于……批评的批评》,这种标题有时也可采用多重否定的形式,但常见的是双重否定形式。此外,诸如《关于启示的启示》,《对于“笑话”的笑话》等,也都是采用叠加法拟题的一种形式。
3、对偶法就是拟题时把结构相同,字数相等的一对句子或词组排列在一起,以表达相关、相联或相反的意思。例如《半月谈》评论员文章《尊师重教,育才兴邦》(1985年第3期),其标题就是采用对偶法拟制的。此外,诸如《运用综合技术开拓未来世界》,《高价水泥一斤不卖计划指标一袋不少》,《卖债券支援国家建设得奖品为您增添喜悦》等,也都是采用对偶法拟制的标题。
采用对偶法拟制的标题,两个句子或词组的意思彼此补充,相互映衬可将文章内容达得更加深刻、鲜明,而且朗读起富有节奏感,能增强标题语言的艺术性。
4、活用动词法文学作品描写人物之所以能给人以深刻的印象,很重要的一点就是作者善于抓住人物富有典型意义的行为动作来进行描写,只有这样才能把人物写“活”。拟制标题也可以采用文学作品描写人物的这种方法,根据文章内容,选取具有典型意义的动态性的词句来拟制标题,着眼于一个“动”字,尽量把题目写“活”例如,有篇文章记叙一位公共汽车女售票员,正确对待一个无理取闹往自己身上吐痰的小青年,从而引起小青年自责的事。如果把题目拟成《售票员风格高尚,乘车人行为可耻》便很一般。而这位作者却不同凡响,将题目拟为《冷静擦去一口痰,微笑震动一颗心》,两相比较,后者就显得格外生动感人。又如有则通报批评某单位制定的服务措施只是挂在墙上而没有落实到行动上,标题是《让措施从墙上“走”下来》。你看,一个“走”字,用得真是恰到好处,平字生辉。
5、虚实结合法这是拟制双行标题所采用的一种拟题方法。大家知道,拟单行标题,作者既可以用平实的文字开门见山地把文章主题或主要内容直接传达给读者,直白陈事,实实在在,不需要任何修饰和点缀;也可以采用形象、含蓄的语句拟题,使标题富有形象性和趣味性,诗情画意,引人遐思。两种方法虽各有千秋,但不免单调,而拟双行标题则可以把这两种方法结合起来使用,使其中一行标题形象、含蓄,另一行标题平实、明快,这就是“虚实结合法”。采用这种方法拟制的标题,其正题一般多采用富有形象性、含蓄性的语句拟制,其作用在于揭示和突出文章的主要内容,副题则采用准确、平实的语句拟制,它对正题具有诊释和限制的作用。例如,发表在《名作欣赏》1986年第3期上的朱炯强的文章
6、设迷法就是采用类似于迷语的方式,在标题中先有意设下一个“迷面”,使读者产生悬念,诱发其想要急切解答的欲望,其“迷底”待阅读全文之后自然揭晓。例如祖慰的文章《赫赫而无名的人生》(《文汇月刊》1987年第6期),题目起得就颇为古怪、有句成语叫“赫赫有名”,“赫赫”乃显赫的意思,用来修饰“有名”,意思是名气很大,声名显赫。既然“赫赫”,何来“无名”?待看过文章之后方才恍然:原来这篇文章是介绍中国导弹核潜艇的总设计师,一位人称“中国核潜艇之父”的科学家的坎坷一生。核潜艇,乃尖端高科技产品,世界上只有极少数国家拥有,而中国已能自行设计、建造,这难道不是轰动全球的赫赫伟业?而高科技军事武器因为是国家保密项目,参与设计、建造的科学家自然也是“无名”的,所以题目就叫“赫赫而无名的人生”。此外,诸如《腰缠万贯的乞丐》,《从未见面的老朋友》,《一位没结婚的男“妈妈”》等,也都是采用设迷法拟制的标题。既然“腰缠万贯”,怎么会是“乞丐”?既然是“老朋友”怎么会没见过面?“妈妈”都是女的,怎么会出来个男的,而且又是“没结婚”的?这些标题都给读者留下了一个悬而未解的疑问,答案只有阅读了文章之后才会知晓。
7、宾语前置法拟制标题常常使用动宾结构的词组或短句的形式。如恩格斯的《论权威》,毛泽东的《论人民民主专政》,吴伯箫的《记一辆纺车》等。但有时为了使标题的形式有所变化,也可以把其中的宾语提到动词前面,变成宾语前置的形式。如马克思的《资本论》,毛泽东的《实践论》,《矛盾论》,薛福成的《观巴黎油画记》,蒸子的《无名礼赞》等。宾语前置式标题与原来的标题比较,只是形式不同,内容并无变化,因此二者可以互换。
8、隔点法运用间隔号把标题中两三个具有某种联系的单词以并列的形式分隔开来,这种拟题方法就叫“隔点法”。例如鲁迅的《猫·狗·鼠》,秦牧的《园林·扇画·散文》,林平的《读书·爱国·修身》(《文汇报》1981年5月3日版)等,都属于这种形式。
运用隔点法拟制的标题,其单词排列整齐、匀称,能给人以美感。另外,这种标题形式还能产生悬念,吸引读者阅读。这种标题一般多适用于杂文、随笔一类的短篇议论文。
9、冒号法近年来在报刊杂志上经常出现一种新的标题形式,这种标题中间都加有一个冒号。例如庄建民的《选美:众说纷纭的话题》(《瞭望》1993年7月26日第30期),《瞭望》杂志社记者文章《1993:在夏收第一线》(《瞭望》1993年7月19日第29期)。
这种标题中的冒号一般具有两个作用:一是表示前面内容是对后面内容的限制;二是表示后面内容是对前面内容某一个方面的诊释、介绍或阐述。一般情况下,这两个作用是同兼的。如上述二例:例一,“选美”是对“众说纷纭的话题”的限制,“众说纷纭的话
题”很多,“选美”只是其一;反过来,“选美”关系到的方面很多,“众说纷纭”只是对其中一个方面的阐述。例二,“1993”是对“在夏收第一线”时间上的限制;而“在夏收第一线”则是对1993年“夏收”这一个方面的介绍和阐述。
拟制冒号标题,一般总是将文字较少的名词或名词性词组放在前面,而将文字较多的动词或名词谓语部分放在后面,如上述二例即是。
运用冒号法拟题,可以准确地揭示文章内容,让凑者在有限的标题文字中获取更多的内容信息,还可以便标题形式更加多样化。这种标题形式在新闻体裁和学术文章中比较多见。
1.2 CSS样式
页面内容添加后,再添加样式文件,创建scroll.css,代码如下:
/**
容器
*/
.container{ width: 100%; font-size: 12px; }
.container::after{ display: block; content: ''; clear: both; }
.scroll-wrap{ width: 500px; height: 500px; overflow: hidden; border: 1px solid #ccc; color: #333; font-size: 14px; color: #666; line-height: 1.8; float: left; }
.scroll-wrap p{ text-indent: 2em; }
此时将scroll.css引入到html代码中,代码如下:
滚动条
1.3 创建scroll.js文件
创建滚动条闭包文件,代码如下:
(function(_win_, _doc_, _$_){
/**
* 定义 自定义滚动条插件
* @param {*} options
*/
_$_.fn.customScroll = function(options){
}
})(window, document, jQuery);
jQuery插件开发有两个方法使用较多,分别是$.fn和$.extend。如以上代码已使用$.fn扩展了customScroll方法,此时可需对外提供相应接口,这时则需要使用到$.extend了,代码如下:
(function(_win_, _doc_, _$_){
/**
* 定义 自定义滚动条插件
* @param {*} options
*/
_$_.fn.customScroll = function(options){
options = $.extend(true, {
wrap: 'scroll-container', //容器
contentVisableBox: 'scroll-content-box', //内容可显示区域
content: 'scroll-content', //内容容器
barBox: 'scroll-bar-box', //滑轨区域
barHandle: 'scroll-bar-handle', //滑轨中手柄
wheelSpeed: 5, //滚轮滑动速度
}, options);
}
})(window, document, jQuery);
注:$.extend第一个参数为true,则表示后面合并对象会进入深度合并,否则只合并对象的第一层属性或方法。
这里我们将对应容器的类名和相应参数对外暴露,以便调用和初始化插件时,可以个性化定制和扩展。
此时我们再将scroll.js引入到html页面中,引入前,必须先引入jquery-3.6.4.min.js,因为咱们插件时基于jquery基础上开发的,代码如下:
滚动条
二、功能开发
实现自定义滚动条结构如下图,通过此图我们可以更清晰了解页面代码。
2.1 初始化页面结构
如上图,当用户引用自定义滚动条插件时,为了更方便使用,则上图结构我们通过js来实现,代码如下:
(function(_win_, _doc_, _$_){
/**
* 定义 自定义滚动条插件
* @param {*} options
*/
_$_.fn.customScroll = function(options){
options = $.extend(true, {
wrap: 'scroll-container', //容器
contentVisableBox: 'scroll-content-box', //内容可显示区域
content: 'scroll-content', //内容容器
barBox: 'scroll-bar-box', //滑轨区域
barHandle: 'scroll-bar-handle', //滑轨中手柄
wheelSpeed: 5, //滚轮滑动速度
}, options);
var _html = $(this).html(),
//创建容器DOM
_scrollWrap = $('
').addClass(options.wrap),
//创建 内容可显示区域 DOM
_contentVisableBox = $('
').addClass(options.contentVisableBox),
//创建 内容容器 DOM
_content = $('
').addClass(options.content),
//创建滑轨区域 DOM
_scrollBarBox = $('
').addClass(options.barBox),
//创建 滑轨中手柄 DOM
_scrollHandle = $('
').addClass(options.barHandle);
//内容添加到内容容器中
_content.html(_html);
//内容追加到 内容可显示区域中
_content.appendTo(_contentVisableBox);
//手柄添加到滑轨区域中
_scrollHandle.appendTo(_scrollBarBox);
//内容可见区域添加到容器中
_scrollWrap.append(_contentVisableBox);
//滑轨区域添加到容器中
_scrollWrap.append(_scrollBarBox);
//替换原内容区域
$(this).replaceWith(_scrollWrap);
}
})(window, document, jQuery);
以上代码大家可能还不太理解,这块给大家分析下,
以上DOM结构,对应上面结构图内容,不太明白的,可以对照多看几遍。
wrap对应DOM则为结构图中最外层大容器;
contentVisableBox对应DOM为内容可见区域,超出部分影响;后面内容滚动绑定scrollTop则在该DOM上
content对应DOM为内容存放区域,内容实际高度,则需在DOM上获取;
barBox对应DOM滚动条可滚动区域,滚动条手柄只能在该区域滑动;
barHandle对应DOM为滚动条手柄,鼠标点击移动区域执行上下拖动功能
wheelSpeed为滚轮滑动的速度
2.2 添加样式
此时我们再增加初始化后,自定义滚动条区域的样式添加到scroll.css中,代码如下:
/* scroll-container */
.scroll-container{ height: 100%; position: relative; padding-right: 10px; }
/* scroll-content */
.scroll-container .scroll-content{ position: relative; padding: 15px; }
/* scroll-content-box */
.scroll-container .scroll-content-box{ width: 100%; height: 100%; overflow: hidden; }
/* scroll-bar-box */
.scroll-container .scroll-bar-box{ width: 10px; height: 100%; padding: 1px; box-sizing: border-box; background-color: #eee; border-left: 1px solid #ccc; position: absolute; top: 0; right: 0; z-index: 10; }
.scroll-container .scroll-bar-box .scroll-bar-handle{ width: 100%; height: 100px; background-color: #ccc; border-radius: 10px; position: relative; left: 0; top: 0; z-index: 1; }
这里自定义滚动条样式直接放在页面样式中,如果你希望开发一套独立的插件,可以将样式和js代码进行剥离,单独编写,方便后期引用和维护。
2.3 滚动条插件初始化
此时,自定义滚动条插件函数已定义,样式也添加好了,可以在页面初始化插件了。在body标签尾部,添加script代码,代码如下:
现在页面效果如下图:
初始化后html结构如下:
2.4 定义变量
定义滚动条移动中所需要的变量,代码如下:
(function(_win_, _doc_, _$_){
/**
* 定义 自定义滚动条插件
* @param {*} options
*/
_$_.fn.customScroll = function(options){
options = $.extend(true, {
wrap: 'scroll-container', //容器
contentVisableBox: 'scroll-content-box', //内容可显示区域
content: 'scroll-content', //内容容器
barBox: 'scroll-bar-box', //滑轨区域
barHandle: 'scroll-bar-handle', //滑轨中手柄
wheelSpeed: 5, //滚轮滑动速度
}, options);
//略...
//替换原内容区域
$(this).replaceWith(_scrollWrap);
var slideHeightLimit = 0, //滑轨可移动高度
slideHeight = 0, //滑轨区域高度
slideHandleHeight = 0, //滑轨手柄高度
contentVisibleHeight = 0, //内容可见区域
contentHeight = 0, //内容实际高度
startTop = 0, //滑轨手柄移动位置
startPageY = 0, //当前点击时鼠标点击的位置
flag = false;
}
})(window, document, jQuery);
2.5 获取对应参数
在插件中定义initialData()函数,用来获取2.4中所定义变量数据,代码如下:
(function(_win_, _doc_, _$_){
/**
* 定义 自定义滚动条插件
* @param {*} options
*/
_$_.fn.customScroll = function(options){
options = $.extend(true, {
wrap: 'scroll-container', //容器
contentVisableBox: 'scroll-content-box', //内容可显示区域
content: 'scroll-content', //内容容器
barBox: 'scroll-bar-box', //滑轨区域
barHandle: 'scroll-bar-handle', //滑轨中手柄
wheelSpeed: 5, //滚轮滑动速度
}, options);
//略...
//替换原内容区域
$(this).replaceWith(_scrollWrap);
var slideHeightLimit = 0, //滑轨可移动高度
slideHeight = 0, //滑轨区域高度
slideHandleHeight = 0, //滑轨手柄高度
contentVisibleHeight = 0, //内容可见区域
contentHeight = 0, //内容实际高度
ratio = 0, //滑轨区域高度与内容高度 比例
startTop = 0, //滑轨手柄移动位置
startPageY = 0, //当前点击时鼠标点击的位置
flag = false;
/**
* 初始化数据
*/
function initialData(){
slideHeight = _scrollBarBox.height(); //滑轨区域高度
contentHeight = _content.height(); //内容实际高度
ratio = slideHeight / contentHeight; //比例
slideHandleHeight = ratio * slideHeight; //滑轨手柄高度
slideHeightLimit = slideHeight - slideHandleHeight; //计算滑块可活动范围
startTop = parseInt(_scrollHandle.css('top')); //获取滑块top开始位置
//根据比例设置手柄高度
_scrollHandle.height(slideHandleHeight);
}
//执行初始化函数
initialData();
}
})(window, document, jQuery);
以上数据初始化,刷新页面发现还没啥变量,只有滚动条手柄高度在DOM上重新设定了,如下图:
2.6 实现拖放滚动事件
在实现自定义滚动条事件,我们需要使用到mousedown、mousemove、mouseup三个事件,我们使用jquery方法来添加这三个事件,代码如下:
(function(_win_, _doc_, _$_){
/**
* 定义 自定义滚动条插件
* @param {*} options
*/
_$_.fn.customScroll = function(options){
options = $.extend(true, {
wrap: 'scroll-container', //容器
contentVisableBox: 'scroll-content-box', //内容可显示区域
content: 'scroll-content', //内容容器
barBox: 'scroll-bar-box', //滑轨区域
barHandle: 'scroll-bar-handle', //滑轨中手柄
wheelSpeed: 5, //滚轮滑动速度
}, options);
var _html = $(this).html(),
//创建容器DOM
_scrollWrap = $('
').addClass(options.wrap),
//创建 内容可显示区域 DOM
_contentVisableBox = $('
').addClass(options.contentVisableBox),
//创建 内容容器 DOM
_content = $('
').addClass(options.content),
//创建滑轨区域 DOM
_scrollBarBox = $('
').addClass(options.barBox),
//创建 滑轨中手柄 DOM
_scrollHandle = $('
').addClass(options.barHandle);
//略...
var slideHeightLimit = 0, //滑轨可移动高度
slideHeight = 0, //滑轨区域高度
slideHandleHeight = 0, //滑轨手柄高度
contentVisibleHeight = 0, //内容可见区域
contentHeight = 0, //内容实际高度
ratio = 0, //滑轨区域高度与内容高度 比例
startTop = 0, //滑轨手柄移动位置
startPageY = 0, //当前点击时鼠标点击的位置
flag = false;
/**
* 初始化数据
*/
function initialData(){
slideHeight = _scrollBarBox.height(); //滑轨区域高度
contentHeight = _content.height(); //内容实际高度
contentVisibleHeight = _contentVisableBox.height(); //内容可见区域
ratio = slideHeight / contentHeight; //比例
slideHandleHeight = ratio * slideHeight; //滑轨手柄高度
slideHeightLimit = slideHeight - slideHandleHeight; //计算滑块可活动范围
startTop = parseInt(_scrollHandle.css('top')); //获取滑块top开始位置
//根据比例设置手柄高度
_scrollHandle.height(slideHandleHeight);
}
//执行初始化函数
initialData();
//添加监听鼠标点击事件
_scrollHandle.on('mousedown', function(e){
e.preventDefault();
flag = true; //标识开始滑动
startPageY = e.pageY; //获取鼠标开始位置
});
//添加监听鼠标滚动事件
$(_doc_).on('mousemove', function(e){
if(flag){
//do something...
}
});
//添加监听鼠标放开事件
$(_doc_).on('mouseup', function(e){
flag = false;
});
}
})(window, document, jQuery);
当点击mousedown事件时,标记启动滚动条滑动事件,将flag赋值为true,并获取点击手柄时鼠标点击的pageY坐标位置,并赋值给startPageY。
当鼠标点击不放并移动时,mousemove事件中判断flag为true时执行,并修改滚动条手柄相关参数。
当鼠标放开时,并flag赋值为false,表示停止滑动,释放事件。
2.7 计算滚动范围并赋值
以上事件已经添加了,但现在滚动条还无法拖动,这里我们需要通过计算并赋值修改相应参数,使滚动条手柄和内容进行移动。这里手柄我们通过postion定准,修改其top位置;内容区域修改可见区域的scrollTop实现内容滚动。这里定位 moveScroll()函数,来处理此操作。在initialData函数后面追加以下代码:
/**
* 移动滑块和内容区域 功能函数
* @param {*} moveLen
* @param {*} moveContLen
*/
function moveScroll(moveLen, moveContLen){
//获取最新滑块位置
var _top = parseInt(_scrollHandle.css('top'));
//在滑块可移动范围内
if(moveLen>0&&moveLen=slideHeightLimit){
_scrollHandle.css({top: slideHeightLimit + 'px' });
_contentVisableBox.scrollTop(contentHeight);
}
}
以上写法可能会存在不足之处,大家有更好算法或写法可按自己需求进行编写。
此时将initialData()放到mousedown事件中,以防页面dom未加载完成,或后期内容被动态修改,所以在执行滑动前重新获取初始数据。
将moveScroll()函数放到mousemove事件,当标记flag为true时,执行滚动条手柄和内容移动操作。
代码如下:
//添加监听鼠标点击事件
_scrollHandle.on('mousedown', function(e){
e.preventDefault();
flag = true; //标识开始滑动
startPageY = e.pageY; //获取鼠标开始位置
initialData(); //重新获取内容比例
});
//添加监听鼠标滚动事件
$(_doc_).on('mousemove', function(e){
if(flag){
var moveLen = e.pageY - startPageY + startTop, //计算滑块移动位置
moveContLen = moveLen / ratio; //通过手柄位置计算内容移动位置
//开始移动
moveScroll(moveLen, moveContLen);
}
});
//添加监听鼠标放开事件
$(_doc_).on('mouseup', function(e){
flag = false;
});
写了这么久,自定义滚动条终于完成,可以点击拖放滑动了。
2.8 滚轮事件
浏览器中,我们可以通过鼠标滚轮上下滑动翻看内容,这里在自定义滚动条功能中也可以实现,为了兼容浏览器,并使用jquery进行监听,代码如下:
//监听滚动事件
_scrollWrap.on('mousewheel DOMMouseScroll', function(e){
e.preventDefault();
initialData(); //初始化数据
var oEv = e.originalEvent,
wheelRange = oEv.wheelDelta ? -oEv.wheelDelta/120 : (oEv.detail || 0)/3,
moveLen = startTop + (wheelRange * options.wheelSpeed),
moveContLen = moveLen / ratio;
//开始移动
moveScroll(moveLen, moveContLen);
});
给滚动条区域最外层容器上添加监听事件,当监听到滚动事件时,初始化所要数据,并且计算wheelRange值,用来判断滚轮是向上,还是向下移动。向下wheelRange值为1,向上值为-1。
wheelSpeed变量,我们之前在options中已对外开放,这里默认为5,如果觉得速度太慢,可以在初始化时,修改此变量,代码如下:
此时options中wheelSpeed参数值已被修改,如下图:
到这里,自定义滚动条功能已完成,在页面中可以拖动滚动条手柄进行上班移动,也可以通过滚轮进行上下翻看内容了。
三、TAB标签
3.1 添加tab结构html
在html页面中,container类容器中添加tab代码,代码如下:
.3.2 添加tab样式
在scroll.css中追加tab样式,代码如下:
/* scroll-tab-wrap */
.scroll-tab-wrap{ width: 500px; border: 1px solid #ccc; color: #333; font-size: 14px; color: #666; line-height: 1.8; float: right; }
.scroll-tab-wrap p{ text-indent: 2em; margin: 0; }
.scroll-tab-wrap .tab-container{ height: 450px; overflow: hidden; }
.scroll-tab-wrap .tab-container .tab-panel{ height: 100%; overflow: hidden; }
.nav-list-box{ width: 100%; padding-bottom: 15px; }
.nav-list-box::after{ display: block; content: ''; clear: both; }
.nav-list-box .list-item{ margin: 0 20px; padding: 10px; cursor: pointer; float: left; }
.nav-list-box .list-item p{ text-indent: 0; }
.nav-list-box .list-item.active{ font-weight: bold; border-bottom: 2px solid #333; }
3.3 添加tab切换事件
这里就在html页面中script添加tab切换事件了,代码如下;
此时点击文章一或文章二内容则可以切换了。
其实Tab切换也可以单独写套插件进行复用,像bootstrap里也有Tab组件,这里主要讲自定义滚动条,就不细讲Tab切换的封装方法,先简单实现下。
3.4 添加自定义滚动条功能
给tab标签对应的tab-panel区域中内容,添加自定义滚动条,代码如下:
页面效果如下:
大家在切换时会发现,当在文章一中滚动条手柄滑到某位置后,切换到文章二中操作,再切换回文章一,还在上次停留位置。如果切换回需还原初始位置,方法也很简单,这块就留给大家自己实现了。