次のスクリプトを使用して、強調表示されたテキストの位置を取得しています。
function getSelectionCharOffsetsWithin(element) {
var start = 0, end = 0;
var sel, range, priorRange;
if (typeof window.getSelection != "undefined") {
range = window.getSelection().getRangeAt(0);
priorRange = range.cloneRange();
priorRange.selectNodeContents(element);
priorRange.setEnd(range.startContainer, range.startOffset);
start = priorRange.toString().length;
end = start + range.toString().length;
} else if (typeof document.selection != "undefined" &&
(sel = document.selection).type != "Control") {
range = sel.createRange();
priorRange = document.body.createTextRange();
priorRange.moveToElementText(element);
priorRange.setEndPoint("EndToStart", range);
start = priorRange.text.length;
end = start + range.text.length;
}
return {
start: start,
end: end
};
}
function alertSelection() {
var mainDiv = document.getElementById("detailBoxParagraph");
var sel = getSelectionCharOffsetsWithin(mainDiv);
alert(sel.start + ": " + sel.end);
}
さて、これを on で使用すると$('p').text()
、
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
すべてがうまく機能します。しかし、タグ('p').html()
のために明らかに異なる$の位置も取得する必要があります<b>
Lorem ipsum dolor `<b>sit</b>` amet, consetetur sadipscing elitr.
これを防止または変更するにはどうすればよいですか?
編集:
私が最初に考えたのは、タグが発生した回数を数え、その値を使用して新しい位置を計算することでしたが、これはどういうわけかばかげています。
私の2番目のアプローチは、タグを作品のアスタリスクに置き換えることでした.text()
編集#2
これは、問題を示す厄介なフィドルです。マウスでテキストを強調表示してからボタンをクリックすると、最初は正しく太字に設定されます。2回目は正しく動作しません。
すぐにフィドルをきれいにします
編集 #3
以下で説明するハイライト プラグインを少しいじってみましたが、マークされた文字列のみに影響するように機能を制限することはできませんでした。一致するすべての単語または最初に出現した単語のみが強調表示されます。誰でも助けることができますか?
必要なコードは次のとおりです。
jQuery.fn.highlight = function(pat) {
this.length = 1 ;
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
}
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < 1; ++i) { // So it will highlight only the first occurence.
i += innerHighlight(node.childNodes[i], pat);
}
}
return skip;
}
return this.length && pat && pat.length ? this.each(function() {
innerHighlight(this, pat.toUpperCase());
}) : this;
};
編集#4
さて、私はそのjavscriptを理解しようとしました。私が見る限り、これは実行できません。なぜなら、highlight() は単純な文字列をパラメーターとして呼び出されるからです。この文字列の位置を知ることはできません。位置を解析してから、その位置から検索を試み、最初に出現したものを強調表示してから中止することができますか?