2017-12-07 27 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

이 어디에 있는지 잘 모르겠지만 문제 영역이 어디인지 알지 못하므로 전체 플러그인을 게시했습니다. 나는 드래그 가능한 인스턴스와 관련이 있다고 내기 만했지만, 지원할 데이터가 없습니다. –

답변

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);