在使用jQuery样板练习jQuery插件开发时,我尝试根据屏幕类型创建一个可以拖动和悬停的旋转木马。然而,在运行多个DOM元素的插件后,我发现我并没有完全分离它。可拖动的实例在旋转木马之间共享,并且全局迫使它们中的每一个同时移动。
说实话,我不知道应该在哪里寻找问题。这是我的第一个带有样板的项目,我觉得此刻有点迷失。
你能这么善良并看看我的代码吗?
https://codepen.io/Nikolaus91/pen/LOoERJ
(function($, window, document, undefined) {
// undefined is used here as the undefined global
// variable in ECMAScript 3 and is mutable (i.e. it can
// be changed by someone else). undefined isn't really
// being passed in so we can ensure that its value is
// truly undefined. In ES5, undefined can no longer be
// modified.
// window and document are passed through as local
// variables rather than as globals, because this (slightly)
// quickens the resolution process and can be more
// efficiently minified (especially when both are
// regularly referenced in your plugin).
// Create the defaults once
var pluginName = "finiteCarousel",
defaults = {
singleRowClass: "finite-carousel__inner",
singleSlideClass: "finite-carousel__slide"
};
// The actual plugin constructor
function Plugin(element, options) {
this.element = element;
// jQuery has an extend method that merges the
// contents of two or more objects, storing the
// result in the first object. The first object
// is generally empty because we don't want to alter
// the default options for future instances of the plugin
this.options = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function() {
// Place initialization logic here
// You already have access to the DOM element and
// the options via the instance, e.g. this.element
// and this.options
//console.clear();
console.log("Initiating");
this.buildCache();
console.log(this);
console.log(this.$element);
console.log(this.$container);
console.log(this.$slides);
this.buildDraggable();
if (typeof Modernizr == "object") {
if (!Modernizr.touchevents) {
console.log("Binding mouse events");
this.bindEvents();
console.log(this.$draggable);
//this.$draggable[0].disable();
}
}
//console.log("Touchevents: " + Modernizr.touchevents);
},
// Cache DOM nodes for performance
buildCache: function() {
/*
Create variable(s) that can be accessed by other plugin
functions. For example, "this.$element = $(this.element);"
will cache a jQuery reference to the elementthat initialized
the plugin. Cached variables can then be used in other methods.
*/
this.$element = $(this.element);
this.$container = this.$element.find("." + defaults.singleRowClass);
this.$slides = this.$element.find("." + defaults.singleSlideClass);
this.$totalWidth = 0;
this.$lastX = 0;
this.$diffX;
this.$currentX;
},
// Build draggable instance
buildDraggable: function() {
var plugin = this;
var isDragging = false;
// Count all slides outer width
plugin.$slides.each(function(index, elem) {
plugin.$totalWidth += $(elem).outerWidth();
});
console.log("\nWidth of all slides: " + plugin.$totalWidth);
// Build draggable instance
plugin.$draggable = Draggable.create('<div />', {
type: "x",
trigger: plugin.$container,
throwProps: true,
edgeResistance: 0.95,
onDrag: updateProgress,
onThrowUpdate: updateProgress,
onThrowComplete: function() {
isDragging = false;
},
onPress: function() {
//console.clear();
//console.log(this);
//console.log(plugin.$draggable[0]);
plugin.$draggable[0].update();
plugin.$lastX = plugin.$draggable[0].x;
updatePosition(plugin.$draggable[0]);
isDragging = true;
TweenMax.killTweensOf(plugin.$draggable[0].target);
},
onComplete: function() {
console.log("On Complete");
}
});
function updateProgress() {
plugin.$diffX = plugin.$draggable[0].x - plugin.$lastX;
TweenMax.set("." + defaults.singleSlideClass, {
x: "+=" + plugin.$diffX
});
plugin.$lastX = plugin.$draggable[0].x;
}
// Updates the position of all slides
function updatePosition(draggableInstance) {
plugin.$currentX = draggableInstance.target._gsTransform.x;
plugin.$lastX = draggableInstance.target._gsTransform.x;
plugin.$slides.each(function(index, elem) {
TweenMax.set(elem, { x: plugin.$currentX });
//currentX += $(elem).outerWidth();
});
}
$(window).resize(applyBorders(plugin.$draggable[0]));
applyBorders(plugin.$draggable[0]);
// Apply borders to our carousel
function applyBorders(draggableInstance) {
var minx = plugin.$container.outerWidth() - plugin.$totalWidth;
var maxx = 0;
draggableInstance.applyBounds({ minX: minx, maxX: maxx });
updatePosition(draggableInstance);
}
},
// Bind mouse events
bindEvents: function() {
var plugin = this;
var isMouseOver = false;
var direction;
var mouseX, mouseY;
var isDragging = false;
var animateX;
var animation = TweenMax.to({}, 0, {});
var animationTimescale = 1;
plugin.$container.on("mouseleave", function() {
console.log("Mouse left");
isMouseOver = false;
TweenMax.killTweensOf(animation);
});
plugin.$container.on("mousemove", function(e) {
var container = this;
var rect = container.getBoundingClientRect();
//console.log(rect);
mouseX = e.pageX - rect.left;
if (mouseX < rect.width / 5) {
direction = 1;
animationTimescale = Math.abs(mouseX / (rect.width / 25) - 5);
isMouseOver = true;
} else if (mouseX > rect.width - rect.width / 5) {
direction = -1;
animationTimescale = Math.abs(
(rect.width - mouseX) / (rect.width / 25) - 5
);
isMouseOver = true;
} else {
isMouseOver = false;
}
//console.log(animationTimescale);
animateX = rect.width / 5;
if (!animation.isActive()) {
animateSlides();
} else {
animation.timeScale(animationTimescale);
}
});
function animateSlides() {
if (
plugin.$draggable[0].target._gsTransform.x < 0 ||
plugin.$draggable[0].target._gsTransform.x >
plugin.$container.outerWidth() - plugin.$totalWidth
) {
if (isMouseOver && !isDragging) {
animation = TweenMax.to(plugin.$draggable[0].target, 0.3, {
ease: Linear.easeNone,
x: "+=" + animateX * direction,
modifiers: { x: checkBounds },
onComplete: animateSlides,
onUpdate: updateSlides
});
}
}
animation.timeScale(animationTimescale);
}
// Uses modifiers plugin to make sure slides remain within bound
function checkBounds(value) {
if (value > 0) {
TweenMax.killTweensOf(plugin.$draggable[0].target);
return 0;
} else if (
value <
plugin.$container.outerWidth() - plugin.$totalWidth
) {
TweenMax.killTweensOf(plugin.$draggable[0].target);
return plugin.$container.outerWidth() - plugin.$totalWidth;
}
return value;
}
// Updates slides along with proxy element
function updateSlides() {
plugin.$diffX =
plugin.$draggable[0].target._gsTransform.x - plugin.$lastX;
TweenMax.set(plugin.$slides, { x: "+=" + plugin.$diffX });
plugin.$lastX = plugin.$draggable[0].target._gsTransform.x;
}
} // end Bind events
};
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function(options) {
console.clear();
return this.each(function() {
console.log('Creating');
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
$(".finite-carousel").finiteCarousel();
答案 0 :(得分:0)
一切都运转良好,我在第283行遇到了拼写错误,我在全球范围内调用所有轮播元素:
TweenMax.set("." + defaults.singleSlideClass), {
x: "+=" + plugin.$diffX
});
我必须将其更改为:
TweenMax.set(plugin.$slides, {
x: "+=" + plugin.$diffX
});
其中:
var plugin = this;
plugin.$slides = this.$element.find("." + defaults.singleSlideClass);