【问题标题】:adding a js method添加一个js方法
【发布时间】:2011-01-02 10:20:03
【问题描述】:

我有一个名为 getID 的 js 函数,它基本上是 return document.getElementById(id)

我想做另一个函数,getTag 可以return getElementsByTagName

我似乎无法管理的部分是我希望能够这样称呼他们:

getID('myid').getTag('input') => 所以这将返回 ID 为 myid 的元素内的所有输入元素

谢谢!

ps:如果 getTag 被它自己调用,它也必须工作,但它只会 return document.getElementsByTagName

更新:

感谢所有回复的人!使用您的建议,我想出了这个,这对我很有效:

函数getEl(){ 返回新的getElement(); } 函数 getElement() { var 范围 = 文档; this.by = 函数(数据){ if (data.id) 范围 = scope.getElementById(data.id); if (data.tag) 范围 = scope.getElementsByTagName(data.tag); 返回范围; } }

我是这样使用它的:

var inputs = getEl().by({id:"msg", tag:"input"});

【问题讨论】:

  • 总是有 1 个项目具有唯一 ID,所以 getID('myid') 永远不会返回集合?
  • 问题是你不能让函数根据你使用它的方式改变它的返回类型,所以你必须使用一些技巧来解决这个问题。作为参考,看看jQuery是如何做到的。
  • @caspar:是的,只有一个元素
  • @musicfreak:我真的不需要jQuery的复杂性,它只是一个简单的脚本
  • @Sorin:如果它只是一个简单的脚本,那你为什么需要“语法糖”呢?是纯粹的虚荣心(“......但我希望它以这种方式工作,因为它看起来更好”)还是有任何技术原因你不能简单地使用已经存在的方法?

标签: object javascript


【解决方案1】:

做到这一点的方法是对 Object 进行原型化。为此,您需要以下代码:

Object.prototype.getTag = function(tagName) {
    返回 this.getElementsByTagName(tagName);
}

但是,这将扩展 所有 对象,因为您真正需要原型的 HTMLElement 很难始终如一地做到。所有专家都同意您应该never expand the Object prototype。更好的解决方案是创建一个从另一个参数获取标签名称的函数:

function getTag(tagName, element) {
    return (元素 || 文档).getElementsByTagName(tagName);
}

// 用法
var oneTag = getTag('input', getID('myid')); // myid 元素内的所有输入标签
var twoTag = getTag('输入'); // 页面上的所有输入

【讨论】:

    【解决方案2】:

    这将要求getID('myid')(一个HTML 元素)返回的任何内容都公开一个名为getTag() 的方法。不是这种情况。浏览器实现 DOM 规范并公开其中定义的方法。

    虽然您在技术上可以使用自己的方法增强原生对象,但最好不要这样做。

    您尝试做的事情已经在 jQuery 等 JS 库中得到了很好的解决,我建议您在花时间模仿它们可以做什么之前先看看其中的一个。例如,您的代码行将变为:

    $("#myid input")
    

    在 jQuery 中。 jQuery 恰好是使用最广泛的 JS 库,还有很多其他的。

    【讨论】:

      【解决方案3】:

      基本上,您将创建一个对象,其中包含您的每个方法并存储本机函数返回的所有数据。它看起来像这样(未经测试,但你明白了):

      var MyLib = {
          getID: function(id) {
              var element = document.getElementById(id);
              this.length = 1;
              this[0] = element;
              return this;
          },
          getTag: function(tag) {
              var elements;
              if (this.length) {
                  for (var i = 0; i < this.length; i++) {
                      var byTag = this[i].getElementsByTagName(tag);
                      for (var j = 0; j < byTag.length; j++) {
                          elements.push(byTag[j]);
                      }
                  }
              }
              for (var i = 0; i < elements.length; i++) {
                  this[i] = elements[i];
              }
              this.length = elements.length;
              return this;
          }
      };
      

      然后你可以像这样使用它:

      var elements = MyLib.getID('myid').getTag('input');
      for (var i = 0; i < elements.length; i++)
          console.log(elements[i]); // Do something
      

      这种方法唯一真正的问题(除了它非常棘手和难以调试之外)是您必须将每个方法的结果视为一个数组,即使只有一个结果。例如,要通过 ID 获取元素,您必须执行 MyLib.getID('myid')[0]

      但是,请注意之前已经这样做了。我建议你看看jQuery,看看他们是如何做到这一点的。您的代码可以简化为:

      $("#myid input")
      

      jQuery 比你想象的要轻量级,将它包含在你的页面中并不会减慢它的速度。使用它不会有任何损失。

      【讨论】:

      • +1 用于迷你库方法。 :) 但是,getTag() 函数是否应该不适用于getID() 返回的元素,而不是使用document?此外,getID() 应该只对getTag() 返回的元素起作用,如果调用是相反的......
      • @Tomalak:哎呀,你说得对,我忘了最重要的部分!哦!我修好了,谢谢指出。 :) 尽管在getTag 之后调用getID 是没有用的,但它仍然有效并且应该得到支持,IMO。毕竟,您可以在 jQuery 中调用$('div #myid')。另外,它不需要更多的代码来支持这种情况——它的行为与您自己调用 getID 的行为完全相同。
      • 我不会这样说它没用。必须有一种语义表达的方式“ID x 的元素,但只有当它被包裹在一个 div 中时”
      【解决方案4】:

      只需使用DOMElement.prototype 属性。

      你会得到这样的东西:

      function getTag(tagName) {
          return document.getElementsByTagName(tagName);
      }
      DOMElement.prototype.getTag = function(tagName) {
          return this.getElementsByTagName(tagName);
      }
      

      但你应该为此使用 jQuery。

      编辑:我的解决方案不适用于 IE,抱歉!

      【讨论】:

        【解决方案5】:

        你可以这样定义:

        var Result = function(el)
        {
          this.Element = el;
        };
        
        Result.prototype.getTag = function(tagName)
        {
          return this.Element.getElementsByTagName(tagName);
        };
        
        var getTag = function(tagName)
        {
          return document.getElementsByTagName(tagName);
        };
        
        var getID = function(id)
        {
          var el = document.getElementById(id);
          return new Result(el);
        };
        

        调用getID 将返回Result 的实例,然后您可以使用其Element 属性访问返回的HTML 元素。 Result 对象有一个名为 getTag 的方法,它将从父结果中返回与该标记匹配的所有子元素。然后我们还定义了一个单独的getTag 方法,它调用文档元素的getElementsByTagName

        尽管如此...JQuery 要容易得多...$("#myId input");

        【讨论】:

          【解决方案6】:

          除非这是关于如何在 JavaScript 中链接方法的学术练习(看起来不是,你只是在学习 JavaScript),否则你所要做的就是:

          var elements = document.getElementById("someIdName");
          var elementsByTag = elements.getElementsByTagName("someTagName");
          for (i=0; i< elementsByTag.length; i++) {
              alert('found an element');
          }
          

          如果你想定义一个可重用的函数,你所要做的就是:

          function myFunction(idName,tagName) {
              var elements = document.getElementById(idName);
              var elementsByTag = elements.getElementsByTagName(tagName);
              for (i=0; i< elementsByTag.length; i++) {
                  alert('found a ' + tagName + ' element within element of id ' + idName);
              }
          }
          

          确实,如果这是您页面上需要的所有 JavaScript 功能,那么就不需要导入 jQuery。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-11-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多