5

jQueryを使って検索したテキストを選択して返したい。

問題は; テキストの一部が<span>または他のインライン要素にある可能性があるため'waffles are tasty'、このテキストで検索する'I'm not sure about <i>cabbages</i>, but <b>waffles</b> <span>are</span> <i>tasty</i>, indeed.'と、一致するものは何も得られませんが、テキストは途切れることなく表示されます。

この HTML を例として使用してみましょう。

<div id="parent">
  <span style="font-size: 1.2em">
    I
  </span>
  like turtles 
  <span>
    quite a
  </span>
  lot, actually.

  <span>
    there's loads of
  </span>
  tortoises over there, OMG

  <div id="child">
    <span style="font-size: 1.2em">
      I
    </span>
    like turtles 
    <span>
      quite a
    </span>
    lot, actually.

    TURTLES!
  </div>
</div>

この (または同様の) JavaScript を使用すると:

$('div#parent').selectText({query: ['i like', 'turtles', 'loads of tortoises'], caseinsensitive: true}).each(function () {
  $(this).css('background-color', '#ffff00');
});
//The (hypothetical) SelectText function would return an array of wrapped elements to chain .each(); on them

この出力を生成したいでしょう:(明らかにコメントなしで)

<div id="parent">
  <span style="font-size: 1.2em">
    <span class="selected" style="background-color: #ffff00">
      I
    </span> <!--Wrap in 2 separate selection spans so the original hierarchy is disturbed less (as opposed to wrapping 'I' and 'like' in a single selection span)-->
  </span>
  <span class="selected" style="background-color: #ffff00">
    like
  </span>
  <span class="selected" style="background-color: #ffff00"> <!--Simple match, because the search query is just the word 'turtles'-->
    turtles
  </span> 
  <span>
    quite a
  </span>
  lot, actually.

  <span>
    there's
    <span class="selected" style="background-color: #ffff00">
      loads of
    </span> <!--Selection span needs to be closed here because of HTML tag order-->
  </span>
  <span class="selected" style="background-color: #ffff00"> <!--Capture the rest of the found text with a second selection span-->
    tortoises
  </span>
  over there, OMG

  <div id="child"> <!--This element's children are not searched because it's not a span-->
    <span style="font-size: 1.2em">
      I
    </span>
    like turtles 
    <span>
      quite a
    </span>
    lot, actually.

    TURTLES!
  </div>
</div>

(架空の)関数は、検索の一部が 、 '' などの他のインライン要素にあるかどうかに関係なく、SelectText選択されたすべてのテキストをタグでラップします。子のコンテンツはインライン要素ではないため、検索しません。<span class="selected"><span><div>

このようなことを行うjQueryプラグインはありますか? (検索クエリを span タグでラップして返します。見つかったテキストの一部が他のインライン要素に配置されている可能性があるかどうかを忘れていますか?)

そうでない場合、そのような関数を作成するにはどうすればよいでしょうか? この関数は私が探しているものですが、見つかったテキストの一部が他のインライン要素にネストされている場合、選択されたスパンとブレークの配列を返しません。

どんな助けでも大歓迎です!

4

5 に答える 5

4

簡単です!これを参照してください。

折り表記:

$.each(
    $(...).findText(...), 
    function (){
        ...
    }
);

インライン表記:

$(...).findText(...).each(function (){
        ...
    }
);
于 2013-11-02T02:39:56.450 に答える
1

私はたまたま今似たようなことに取り組んでいるので、「オプション 3」の私の解釈の始まりを見たい場合のために、これを共有したいと思いました。ノードは、既存のタグを変更せずにトラバースされます。一般的なブラウザではまだテストされていないため、このブラウザでは一切の保証がありません!

