0
jQueryの定型文を使用してjQueryプラグインの開発を実践している間に、画面の種類に基づいてドラッグアンドホバーの両方を有効にするカルーセルを作成しようとしました。しかし、複数のDOM要素のプラグインを実行した後、私はそれを完全に分離しなかったことを知りました。ドラッグ可能なインスタンスはカルーセル間で共有され、各インスタンスは同時にグローバルに移動します。jQueryプラグイン - すべてのインスタンスを分離する際の問題
正直言って、どこで問題を探しているのか分かりません。それはその定型文を持つ私の最初のプロジェクトです、そして、私は今は少し失われているように感じます。
あなたはとても親切で自分のコードを見ていただけますか?
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();
問題のある領域のみを最小限に表示してください。 [mcve] – charlietfl
のようにコードレビュー投稿のように –
私はどこに問題の領域がわからないので、私はプラグイン全体を投稿しました。私はそれがdraggableインスタンスとは何かを持っていることだけが賭けているが、私はそれをサポートするためのデータがない。 –