使用链式调用就报错,说 _bindContScroll 不是函数,不用的话运行一切正常。
完整代码:
(function(win, doc, $){ 'use strict'; // 构造函数 function CusScrollBar(options) { this._init(options); } $.extend(CusScrollBar.prototype, { _init : function(options) { let self = this; self.options = { scrollDir : "y", contSelector : "", barSelector : "", sliderSelector: "" }; $.extend(true, self.options, options || {}); self._initDomEvent(); return self; }, // _initDomEvent : function() { let opts = this.options; this.$cont = $(opts.contSelector); this.$slider = $(opts.sliderSelector); this.$bar = opts.barSelector ? $(opts.barSelector) : self.$slider.parent(); this.$doc = $(doc); // 就是这里报错 this._initSilderDragEvent() this._bindContScroll(); }, // _initSilderDragEvent : function() { let slider = this.$slider; let sliderEl = slider[0]; if (sliderEl) { let self = this; let doc = self.$doc; let dragStartPagePosition; let dragStartScrollPosition; let dragContBarRate; function mousemoveHandler(e) { e.preventDefault(); console.log('mousemove') if (dragStartPagePosition == null) { return; } self.scrollTo(dragStartScrollPosition + (e.pageY - dragStartPagePosition) * dragContBarRate); }; slider.on('mousedown', function(e) { e.preventDefault(); console.log('mousedown') dragStartPagePosition = e.pageY; dragStartScrollPosition = self.$cont[0].scrollTop; dragContBarRate = self.getMaxScrollPosition() / self.getMaxSliderPosition(); console.log(dragContBarRate) // 命名空间 doc.on('mousemove.nnHoney', mousemoveHandler).on('mouseup.nn', function(event) { event.preventDefault(); console.log('mouseup') // doc.off("mousemove mouseup"); doc.off(".nn"); });; }); } return self; }, getMaxScrollPosition : function() { let self = this; // 内容可以滚动的高度 // self.$cont.height() 内容可视区域的高度(文章未充满页面的情况) // self.$cont[0].scrollHeight 内容完整高度(文章超出页面包括隐藏部分) return Math.max(self.$cont.height(), self.$cont[0].scrollHeight) - self.$cont.height(); }, getMaxSliderPosition : function() { let self = this; return self.$bar.height() - self.$slider.height(); }, scrollTo : function(postionVal) { let self = this; self.$cont.scrollTop(postionVal) }, _bindContScroll : function() { let self = this; self.$cont.on("scroll", function(e) { e.preventDefault(); let sliderEl = self.$slider && self.$slider[0]; if (sliderEl) { sliderEl.style.top = self.getSliderPosition() + 'px'; } }); return self; }, getSliderPosition : function() { let self = this; let maxSliderPosition = self.getMaxSliderPosition(); return Math.min(maxSliderPosition, maxSliderPosition * self.$cont[0].scrollTop / self.getMaxScrollPosition()); } }); win.CusScrollBar = CusScrollBar; })(window, document, jQuery);
自己排查出原因了。
排查过程,把_bindContScroll函数内的内容都屏蔽,只返回self,还是报错,说明跟_bindContScroll函数没关系。
那问题只可能出在前面,在 this._initSilderDragEvent() 函数中找,发现没有在函数的一开始就将this交给self,而是在函数中间将this交给self,因作用域的原因导致这个操作的效果打了折扣,最后return了一个错误的self,导致对象本身的属性和函数传递不畅,以至于爆出_bindContScroll不是函数的错误。
另外,给老师提个意见,本身后半课程讲的就比较粗糙,课程页面切换有加了花里胡哨的效果,我看的时候更眼花缭乱了,希望老师以后的课程改进。总之,还是感谢老师的。