2015-04-17 53 views
0

我很新的JavaScript,所以我需要一些幫助。
我試圖做一個簡單的插件(只爲了解當然,瞭解更好的東西),但我遇到了一些麻煩和一些幫助將不勝感激。
我的插件是基本的,我想在動畫滾動一些內容,所以這裏是我的代碼:
JS:簡單的Javascript插件在控制檯返回錯誤

(function() { 
    //============================= 
    //=======CONSTRUCTOR=========== 
    //============================= 
    this.hAnimate = function() { 
    this.hanimate = null; 
    this.el = null; 


    //default options 
    var defaults = { 
     class : 'hanimate' 
    } 

    // Create options and extend defaults 
    if (arguments[0] && typeof arguments[0] === "object") { 
    this.options = extendDefaults(defaults, arguments[0]); 
    } 

    } 
    //============================== 
    //===========FUNCTIONS========== 
    //============================== 

    hAnimate.prototype.init = function() { 

    window.addEventListener('scroll' , function(){ 
     this.el = document.querySelector(this.options.class); 
    var distanceY = window.pageYOffset || document.documentElement.srollTop, 
     scrollDelay = this.el.getAttribute('data-scroll'); 

     if (distanceY > scrollDelay){ 
      this.el.classList.add('scrolled'); 
     } 
     else{ 
      if(this.el.classList.contains('scrolled')){ 
      this.el.classList.remove('scrolled') 
      } 
     } 
    }); 
    } 
    function extendDefaults(source, properties) { 
    var property; 
    for (property in properties) { 
     if (properties.hasOwnProperty(property)) { 
     source[property] = properties[property]; 
     } 
    } 
    return source; 
    } 

}()); 

HTML:

<header class='hanimate' data-scroll='1000' data-effect='bg-red'> 
    <h1>This is my header</h1> 
    </header> 
    <main class='wrapper'> 

    </main> 
    <script src='scripts/hAnimate.js'></script> 
    <script> 
    window.onload = function(){ 
     new hAnimate().init(); 
    } 
    </script> 

和CSS:

.wrapper{ 
    width:80%; 
    margin:0 auto; 
    min-height:5000px} 

.hanimate{ 
    position:fixed; 
    top:0; 
    left:0; 
    width:100%; 
    height:5em; 
    display:flex; 
    align-items:center; 
    justify-content:center; 
    background:#f2f2f2; 
} 

[data-effect='bg-red']{ 
    transition:background .7s; 
} 
.scrolled[data-effect='bg-red']{ 
    background:red; 
} 

所以當我試圖運行它會導致我在控制檯012中出錯

ReferenceError: options is not defined

this.el = document.querySelector(this.options.class);

演示here

UPDATE
所以我做了一些研究,但只是我只是想不通,我是初學者,我知道,但我只是不明白, 這是我更新的代碼:

// Create an immediately invoked functional expression to wrap our code 
;(function(window) { 
    'use strict'; 
    function extend(a, b) { 
     for(var key in b) { 
      if(b.hasOwnProperty(key)) { 
       a[key] = b[key]; 
      } 
     } 
     return a; 
    } 
    // Define our constructor 
    function hAnimate(el, options) { 
    this.el = document.querySelector(el); 
    this.options = extend(this.defaults, options); 
    this.init(); 
    } 

    hAnimate.prototype = { 
    defaults : { 
      classToAdd : 'scrolled' 
     }, 
    init: function() { 
     window.addEventListener('scroll', function(){ 
      var self = this, 
       distanceY = window.pageYOffset || document.documentElement.scrollTop, 
       scrollDel = 100; 

      if (distanceY > scrollDel) { 
      this.el.classList.add(this.options.classToAdd); 
      } else { 
       if (this.el.classList.contains(this.options.classToAdd)) { 
       this.el.classList.remove(this.options.classToAdd); 
       } 
      } 
     }); 
    } 

} 
window.hAnimate = hAnimate; 

})(window); 


document.addEventListener('DOMContentLoaded', function() { 
    //var el = document.querySelector('.hAnimate'); 
    new hAnimate('.hanimate', {classToAdd : 'green'}); 
}); 

和錯誤是

TypeError: this.el is undefined, i tried self.el too but don't work either.
Instead this work :

// Create an immediately invoked functional expression to wrap our code 
;(function(window) { 
    'use strict'; 
    function extend(a, b) { 
     for(var key in b) { 
      if(b.hasOwnProperty(key)) { 
       a[key] = b[key]; 
      } 
     } 
     return a; 
    } 
    // Define our constructor 
    function plugin(el, options) { 
    this.el = document.querySelector(el); 
    this.options = extend(this.defaults, options); 
    this.init(); 
    } 

    plugin.prototype = { 
    defaults : { 
      color : 'red' 
     }, 
    init: function() { 
     this.el.style.color = this.options.color; 
    } 

} 
window.plugin = plugin; 

})(window); 

document.addEventListener('DOMContentLoaded', function() { 

//var el = document.querySelector('.plugin'); 
new plugin('.plugin', {color: 'blue'}); 

}); 


我希望有人可以給我一些建議,我真的想熟悉JavaScript

+0

看到這個,如果它可以幫助:https://tommcfarlin.com/javascript-reference-error-is-not-defined/ –

+0

這很可能是因爲this.options從未設置。儘管您定義了默認選項,但在參數[0]不是對象的情況下,您絕不會指定它們。所以也許在第18行之後添加:'else {this.options = defaults; }' – kecer

+0

沒有幫助,我有一個地方的錯誤,但我不知道在哪裏@kecer我嘗試過,但不幸的是不工作 –

回答

0

因此,正如我在我的評論說,你有問題類似於this one

很容易,當你定義一個事件處理程序時,這個指的是事件發生的元素,而不是你的對象。如果您不想重寫代碼,則簡單解決方法是在定義init行爲時創建引用該對象的別名。

hAnimate.prototype.init = function() { 
    var obj = this; 
    window.addEventListener('scroll' , function(){ 
     .... 
    } 
} 

因此,在定義爲滾動事件處理程序的功能,將OBJ指的是hAnimate實例和給一個元素。所以你所要做的就是用「obj」替換「this」的所有相關事件。

。在你的代碼,另一個bug不過,這條線是準確的:

this.el = document.querySelector(this.options.class); 

假設this.options.class只保存類的名稱,使用它作爲querySelector不會產生任何結果(因爲它將被解釋爲標籤名稱而不是類名稱)。 使用此:

obj.el = document.getElementsByClassName(obj.options.class)[0]; 

,[0]是用來獲取唯一的第一個元素。請注意,你可以使用#id,但這取決於你。

這裏被修改fiddle

注:它不會對我的工作的jsfiddle,但話又說回來,沒有什麼。我想知道爲什麼。它雖然在本地主機上運行良好。

+0

不適用於我,但有一個基於您的答案,這應該工作,我會更新代碼做一些測試,如果將工作,我會接受你的答案的想法 –