繁体   English   中英

将jQuery与OOP JS一起使用是否有效?如果可以,如何在类函数之间创建状态更改菜单?

[英]Is it effective/efficient to use jQuery with OOP JS, and if so, how do I create a changing-state menu across class functions?

我试图用面向对象的JavaScript编写JavaScript widget ,或者至少我理解JS几乎等同于类的东西。

我想要实现的只是一个更改状态的菜单。

  • 加载小部件后,使用包含年份组 <li><ul>菜单填充#nav
  • 单击年份组<li> ,将其<li> #nav ul清空,并在该年份中将其与导师组 <li>一起重新填充,并附加一个return链接。
  • 单击return链接后,清空#nav并使用原始的年组 <ul>菜单重新填充它,同时能够使用上述所有功能。

从历史上讲 (即迄今为止),我曾使用“嵌入式”功能来尝试将所有内容保持在同一DOM层/定时内。 我真的不明白这是如何工作的,或者这是否合适,但是代码本身似乎可以工作。

这是我之前做过的一个例子:

var GroupsDisplayHTML = '<h2>Tutor Groups</h2>' +
    '<ul><li><a class="year" href="javascript:void(0);" title="Year 9" id="9">Year 9</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 10" id="10">Year 10</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 11" id="11">Year 11</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 12" id="12">Year 12</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 13" id="13">Year 13</a></li></ul>';

$("div#groups").html(GroupsDisplayHTML);

$('a.year').click( function() {
    var Groups;
    var Groups_Sorted = [];

    Frog.API.get('groups.getAll',
    {
        'onSuccess': function (data) { Groups = data; },
        'onError': function(err) { alert(err); }
    });

    for (var i = 0; i < Groups.length; i++) {
        var Year = $(this).attr("id");

        if (Groups[i].name.indexOf(Year) == 0 && Groups[i].name.indexOf('/Tp') != -1) {
            var arrayToPush = { 'id': Groups[i].id, 'name': Groups[i].name };
            Groups_Sorted.push(arrayToPush);
        }
    }

    GroupsDisplayHTML = '<h2>Year ' + Year + '</h2><ul>';

    for(var i = 0; i < Groups_Sorted.length; i++){
        GroupsDisplayHTML += '<li><a class="group" href="javascript:void(0);" title="' + Groups_Sorted[i].id + '" id="' + Groups_Sorted[i].id + '">' + 
            Groups_Sorted[i].name + ' <span style="font-size:10px;color:#bbb;">(' + Groups_Sorted[i].name + ')</span></a></li>';
    }

    GroupsDisplayHTML += '<li><a class="return" href="javascript:void(0);">&lt;- Back to Year Groups</a></li></ul>';

    $("div#groups").html(GroupsDisplayHTML);

    $('a.group').click( function() {
        var Group_ID = $(this).attr("id");
        AssignPoints.getUsers(Group_ID);
    });

    $('a.return').click( function() {
        AssignPoints.displayGroups(data);
    });
});

但是,现在,我想知道是否更好的方法是使用jQuery的on函数。 这是我当前正在编写的代码(*仅用于尝试实现状态更改菜单):

