代码之家  ›  专栏  ›  技术社区  ›  Hexagon Theory

将链接方法附加到JavaScript中的元素集合

  •  1
  • Hexagon Theory  · 技术社区  · 17 年前

    <div>a</div>
    <div>b</div>
    <div>c</div>
    <script>
    NodeList.prototype._ = function(s)
     {
        for (x = 0; x < this.length; x++)
         {
            eval('this[x]' + '.' + s);
         }
        return this;
     }
    document.getElementsByTagName('div')._("style.backgroundColor = 'red'")._('innerHTML += x');
    </script>
    

    目前,它在Opera中工作得很好;正如预期的那样,正在对所有div元素调用u方法,然后对传递给它的字符串求值 到上面 每个元素依次。注意,该方法允许链接,并且已经演示过,调用u来附加预测的 每个元素的innerHTML的迭代器变量。

    现在,两个问题。。。

    首先,有没有更好的方法来解决这个问题?我一直希望我能做到 document.getElementsByTagName('div').style.backgroundColor = "red"; 但是,唉,它还没有成为现实。这就是为什么我首先要这样做,以及为什么我如此简洁地命名方法;我试图尽可能地模拟它。

    NodeList HTMLCollection

    2 回复  |  直到 17 年前
        1
  •  1
  •   Hexagon Theory    17 年前

    我已经想出了一个可行的解决方案;使用这个方法来链式修改元素集合有什么本质上的坏处吗?

    <script>
    _ = function()
     {
        for (x = 0; x < arguments[0].length; x++)
         {
            for (y = 0; y < arguments[1].length; y++)
             {
                eval('arguments[0][x]' + '.' + arguments[1][y]);
             }
         }
     }
    </script>
    

    用法:

    divs = document.getElementsByTagName('div');
    _(divs, ["style.color = 'red'", "innerHTML += x"]);
    
        2
  •  0
  •   Ruan Mendes    15 年前

    /**
     * Sets a property on each of the elements in the list
     * @param {NodeList} list
     * @param {string} prop The name of property to be set, 
     *        e.g., 'style.backgroundColor', 'value'.
     * @param {mixed} value what to set the value to
     */
    function setListProp( list, prop, value) {    
        for (var i = 0; i < list.length; i++) {
            setProp(list[i], prop, value);
        }
    }
    
    /**
     * Avoids the use of eval to set properties that may contain dots
     * Why avoid eval? eval is slow and could be dangerous if input comes from 
     * an unsanitized source
     * @param {object} el object that will have its property set
     * @param {string} propName ('value', 'style.backgroundColor')
     * Example: setProp(node, 'style.backgroundColor', "#ddd");
     */
    function setProp(el, propName, value) {
        var propList = propName.split('.');
        // Note we're not setting it to the last value in the property chain
        for (var i=0; i < propList.length - 1 ; i++) {
            el = el[propList[i]];
        }
        var lastProperty = propList[propList.length -1];
        el[lastProperty] = value;
    }
    

    测试用例 使用Firefox访问google.com,在控制台中键入上述代码,然后键入以下内容:

    // Set tooltip on links
    setListProp( document.getElementsByTagName('a'), 'title', 'YEAH it worked');
    
    
    // Set bg to red on all links
    setListProp( document.getElementsByTagName('a'), 'style.backgroundColor', '#f00');
    

    更新

    /** 
     * This exists in many libs and in newer versions of JS on Array's prototype 
     * @param {Object[]} arr The array that we want to act on each element. 
     *                   Does not work for sparse arrays
     * @param {Function} callback The function to be called for each element, it will be passed
     *        the element as its first argument, the index as the secibd
     */
    function iterate(arr, callback) {
      for (var i=0,item; item=arr[i]; i++) {
        callback(item, i);
      }
    }
    

    你可以这样称呼它

    var as = document.getElementsByTagName('a'); 
    iterate( as, function(el, index) {
      el.style.backgroundColor = 'red';
      el.innerHTML += "Whatever";
    });