2016-05-13 81 views
0

我正在寫我的第一個jQuery插件,它是一個樹型瀏覽器。它應該首先顯示頂級元素,然後點擊更深入地顯示(取決於級別)孩子以不同的方式。jQuery插件實例變量與事件處理程序

我已經啓動並運行了。但是現在我想實現一個「後退」功能,爲此我需要爲樹形瀏覽器的每個實例(如果頁面上有多個)存儲單擊的元素數組。

我知道我可以將實例私有變量放在「this」中。在插件中。

但是,如果我爲某個主題分配onClick的事件處理程序,如何獲取此實例的專用變量? $(this)此時引用了clicked元素。

可以請任何人給我一個建議或指導如何完成這個工作的鏈接?

我只找到實例特定變量的教程,沒有涉及事件處理程序。

任何幫助表示讚賞。

在此先感謝。

更新:我清理了龐大的代碼生成並保留了邏輯結構。這是我的代碼:

(function ($) { 

$.fn.myTreeBrowser = function (options) { 

    clickedElements = []; 

    var defaults = { 
     textColor: "#000", 
     backgroundColor: "#fff", 
     fontSize: "1em", 
     titleAttribute: "Title", 
     idAttribute: "Id", 
     parentIdAttribute: "ParentId", 
     levelAttribute: "Level", 
     treeData: {} 
    }; 

    var opts = $.extend({}, $.fn.myTreeBrowser.defaults, options); 


    function getTreeData(id) { 
     if (opts.data) { 
      $.ajax(opts.data, { async: false, data: { Id: id } }).success(function (resultdata) { 
       opts.treeData = resultdata; 
      }); 
     } 
    } 

    function onClick() { 

     var id = $(this).attr('data-id'); 

     var parentContainer = getParentContainer($(this)); 

     handleOnClick(parentContainer, id); 
    } 

    function handleOnClick(parentContainer, id) { 
     if (opts.onTopicClicked) { 
      opts.onTopicClicked(id); 
     } 

     clickedElements.push(id); 

     if (id) { 

      var clickedElement = $.grep(opts.treeData, function (n, i) { return n[opts.idAttribute] === id })[0]; 

      switch (clickedElement[opts.levelAttribute]) { 
       case 1: 
        renderLevel2(parentContainer, clickedElement); 
        break; 
       case 3: 
        renderLevel3(parentContainer, clickedElement); 
        break; 
       default: 
        debug('invalid level element clicked'); 
      } 
     } else { 
      renderTopLevel(parentContainer); 
     } 
    } 

    function getParentContainer(elem) { 
     return $(elem).parents('div.myBrowserContainer').parents()[0]; 
    } 

    function onBackButtonClick() { 
     clickedElements.pop(); // remove actual element to get the one before 
     var lastClickedId = clickedElements.pop(); 

     var parentContainer = getParentContainer($(this)); 
     handleOnClick(parentContainer, lastClickedId); 
    } 



    function renderLevel2(parentContainer, selectedElement) { 
     $(parentContainer).html(''); 

     var browsercontainer = $('<div>').addClass('myBrowserContainer').appendTo(parentContainer); 

     //... rendering the div ... 
     // for example like this with a onClick handler 
     var div = $('<div>').attr('data-id', element[opts.idAttribute]).addClass('fct-bs-col-md-4 pexSubtopic').on('click', onClick).appendTo(subtopicList); 

     // ... rendering the tree 

     var backButton = $('<button>').addClass('btn btn-default').text('Back').appendTo(browsercontainer); 
     backButton.on('click', onBackButtonClick); 

    } 


    function renderLevel3(parentContainer, selectedElement) { 
     $(parentContainer).html(''); 

     var browsercontainer = $('<div>').addClass('myBrowserContainer').appendTo(parentContainer); 

     //... rendering the div ... 
     // for example like this with a onClick handler 
     var div = $('<div>').attr('data-id', element[opts.idAttribute]).addClass('fct-bs-col-md-4 pexSubtopic').on('click', onClick).appendTo(subtopicList); 

     // ... rendering the tree 

     var backButton = $('<button>').addClass('btn btn-default').text('Back').appendTo(browsercontainer); 
     backButton.on('click', onBackButtonClick); 

    } 


    function renderTopLevel(parentContainer) { 

     parentContainer.html(''); 

     var browsercontainer = $('<div>').addClass('fct-page-pa fct-bs-container-fluid pexPAs myBrowserContainer').appendTo(parentContainer); 

     // rendering the top level display 

    } 



    getTreeData(); 

    //top level rendering! Lower levels are rendered in event handlers. 
    $(this).each(function() { 
     renderTopLevel($(this)); 
    }); 

    return this; 
}; 



// Private function for debugging. 
function debug(debugText) { 
    if (window.console && window.console.log) { 
     window.console.log(debugText); 
    } 
}; 

}(jQuery));

回答

0

只需使用一個類變量並將this傳遞給它。通常我稱之爲self。所以你的插件類的構造函數中的var self = this;和你很好去。

面向對象的方式:

function YourPlugin(){ 
    var self = this; 
} 

YourPlugin.prototype = { 
    constructor: YourPlugin, 

    clickHandler: function(){ 
     // here the self works 
    } 
} 

Check this Fiddle

或者將數據傳遞給事件處理程序的簡單方法:

$("#foo").bind("click", { 
    self: this 
}, function(event) { 
    alert(event.data.self); 
}); 
+0

以及如何從eventHandler獲取此「自我」?我的事件處理程序如下所示:function onClick(){ var id = $(this).attr('data-id'); var parentContainer = getParentContainer($(this)); handleOnClick(parentContainer,id); } – HugoHiasl

+0

當你想要特定的答案時,你應該發佈更多的代碼。如果僅使用函數式編程方法,則不可行,因爲eventHandler是在全局上下文中執行的。如果你的插件是一個帶有實例的類,而eventHandler是它的方法,那麼你可以訪問實例變量。 – okolimar

+1

我更新了我的問題。在網絡中有沒有好的教程,我可以更深入地瞭解如何以正確的方式做到這一點? – HugoHiasl

0

您可以使用jQuery的代理功能:

$(yourElement).bind("click", $.proxy(this.yourFunction, this)); 

然後,您可以在yourFunction中使用this作爲插件中的this