2017-12-07 8 views
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(); 
+1

問題のある領域のみを最小限に表示してください。 [mcve] – charlietfl

+0

のようにコードレビュー投稿のように –

+0

私はどこに問題の領域がわからないので、私はプラグイン全体を投稿しました。私はそれがdraggableインスタンスとは何かを持っていることだけが賭けているが、私はそれをサポートするためのデータがない。 –

答えて

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); 
関連する問題