甜甜的泥土

自定义滚动条

555《吕氏春秋》记载了一则故事。鲁国有一项政策:如果有鲁人在其他诸侯国沦为奴隶,本国人可以将其赎回来,从政府领取所花费的金钱。有一次子贡从外面赎回了一些人,他是富豪,不在乎那些钱,或许也觉得计较那些钱有损于自己的清德,于是就推让不受。这本来可以理解为高尚的行为,却遭到孔子的批评。因为普通人并不像子贡那样有钱,让他们自己掏腰包赎人,政府给钱也不要,他们会感到为难,结果只能是视而不见。鲁国一项很好的政策,却因为子贡的“高风亮节”,实质上遭到了破坏。而更严重的是,这还损害了鲁人的道德风俗,因为人们将逐渐习惯自己的冷漠。

孔子对子贡的批评,包含了一种既简单又深刻的思考:道德的价值,在于它能够维护某种公众利益,如果脱离实际去提高道德标准,将道德自身视为目的,其结果足以破坏道德存在的基础。中国几十年前很努力地宣扬“无私”的理念,“文革”中更是发展到戏剧化的程度,结果是人人演戏,可信的道德就在这种表演中消失了。

《论语》中有一段对话也值得一说。有位叶公告诉孔子:他的家乡有个做父亲的偷了别人的羊,儿子就去告发,大家都认为他很正直。孔子针锋相对地说:我们那里对正直的看法不是这样,我们认为“父为子隐,子为父隐”,正直就在其中。对孔子的这段话历来有很多争议,现代更有人严厉批评这是以亲情破坏法制。但其实孔子的意见牵涉到法律与伦理的一些根本问题。

在孔子看来,亲情是人类的天性,维护亲情也就是维护社会伦理的根本基础。父子之间、夫妻之间相互告发,其带来的伦理损害要远远大于偷羊之类错误行为所带来的伦理损害。用孟德斯鸠的话来说,就是:“妻子怎能告发她的丈夫呢?儿子怎能告发他的父亲呢?为了要对一种罪恶的行为进行报复,法律竟规定出一种更为罪恶的行为……为了保存风纪,反而破坏人性,而人性却是风纪的泉源。”

当然,中国自古就有“大义灭亲”之说。问题是“大义”必须大到超过维护亲情的必要。所以孔子谈论“父子相隐”的道理,取的是“攘羊”这样的例子。你不能说孔子不反对偷羊,但这和“大义”毕竟还有很远的距离。“文革”中鼓励人们相互揭发,芝麻绿豆、扯皮撒谎皆往“大义”上靠,弄到夫妻在床上关了灯都不敢放胆胡说,这时想到“父子相隐”,就会明白它的道理了吧。

《史记·孔子世家》记述孔子经过蒲地去卫国都城,当地有公叔氏发动叛乱,阻止孔子去卫,意思大概是怕对自己有所不利。于是孔子和他们立下盟誓,答应离开蒲以后不去卫。 结果才出东门,孔子就下令车子向卫驰去。子贡疑惑地问:这不是背盟了吗?孔子淡然一笑,洒脱得很:受要挟订下的盟誓,不管用的。用现代法律的概念来说,就是在不能表达本人真实意志的情况下签订的文书不具法律效力。

