0

.getElementBy...現在、JavaScript で DOM 呼び出しを使用している関数があります。

var $ = function (selector) {
  var elements = [];

  var lastSelector  = selector.substring(selector.search(/[^#.]+$/), selector.length);

  if(selector.includes('#') !== true || selector.includes('.') !== true) {
    elements.push(document.getElementsByTagName(lastSelector));
    elements = Array.prototype.slice.call(elements[0]);
  }

return elements;
};

コードを使用する関数には、他にも多数の if ステートメントがあります。

elements.push(document.getElementsByTagName(lastSelector));
elements = Array.prototype.slice.call(elements[0]);

また

elements.push(document.getElementsByClassName(lastSelector));
elements = Array.prototype.slice.call(elements[0]);

理想的には、繰り返しをDRYしたいと思います:

elements = Array.prototype.slice.call(elements[0]);

ifしかし、要素がまだ入力されていないため、ステートメントの前に定義することはできません。したがって、空の配列とエラーでコードを実行しようとします。

助言がありますか?

4

2 に答える 2

1

セレクターによって要素を選択するために自作の限定機能を使用する代わりに、querySelectorAll()IE8+ を含むすべてのブラウザーで利用可能な標準を使用することができます。

配列のようなオブジェクト (DOM コレクションなど) を実数Array(Array.prototype.slice.call()コードで使用されるもの) に変換するには、次の関数を使用します。

var arrayFrom = function(arrayLike) {
    if (Array.from) {
        return Array.from(arrayLike);
    }

    var items;

    try {
        items = Array.prototype.slice.call(arrayLike, 0);
    }
    catch(e) {
        items = [];

        var count = arrayLike.length;

        for (var i = 0; i < count; i++) {
            items.push(arrayLike[i]);
        }
    }

    return items;
};

または、ブラウザーが非Array引数の受け渡しをサポートしていない場合は、次の簡略化されたバージョンArray.prototype.slice.call()(IE8-私が正しく思い出せば) は問題ではありません。

var arrayFrom = function(arrayLike) {
    return Array.from
         ? Array.from(arrayLike);
         : Array.prototype.slice.call(arrayLike, 0);
};
于 2016-06-27T22:47:35.203 に答える
0

確かに@marat-tanalinの回答を検討してください。使用querySelectorAll()がオプションではない場合、次のことがうまくいきました。@ master565 の助けに感謝します。

まず、行を折り返します。

elements.push(document.getElementsByTagName(lastSelector));
elements = Array.prototype.slice.call(elements[0]);

関数で:

function pushByTag(selector) {
  elements.push(document.getElementsByTagName(selector));
  elements = Array.prototype.slice.call(elements[0]);
}

物をかなり乾燥させます。if次に、引数に変数を設定すると、非常に役立ちました。

if(selector.includes('#') !== true || selector.includes('.') !== true)

なりました:

var noClassOrId = selector.includes('#') !== true || selector.includes('.') !== true;

これらの両方のリファクタリングにより、ifステートメントを 1 行にまとめて、かなり読みやすいと主張することができました。

if (noClassOrId) pushByTag(lastSelector);
于 2016-06-28T11:34:39.590 に答える