function DOMComb2 (oParent) {
    if (oParent.hasChildNodes()) {
        for (var oNode = oParent.firstChild; oNode; oNode = oNode.nextSibling) {
            if (oNode.nodeType==3 && oNode.nodeValue) { // Add regexp to search the text here
                var highlight = document.createElement('span');
                highlight.appendChild(oNode.cloneNode(true));
                highlight.className = 'selected';
                oParent.replaceChild(highlight, oNode);

                // Or, the shorter, uglier jQuery hybrid one-liner
                // oParent.replaceChild($('<span class="selected">' + oNode.nodeValue + '</span>')[0], oNode);
            }
            if (oNode.tagName != 'DIV') { // Add any other element you want to avoid
                DOMComb2(oNode);
            }
        }
    }
}

次に、おそらく jQuery を使用して選択的に検索します。

$('aside').each(function(){
    DOMComb2($(this)[0]);
});

もちろん、脇の中に脇があれば、おかしなことが起こるかもしれません。

(Mozilla dev リファレンス サイトhttps://developer.mozilla.org/en-US/docs/Web/API/Nodeから採用された DOMComb 関数 )

于 2013-11-01T00:31:45.933 に答える
0

私が理解したように、私たちは のようなイテレータについて話しています$.each($(...).searchText("..."),function (str){...});

David Herbert Lawrenceの詩をチェックしてください。

<div class="poem"><p class="part">I never saw a wild thing<br /> 
sorry for itself.<br /> 
A small bird will drop frozen dead from a bough<br />
without ever having felt sorry for itself.<br /></p></div>

実際、レンダリング後、ブラウザは次のように認識します。

<div class="poem">
<p class="part">
<br>I never saw a wild thing</br> 
<br>sorry for itself.</br> 
<br>A small bird will drop frozen dead from a bough</br>
<br>without ever having felt sorry for itself.</br> 
</p>
</div>

たとえば、次のフレーズを探しています"wild thing sorry for"。したがって、抜粋を強調する必要があります。

wild thing</br><br>sorry for

このようにラップできず<span>wild thing</br><br>sorry for</span>、一時的な id="search-xxxxxx" で jQuery セレクターを作成し、それを返すことができません - それは間違った html です。次のように各テキストをラップできます。

<span search="search-xxxxx">wild thing</span></br><br><span search="search-xxxxx">sorry for</span>

次に、いくつかの関数を呼び出して、セレクターの jQuery 配列を返す必要があります。

return($("[search=search-xxxxx]"));

これで、2 つの「結果」が得られまし。b) 「ごめんなさい」。それは本当にあなたが望むものですか?

また

jQuery の別のプラグインのように、独自のeach()関数を作成する必要があります。

$.fn.eachSearch = function(arr, func){
    ...
};

arr はセレクターの配列ではなく、次のようなセレクターの配列の配列になります。

arr = [
    {selector as whole search},
    {[{selector as first part of search]}, {[selector as second part of search]}},
    ...    
]
于 2013-11-01T18:40:21.040 に答える
0

私はフィドルとしてドラフトを書きました。主な手順:

jQueryのプラグインを作りました

$.fn.selectText = function(params){
    var phrases = params.query, 
        ignorance = params.ignorecase;
        wrapper = $(this);
    . . .
    return(wrapper);
};

これで、セレクションを$(...).selectText({query:["tortoise"], ignorance: true, style: 'selection'});

関数呼び出しの後にイテレータが必要なのはわかっていますが、イテレータは有効なjQueryセレクターを返さなければならないため、あなたの場合は不可能です。例: word <tag>word word</tag> wordは有効なセレクタではありません。

ラッパーのコンテンツをサニタイズした後、検索ごとmakeRegexp()に独自の正規表現を作成します。

検索された HTML ソースの各部分はemulateSelection()wrapWords()

<span class="selection">...</span>主なアイデアは、タグで区切られていないフレーズの各部分をラップすることですが、ノードのツリー全体を分析することではありません。

ノート:

<b><i>...HTMLのタグでは機能しません。そのため、正規表現文字列を修正する必要があります。Unicode で動作することを保証するものではありません。しかし、誰が知っている...

于 2013-10-31T23:02:35.007 に答える