2

ページから要素 (通常は <div>) を取得し、そこから特定の子要素があるかどうかを判断する純粋な JavaScript 関数を作成しようとしています。これは基本的に、テキスト コンテンツを意味する任意のタグである so:<p>または任意のヘッダー タグ so ( <h1>.. <h6>) またはリストなどです。

これらの要素を操作するつもりはありません。単にそれらの存在を確認するだけです。

したがって、関数は次の形式になります

/**
 * Takes an element and returns whether
 * the element contains content
 * @return boolean (true/false)
 */
var isContent = function (elementToCheck) {

};

document.getElementsByTagName('div')現在、ページのすべての<div>要素を取得するために使用しています。次に、これらを一度に 1 つずつ関数に解析します。

私は現在これを下げています

var isContent = function (elementToCheck) {
    if (elementToCheck.hasChildNodes()) {
        var children = elementToCheck.childNodes;

        for (var i = 0; i < children.length; i++) {
            // handle children[i]
        }
   }
}

私はさまざまなものとの同等性を使用してテストしてきましたがchilren[i].nodeValue、どれも合格できません。

これを続けるための最良の方法は何ですか?これの外側にあるすべての要素を取得し、それらをループしてここで解析し、別のループを実行する必要があるため、厄介な関数になっていると思います。正規表現でそれが可能かどうか疑問に思っていますか?

4

3 に答える 3

1

<div>空でないコンテンツ モデルを持つ少なくとも 1 つの子ノードを持つすべての要素を検索する場合は、IE8 に戻る (および含む) すべてのブラウザーで次のようなものが機能します。

function findDivWithContents() {
  var allDivs = document.getElementsByTagName('div');
  var di, divs = [];
  for (di = 0; di < allDivs.length; ++di) {
    if (allDivs[di].querySelectorAll('p, span, h1, h2, h3, h4, ... ').length > 0)
      divs.push(allDivs[di]);
  return divs;
}

これは.querySelectorAll()、コンテナ要素を見つけるために使用します。(もちろん、リストを完成させる必要があります。)

編集する代わりに、逆方向に実行することもできます: 関心のあるすべてのコンテナ型要素を繰り返し処理し、それらの親が であるかどうかを確認します<div>:

function findTheDivs() {
  var containers = document.querySelectorAll('p, span, div, h1, h2, h3, ... ');
  var i, divs = [];
  for (i = 0; i < containers.length; ++i) {
    if (containers[i].parentNode.tagName === 'DIV')
      divs.push(containers[i].parentNode);
  return divs;
}

多分これで効率が上がると思います。<div>(複数回リストに追加するのを避けるために、意味のない「クラス」マーカーをそれぞれに追加する必要がある場合があります。)

于 2013-03-28T13:52:49.993 に答える
0

この方法では、jQuery は必要ありません。テキスト コンテンツが必要なタグを指定する必要はありません (ただし指定できます)。また、見つかったテキストに正規表現を適用できます。

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
    function logTextContent(elem) {
    var childNodes = elem.childNodes;
    for(var i=0; i<childNodes.length; i++) {
        var nodex = childNodes[i];
        if(nodex.nodeType == 3 /* text node */) {
        var textContent = nodex.nodeValue;
        if(textContent.match(/\S+/) /* apply regex */) {
            console.log("found text: "+textContent);
        }
        }
        else if (nodex.nodeType == 1 /* element node*/) {
        logTextContent(nodex)
        }
    }
    }
    function findDocumentTexts() {
    var docElems = document.getElementsByTagName("body");
    for(var i=0; i<docElems.length; i++) {
        var elem = docElems[i];
        logTextContent(elem);
    }
    }
</script>
</head>
<body>
<button onclick="findDocumentTexts()">find document texts</button>
<!-- I will fail -->
<div>
    <!-- I will pass -->
    <div>
    <h1>Heading</h1>
    <p>
        I should be found straight away
    </p>
    </div>
    <!-- I will fail -->
    <div>
    <!-- I will pass -->
    <div>
        <p>
        I will be missed by the first div but found by the second
        </p>
    </div>
    </div>
</div>
</body>
</html>
于 2013-03-28T14:59:47.200 に答える
0

私はこれに大騒ぎしましたが、Pointy は私にとって新しい機能について言及しており、これによりループquerySelectorAll()をカットできる可能性があります。containsTextElements

var textTags = ["h1", "h2", "h3", "h4", "h5", "h6", "p"];

var containsTextElements = function(elementToCheck) {

    for (var i = 0; i < textTags.length; i++) {
        if(elementToCheck.getElementsByTagName(textTags[i]).length > 0)
            return true;    
    }
    return false;
}

var doStuffToDivsWithText = function(callback) {

    var divs = document.getElementsByTagName("div");
    for(var i = 0; i < divs.length; i++ ) {
        if(containsTextElements(divs[i]))
            callback(divs[i]); 
    };
}

doStuffToDivsWithText(function(div) {
    console.log(div.id);
});
于 2013-03-28T14:56:53.187 に答える