问答详情
源自:3-4 拖动滑块内容滚动的实现

不知道为什么使用链式调用就报错,第33~34行

http://img.mukewang.com/594be41700011e3511160446.jpg

使用链式调用就报错,说 _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);


提问者:ThinkSummer 2017-06-22 23:41

个回答

  • ThinkSummer
    2017-06-22 23:55:28

    自己排查出原因了。

    排查过程,把_bindContScroll函数内的内容都屏蔽,只返回self,还是报错,说明跟_bindContScroll函数没关系。

    那问题只可能出在前面,在 this._initSilderDragEvent() 函数中找,发现没有在函数的一开始就将this交给self,而是在函数中间将this交给self,因作用域的原因导致这个操作的效果打了折扣,最后return了一个错误的self,导致对象本身的属性和函数传递不畅,以至于爆出_bindContScroll不是函数的错误。

    另外,给老师提个意见,本身后半课程讲的就比较粗糙,课程页面切换有加了花里胡哨的效果,我看的时候更眼花缭乱了,希望老师以后的课程改进。总之,还是感谢老师的。