如何为 jquery 插件选择的每个元素声明变量的本地实例

发布于 2024-10-10 08:16:25 字数 2810 浏览 1 评论 0原文

对于我尝试编写的 JQuery 插件,我想存储一个局部变量,其范围仅限于选择器标识的 HTML。在下面的基本示例中,HTML 页面有两个表单元素,我分别选择每个表单元素,并在每个实例内我想要统计表单包含的文本元素的数量。在下面的示例中,“_elements”始终包含最后调用的选择器的文本输入元素的数量。现在我认为这是因为 Javascript 的块级作用域和闭包,但不确定如何实现它。有人可以告诉我我的方法的错误吗?

请不要建议不同的方法来执行此操作(即根本不存储变量,总是直接选择匹配元素的计数 - 我知道这会起作用,但这只是我所遇到的问题的简化示例具有局部变量

<html>
    <head>
        <script language="javascript" src="jquery-1.4.4.min.js" type="text/javascript"></script>
        <script language="javascript" type="text/javascript">

            (function ($) {

                var methods = {

                    Setup: function (options) {
                        if ($(this).length == 0)
                            throw new Error("AutoSave() selector did not find required element");
                        if ($(this).length > 1)
                            throw new Error("AutoSave() is not designed to handle a selector that matches two or more elements!");

                        _elements = $('INPUT[TYPE=TEXT]', this)
                        _elements.length;

                        return this;
                    },
                    NumOfElements: function (options) {
                        alert(_elements.length);
                        return this;
                    }
                };

                $.fn.autoSave = function (method) {

                    if (methods[method]) {
                        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
                    } else if (typeof method === 'object' || !method) {
                        return methods.Setup.apply(this, arguments);
                    } else {
                        $.error('Method ' + method + ' does not exist on jQuery.AjaxClickEvent');
                    }
                };

            })(jQuery);

        </script>
    </head>
    <body>
        <form method="post" action="" id="myForm" name="myForm">
            <input type="text" id="txt1" name="txt2" />
            <input type="submit" id="submit" name="submit" />
        </form>
        <form method="post" action="" id="myForm2" name="myForm2">
            <input type="text" id="Text1" name="Text1" />
            <input type="text" id="Text2" name="Text2" />
            <input type="submit" id="submit1" name="submit1" />
        </form>
<script>
    $(document).ready(function () {
        $("#myForm").autoSave();
        $("#myForm").autoSave('NumOfElements');  // Shows 1
        $("#myForm2").autoSave();
        $("#myForm2").autoSave('NumOfElements');  // Shows 2
        $("#myForm").autoSave('NumOfElements');  // Shows 2 (should be 1)
    });
</script>
    </body>
</html>

For a JQuery plugin that I am trying to write I would like to store a local variable that whose scope is limited to the HTML identified by the selector. In the basic example below an HTML page has two form elements, I select on each form element separately and inside each instance I want to have the count of the number of text elements the form contains. In the example below "_elements" always contains the number of text input elements for last selector called. Now I think this is because of Javascript's block level scope and closure, but not sure how to implement it. Could somebody please show me the error of my ways.

Please don't suggest different ways of doing this (i.e. not storing the variable at all, always selecting the count of the matching elements directly - I know that would work but this is just a simplified example of the problem I'm having with local variables

<html>
    <head>
        <script language="javascript" src="jquery-1.4.4.min.js" type="text/javascript"></script>
        <script language="javascript" type="text/javascript">

            (function ($) {

                var methods = {

                    Setup: function (options) {
                        if ($(this).length == 0)
                            throw new Error("AutoSave() selector did not find required element");
                        if ($(this).length > 1)
                            throw new Error("AutoSave() is not designed to handle a selector that matches two or more elements!");

                        _elements = $('INPUT[TYPE=TEXT]', this)
                        _elements.length;

                        return this;
                    },
                    NumOfElements: function (options) {
                        alert(_elements.length);
                        return this;
                    }
                };

                $.fn.autoSave = function (method) {

                    if (methods[method]) {
                        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
                    } else if (typeof method === 'object' || !method) {
                        return methods.Setup.apply(this, arguments);
                    } else {
                        $.error('Method ' + method + ' does not exist on jQuery.AjaxClickEvent');
                    }
                };

            })(jQuery);

        </script>
    </head>
    <body>
        <form method="post" action="" id="myForm" name="myForm">
            <input type="text" id="txt1" name="txt2" />
            <input type="submit" id="submit" name="submit" />
        </form>
        <form method="post" action="" id="myForm2" name="myForm2">
            <input type="text" id="Text1" name="Text1" />
            <input type="text" id="Text2" name="Text2" />
            <input type="submit" id="submit1" name="submit1" />
        </form>
<script>
    $(document).ready(function () {
        $("#myForm").autoSave();
        $("#myForm").autoSave('NumOfElements');  // Shows 1
        $("#myForm2").autoSave();
        $("#myForm2").autoSave('NumOfElements');  // Shows 2
        $("#myForm").autoSave('NumOfElements');  // Shows 2 (should be 1)
    });
</script>
    </body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情感失落者 2024-10-17 08:16:25

好吧,你的代码没问题,你没有疯。问题是methods.Setup 函数中的this 不是jQuery 对象/html 节点。它是单例方法。所以你总是修改相同的_elements - 因此最后一个例子中是2。

解决方案是添加:

var methods = {
  my_form: null,
  ...
}

然后当它全部实例化时:

$.fn.autoSave = function (method) {
  methods.my_form = this;

然后将方法中的 this 调用更改为引用methods.my_form。然后您将获得对 DOM 的适当对象引用。 (我还建议将 _elements 存储在 DOM 中的 HTML 节点上,而不是“在以太中” - 使用 data http://api.jquery.com/data/)

OK so your code is fine, you're not crazy. The problem is that this in the methods.Setup function is not the jQuery object/html node. It is the methods singleton. So you are always modifying the same _elements - hence 2 in the last example.

The solution is to add:

var methods = {
  my_form: null,
  ...
}

And then when it all gets instantiated:

$.fn.autoSave = function (method) {
  methods.my_form = this;

Then change the this calls in your methods to reference methods.my_form. Then you will have the appropriate object reference to the DOM. (I would also suggest storing _elements on the HTML node in the DOM and not "out in the ether" - use data http://api.jquery.com/data/)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文