1

任意に設計された住所フォームの「出荷先」を検出し、その内容を解析するユーザースクリプトを作成しています。これを行うにはtr、アドレスのラベル( "Name"、 "Address1"など)とそれに対応するinputフィールドの両方を含むフォーム "rows"(要素である場合とそうでない場合があります)を見つける必要があります。鬼ごっこ。たとえば、次のスニペットでは次のようになります。

<div>
<label>MaidenName</label>
<table><tbody>
    <tr>
        <td><label>FirstName</label></td>
        <td><input value = "Bob"></td>
    </tr>
    <tr>
        <td><label>LastName</label></td>
        <td><input value = "Smith"></td>
    </tr>
    <tr>
        <td><label>CompanyName</label></td>
        <td><input value = "Ink Inc"></td>
    </tr>
</tbody></table>
</div>

trそれぞれに「名前」ラベルと入力フィールドが含まれているため、すべての要素を一致させたいと思います。divただし、 「MaidenName」ラベルはテーブル内のフィールドで見つかった一致よりも範囲が広いため、一致させたくありません。

これらの行(多くの場合、行ではdivなく要素)を見つけるための現在のアルゴリズムtrは、次のとおりです。

  • 適切な「名前」ラベルが付いたすべてのノードを検索します
  • 入力フィールドの祖先であるノードが見つかるまで、各ノードのDOMを上に向かって作業します
  • 次に、そこに到達するためにトラバースした子を削除し、セットの親要素のみを残します。

私が作業しているポートから変換すると、JQueryJavascriptは次のようになります。

// set up my two lists
var labelNodes = getLabelNodes();
var nodesWithAddress = 
    $().find("input[type='text']:visible, select:visible");

var pathToCommonParents = getLabelNodes()
    .parentsUntil(nodesWithAddressChildren.parents()).parent();

// keep the highest-level nodes, so we only have the common paths - 
//not the nodes between it and the labels.
return combinedNodeSet.filter(
    function (index) {return $(this).find(combinedNodeSet).length == 0});

これは機能します...しかし、オーバーヘッドをトラバースして比較することはすべて、私のパフォーマンスを完全に破壊します(これには5秒以上かかる場合があります)。

これを実装するためのより良い方法は何でしょうか?次の擬似コードの方が良いと思いますが、間違っている可能性があり、実装方法がわかりません。

var filteredSet = $().find(*).hasAnyOf(labelNodes).hasAnyOf(nodesWithAddress);
return filteredSet.hasNoneOf(filteredSet); 
4

2 に答える 2

2

アップデート

私はより良い解決策を見つけました(改訂版を参照)これはあなたにとって完璧に機能すると思います。

function getMySpeacialElements() {
    var aSpeacialElements = [];
    $("label").each(function() {
        var oParent = $(this).parent(),
            oSpeacial = oParent.parent();
        oSpeacial.children("*").each(function() {
            if ($(this).children("input").length) {
                aSpeacialElements.push(oSpeacial[0]);
            }
        });
    });
    return aSpeacialElements;
}

</ p>

ライブデモ

于 2012-07-27T22:41:36.077 に答える
0

michaの回答を一般化して、ページに依存しない方法で表示できるようにします(さまざまなタグとネストレベル)。

var labelNodes = getLabelNodes();
var returnNodes = $();

var regexAncestors = labelNodes.parent();

while (regexAncestors.length){
    regexAncestors = regexAncestors.not("body");
    var commonParentNodes = regexAncestors.has("input[type='text']:visible, select:visible");
    returnNodes.add(commonParentNodes);
    regexAncestors = regexAncestors.not(commonParentNodes).parent();
}
return returnNodes;
于 2012-07-30T18:35:11.460 に答える