Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 修改每个可能的DOM元素的原型_Javascript_Cross Browser_Getelementsbyclassname - Fatal编程技术网

Javascript 修改每个可能的DOM元素的原型

Javascript 修改每个可能的DOM元素的原型,javascript,cross-browser,getelementsbyclassname,Javascript,Cross Browser,Getelementsbyclassname,更新标题以更好地反映我正在努力做的事情 简而言之,不同的dom元素有不同的构造函数,它们似乎并不共享一个共同的原型。我正在寻找通过修改这些原型向每个DOM元素添加函数属性的方法,但我不确定如何找到它们 例如,我可以这样做: function enhanceDom (tagNames, methods) { var i=-1, tagName; while (tagName=tagNames[++i]) { var tag=document.createElement(tagNam

更新标题以更好地反映我正在努力做的事情

简而言之,不同的dom元素有不同的构造函数,它们似乎并不共享一个共同的原型。我正在寻找通过修改这些原型向每个DOM元素添加函数属性的方法,但我不确定如何找到它们

例如,我可以这样做:

function enhanceDom (tagNames, methods) {
  var i=-1, tagName;
  while (tagName=tagNames[++i]) {
    var tag=document.createElement(tagName);
    if (!(tag && tag.constructor)) continue;
    for (var methodName in methods) {
      tag.constructor.prototype[methodName]=methods[methodName];
    }
  }
}

var thingsToEnhance = ['a','abbr','acronym','address'/* on and on... */];

enhance(thingsToEnhance, {
  doStuff : function(){
    /* ... */
  },
  doOtherStuff : function(){
    /* ... */
  } 
  /* ... */
});
当然,我不想列出每一个html元素。有人能想出更好的办法吗

(原质询如下)

Goal-使
getElementsByClassName
在任何浏览器中的任何DOM节点上工作

这是以前做过的(有点),但这是我的尝试

我的问题是,有没有一种好的方法可以让动态创建的元素起作用?HTMLDOM元素似乎不共享一个可以添加
getElementsByClassName
的公共可预测原型。。。还是我遗漏了什么

以下是我到目前为止得到的信息(编辑-根据讨论进行更新)


它在加载脚本之前加载的内容上运行良好,但是动态创建的新元素不会得到
getElementsByClassName
方法。有什么建议吗(除了setInterval,请)?

我认为您想要的可以通过原型化来实现,比如

但是不要这样做。它并不是在所有主流浏览器中都能可靠地工作

你在问题的例子中所做的也是不可取的。实际上,您正在扩展主机对象。同样,请不要这样做

你会落入那些陷阱

我不想仅仅复制Kangax的文章,所以请阅读


你为什么一开始就想要这个?你的目标是什么?

这似乎可行,但很难看。我想知道它在IE中是否有效

(function(){

  enhanceDom('a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol optgroup option p param pre q s samp script select small span strike strong style sub sup table tbody td textarea tfoot th thead title tr tt u ul var'
  ,{
    getElementsByClassName : getByClass
    /* , ... */
  });

  function enhanceDom (tagNames, methods) {
    var i=-1, tagName;
    if (tagNames==''+tagNames) {
      tagNames=tagNames.split(' ');
    }
    for (var methodName in methods) {
      setIfMissing(document, methodName, methods[methodName]);
      while (tagName=tagNames[++i]) {
        var tag=document.createElement(tagName);
        if (tag || !tag.constructor) continue;
        var proto=tag.constructor.prototype;
        setIfMissing(proto, methodName, methods[methodName]);
      }
    }
  }

  function setIfMissing (obj, prop, val) {
    if (typeof obj[prop] == 'undefined') {
      obj[prop]=val;
    }
  }

  function withDescendants (node, callback, userdata) {
    var nodes=node.getElementsByTagName('*'), i=-1;
    while (node=nodes[++i]) {
      callback(node, userdata);
    }
    return userdata;
  }

  function getByClass (className) {
    return withDescendants(this, getMatches, {
      query:new RegExp('(^|\\s+)' + className + '($|\\s+)'), 
      found:[]
    }).found;
  }

  function getMatches (node, data) {
    if (node.className && node.className.match(data.query)) {
      data.found.push(node);
    }
  }

}());

您决定不使用jQuery这样的框架是有原因的吗?如果是这样的话,你可能想在你的问题中说明这一点,否则你会得到很多“使用jQuery!”的答案。我希望很明显,我不打算为此使用jQuery。祝你好运。@Greg在发布的代码中没有JQuery代码,也没有JQuery标记,我认为已经足够了……也许你应该看看Sizzle(在这里插入强制性的“使用JQuery!”回答)这篇很棒的文章。我意识到修改宿主对象的一些危险。这个实验的总体目标是创建一个兼容性层,这样所有脚本都可以在单个浏览器上测试,并且可以跨浏览器工作,而无需修改。不是创建一个新的库,只是为了扩展没有特定功能的浏览器,以便它们与我们的开发人员测试的浏览器一样工作。它将只用于内部的东西(其中一些已经积累),而不是作为GP库使用。
Element
或HTMLElement可能是我想要的。这一点上的跨浏览器支持太糟糕了。将此标记为正确。
Element.prototype.getElementsByClassName = function() {
    /* do some magic stuff */
};
(function(){

  enhanceDom('a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol optgroup option p param pre q s samp script select small span strike strong style sub sup table tbody td textarea tfoot th thead title tr tt u ul var'
  ,{
    getElementsByClassName : getByClass
    /* , ... */
  });

  function enhanceDom (tagNames, methods) {
    var i=-1, tagName;
    if (tagNames==''+tagNames) {
      tagNames=tagNames.split(' ');
    }
    for (var methodName in methods) {
      setIfMissing(document, methodName, methods[methodName]);
      while (tagName=tagNames[++i]) {
        var tag=document.createElement(tagName);
        if (tag || !tag.constructor) continue;
        var proto=tag.constructor.prototype;
        setIfMissing(proto, methodName, methods[methodName]);
      }
    }
  }

  function setIfMissing (obj, prop, val) {
    if (typeof obj[prop] == 'undefined') {
      obj[prop]=val;
    }
  }

  function withDescendants (node, callback, userdata) {
    var nodes=node.getElementsByTagName('*'), i=-1;
    while (node=nodes[++i]) {
      callback(node, userdata);
    }
    return userdata;
  }

  function getByClass (className) {
    return withDescendants(this, getMatches, {
      query:new RegExp('(^|\\s+)' + className + '($|\\s+)'), 
      found:[]
    }).found;
  }

  function getMatches (node, data) {
    if (node.className && node.className.match(data.query)) {
      data.found.push(node);
    }
  }

}());