带有事件处理程序的jQuery插件实例变量

时间:2016-05-13 11:33:47

标签: javascript jquery plugins

我正在编写我的第一个jQuery插件,它是一个树形浏览器。它应首先显示顶级元素,然后点击更深入,并以不同的方式显示(取决于级别)孩子。

我已经开始运行了。但是现在我想实现一个"返回"功能,为此,我需要为树浏览器的每个实例存储一个单击元素数组(如果页面上有多个)。

我知道我可以将实例私有变量放在"这个。"在插件中。

但是如果我在一个主题上分配onClick的事件处理程序,我该如何获得这个实例私有变量? $(this)此时正在引用被点击的元素。

可以请任何人给我一个建议或链接到教程如何完成这项工作?

我只找到了实例特定变量的教程,没有涉及事件处理程序。

感谢任何帮助。

提前致谢。

更新:我清理了巨大的代码生成并保留了逻辑结构。这是我的代码:

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

2 个答案:

答案 0 :(得分:0)

再使用一个类变量并将this传递给它。通常我称之为self。所以在你的插件类的构造函数中var self = this;,你很高兴。

面向对象的方式:

function YourPlugin(){
    var self = this;
}

YourPlugin.prototype = {
    constructor: YourPlugin,

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

Check this Fiddle

或者将数据传递给eventHandler的简单方法:

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

答案 1 :(得分:0)

您可以使用jQuery代理功能:

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

然后,您可以在this中使用yourFunction作为插件中的this