上面说的三件事,性质都有些不同,但都表现了孔子的一种性格特点、思想特点,就是不用极端的、偏执的态度来看待道德问题。我对孔子,不像有些人崇敬得那么厉害,但很喜欢他的温厚与看重常情常理,觉得他是一位好老头。五四新文化运动时期,周作人曾经有一些非常重要的议论,其中一点是健康的道德必须建立在正常的人情、人性的基础之上。回头看孔子,他没有背离这个道理,儒家理论,有许多是到了后来才演化得苛酷乃至奇怪的。

                    
(function(){
    function ScrollBar(opt){
        this.opt = opt || {};
        this.scrollBox = document.getElementsByClassName(this.opt.elem)[0];
        this.scrollBar = this.scrollBox.getElementsByClassName('scroll-bar')[0];
        this.scrollBtn = this.scrollBox.getElementsByClassName('scroll-btn')[0];
        this.scrollCon = this.scrollBox.getElementsByClassName('scroll-con')[0];

        this.scrollBtnHeight = this.scrollBtn.offsetHeight;         // 按钮的高度
        this.scrollBoxHeight = this.scrollBox.offsetHeight;         // 容器的高度
        this.scrollBarHeight = this.scrollBoxHeight;                // 滚动条的高度
        this.scrollConHeight = this.scrollCon.scrollHeight - this.scrollBoxHeight; // 文章可以滚动内容高度

        this.MAXDIS = this.scrollBarHeight - this.scrollBtnHeight;  // 可拖动最大距离
        this.scrollBarPosition = this.scrollBar.getBoundingClientRect().top; // 滚动条基于文档的Y距离
        this.mouseClickPosition;                                    // 鼠标点击在按钮的距离
        this.init();
    }
    ScrollBar.prototype = {
        scrollTop:function(dis){

            var self = this;
            var _scrollTop = dis * self.scrollConHeight / self.MAXDIS;
            self.scrollCon.scrollTop = _scrollTop;
        },
        atuoMoveBtn:function(scrollTop){
            var self = this;
            var _moveY = scrollTop * self.MAXDIS / self.scrollConHeight;
            self.scrollBtn.style.top = _moveY + 'px';
        },
        mouseMoveEvent:function(event){
            var self = this;
            var dis = event.clientY - self.scrollBarPosition - self.mouseClickPosition;

            // 限制范围
            dis > self.MAXDIS && (dis = self.MAXDIS);
            dis < 0 && (dis = 0);

            self.scrollBtn.style.top = dis + 'px'; 
            
            self.scrollTop(dis);
        },
        mouseUpEvent:function(event){
            var self = this;
            self.scrollCon.classList.remove('scrolling');
            document.removeEventListener('mousemove',self._MoveEvent,false);
            document.removeEventListener('mouseup',self._UpEvent,false);
            
        },
        wheelEvent:function(event){
            var self = this;
            var e = event || window.event;
            var deltaY = e.deltaY * -30  ||    // wheel 事件
                         e.wheelDeltaY/4 ||    // mousewheel 事件  chrome
            (e.wheelDeltaY === undefined &&    // 如果没有2D属性
                         e.wheelDelta/4) ||    // 那么就用1D的滚轮属性
                          e.detail * -10 ||    // firefox的DOMMouseScroll事件
                                       0 ;     // 属性未定义
            if (ywh.isMacWebkit) {
                deltaY /= 30;
            }

            if (ywh.isFirefox && e.type !== "DOMMouseScroll") {
                self.scrollCon.removeEventListener('DOMMouseScroll',self._wheelEvent,false);
            }

            if(!e.ctrlKey){
                if(deltaY > 0){
                    console.log(deltaY);
                    self.scrollCon.scrollTop -= 20;
                }else{
                    self.scrollCon.scrollTop += 20;
                }
                 self.atuoMoveBtn(self.scrollCon.scrollTop);
            }


            e.preventDefault();
            e.stopPropagation();                           
        },
        init:function(){
            this._MoveEvent = this.mouseMoveEvent.bind(this);
            this._UpEvent = this.mouseUpEvent.bind(this);
            this._wheelEvent = this.wheelEvent.bind(this);

            var self = this;
            // 拖动滚轮的事件
            self.scrollBtn.onmousedown = function(event){
                var e = event || window.event;

                // 每次点击都获取一次按钮位置,以得到鼠标与按钮顶部的距离
                var scrollBtnPosition = this.offsetTop;
                self.mouseClickPosition = e.clientY - self.scrollBarPosition - scrollBtnPosition;

                self.scrollCon.classList.add('scrolling'); // 防止拖动的时候选中文字

                document.addEventListener('mousemove',self._MoveEvent,false);
                document.addEventListener('mouseup',self._UpEvent,false);
            }

            // 滚动内容的事件
            self.scrollCon.addEventListener('mousewheel',self._wheelEvent,false);

            // firefox
            if (ywh.isFirefox) {
                self.scrollCon.addEventListener('DOMMouseScroll',self._wheelEvent,false);
            }
        }
    }
    ywh.ScrollBar = ScrollBar;
})();

// 实例化
var ScrollBar = new ywh.ScrollBar({
    elem:'scroll-box'
});