var TutorGroupPoints = {
    URL: 'http://staff.curriculum.local/frog/rewards.php',
    currentUser: UWA.Environment.user.id,
    groupsObject: { },
    sortedArray: [ ],
    navHTML: '<h2>Tutor Groups</h2>' +
        '<ul>' +
            '<li><a class="year" title="Year 9" id="9">Year 9</a></li>' +
            '<li><a class="year" title="Year 10" id="10">Year 10</a></li>' +
            '<li><a class="year" title="Year 11" id="11">Year 11</a></li>' +
            '<li><a class="year" title="Year 12" id="12">Year 12</a></li>' +
            '<li><a class="year" title="Year 13" id="13">Year 13</a></li>' +
        '</ul>',

    init: function() {
        /* caching outer this -> AJAX scope problems */
        var that = this;

        /* retrieve all of the user groups from Frog VLE and store them in an object-level variable */
        Frog.API.get('groups.getAll',
        {
            'onSuccess': function (data) { that.groupsObject = data; },
            'onError': function(err) { alert(err); }
        });

        /* populate the div#nav with our year group UL */
        $('#nav').append(this.navHTML);

        /* using "on" because the LIs have been created in the DOM? */
        $('#nav ul').on("click", "li a", function(e) {
            e.preventDefault();
            that.yearClick( $(this).attr("id") );
        });
    },

    yearClick: function(year) {
        /* run through groupsObject and pull out any tutor groups found in the year we've clicked on
           then put those into our sortedArray */
        for (var i = 0; i < this.groupsObject.length; i++) {
            if (this.groupsObject[i].name.indexOf(year) == 0 && this.groupsObject[i].name.indexOf('/Tp') != -1) {
                /* all we need is name and id */
                var arrayToPush = { 'id': this.groupsObject[i].id, 'name': this.groupsObject[i].name };
                this.sortedArray.push(arrayToPush);
            }
        }

        /* clear the existing UL from div#nav */
        $('#nav ul').empty();

        /* populate div#nav's UL with LIs of our tutor groups (label being name, attr="id" being id) and
           clickable links for each */
        for (var i = 0; i < this.sortedArray.length; i++) {
            $('#nav ul').append('<li><a class="tutor" id="' + this.sortedArray[i].id + '">' + this.sortedArray[i].name + '</a></li>');
        }

        /* add a "return" link to view other years' tutor groups */
        $('#nav ul').append('<li><a id="return">&lt;- Return</a></li>');

        /* upon clicking the return link, empty #nav ul then re-append our navHTML from earlier */
        $('#nav ul').on("click", "a#return", function(e) {
            e.preventDefault();
            $('#nav ul').empty();
            $('#nav').append(this.navHTML);
        });

        /* upon clicking any of our tutor group LIs, display that link's id so that we can use it in
           another function to actually display some content */
        $('#nav ul').on("click", "a.tutor", function(e) {
            e.preventDefault();
            alert( $(this).attr("id") );
        });
    }

};

widget.onLoad = function(){
    /* run our "class" */
    TutorGroupPoints.init();
}

和HTML:

<div id="wrapper">
    <div id="nav">

    </div>
    <div id="content">

    </div>
</div>

我在这里创建了一个jsFiddle ,它是对代码的轻微操纵(即,我删除了无法访问的Frog API调用,并用固定对象替换了它们)。 希望这可以正常工作。

这里的问题是,一旦我单击返回按钮,就什么也没有发生 此外,我怀疑固定返回按钮会为我提供一些链接,这些链接在单击时将无济于事。

理想情况下 ,根据代码的最底端,当用户单击特定的导师组时,我想在TutorGroupPoints类中运行另一个函数 这将如何影响我的返回按钮等? 他们会因为没有从“当前”功能运行而停止工作吗?

我不仅仅要“解决”我的代码问题,还需要提供一些指导 ,即,我编写的最新代码是否比旧版本要好? 我应该使用on还是应该使用嵌入式jQuery函数和可通信类函数?

提前致谢,

简短答案: http : //jsfiddle.net/byzgv/4/

我不确定OOP方面,但这似乎是您的情况:

  1. 加载页面时,您将一个列表插入div。
  2. 您将一些事件处理程序添加到此列表中
  3. 您单击一个列表项,您的事件处理程序运行,并更改列表项。
  4. 单击它时,“返回”列表项“不执行任何操作”。

在您的小提琴中,单击“返回”列表项执行某些操作,从而清空此列表。 这部分是您要求它执行的操作:

$('#nav').on("click", "ul a#return", function(e) {
    e.preventDefault();
    $('#nav ul').empty();
    $('#nav').append(this.navHTML);
});

因此,此事件处理程序已触发,并且前两个指令已起作用。 append调用不起作用,因为您处于不同的上下文中- this不引用TutorGroupPoints对象。 因此,您可以通过显式引用对象来解决此问题:

$('#nav').on("click", "ul a#return", function(e) {
    e.preventDefault();
    $('#nav ul').empty();
    $('#nav').append(TutorGroupPoints.navHTML);
});

(顺便说一句,您要追加一个全新的列表,因此需要执行$('#nav').empty();而不是$('#nav ul').empty();

然后,正如您所猜测的,单击“返回”项将为您提供一个新列表,该列表不响应单击事件。 这是因为您如何调用on函数。 你叫jQuery对象on时,正在建立的事件处理程序上必须存在。 在您的init函数中,列表在设置事件处理程序时确实存在,因为您需要在调用之前将其追加到div on 但是,稍后,您将其丢弃,然后将其替换。

为了使事件处理程序能够在所有列表上而不是仅在第一个列表上运行,您需要将事件处理程序附加到从一开始就存在且不会更改的元素,即#nav div。 所以

$('#nav ul').on("click", "li a", function(e) {

可以变成

$('#nav').on("click", "ul li a", function(e) {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM