この回答に示されている手法を使用して、Webページの選択範囲を単語の境界まで拡張しています。
function snapSelectionToWord() {
var sel;
// Check for existence of window.getSelection() and that it has a
// modify() method. IE 9 has both selection APIs but no modify() method.
if (window.getSelection && (sel = window.getSelection()).modify) {
sel = window.getSelection();
if (!sel.isCollapsed) {
// Detect if selection is backwards
var range = document.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
var backwards = range.collapsed;
range.detach();
// modify() works on the focus of the selection
var endNode = sel.focusNode, endOffset = sel.focusOffset;
sel.collapse(sel.anchorNode, sel.anchorOffset);
if (backwards) {
sel.modify("move", "forward", "word");
sel.extend(endNode, endOffset);
sel.modify("extend", "backward", "word");
} else {
sel.modify("move", "backward", "word");
sel.extend(endNode, endOffset);
sel.modify("extend", "forward", "word");
}
}
} else if ( (sel = document.selection) && sel.type != "Control") {
var textRange = sel.createRange();
if (textRange.text) {
textRange.expand("word");
// Move the end back to not include the word's trailing space(s),
// if necessary
while (/\s$/.test(textRange.text)) {
textRange.moveEnd("character", -1);
}
textRange.select();
}
}
}
ここまでは順調ですね。ただしsnapSelectionToWord
、選択範囲で関数を複数回呼び出すと、呼び出しごとに双方向に1語ずつ拡張されます。これは、テキストが選択されているときに関数を複数回呼び出す場合には適していません。
これは、問題を示す「スナップ」ボタンを繰り返しクリックできるライブjsFiddleの例です。
元のソリューションを修正して、すでに単語の境界にある場合に選択範囲が拡張されないようにするにはどうすればよいですか?
- 元の解決策についてコメントを残したいのですが、残念ながら、StackOverflowカルマ旅団から十分なカルマがまだ与えられていません。それ以外の場合は、そこで質問します。また、問題を解決する方法がわからないため、元のソリューションを編集しません。
編集:リクエストごとにコードスニペットを追加