我的总体目标是在点击网页后选择整个单词。
为此,我需要找到当前选择开头之前的第一个单词边界。感谢@4castle,我有一个正则表达式,正确识别单词边界。我目前的目标是使用此正则表达式向后搜索字符串,模仿stringHaystack.lastIndexOf(stringNeedle, offset)
的工作方式。
我目前的解决方案是在offset
点之前反转字符串的一部分,然后使用reverseString.search(regex)
,如下所示:
function searchBackwards (string, offset, regex) {
string = string.substring(0, offset)
var reverseString = ""
var ii = string.length
var backSet
while (ii--) {
reverseString += string[ii]
}
backSet = reverseString.search(regex)
offset = backSet < 0 ? 0 : offset - backSet
return offset
}
然而,我觉得必须有一个更优雅的解决方案。您对改进这种方法有什么建议吗?
编辑:按照@WiktorStribiżew的建议,我已将searchBackwards
功能更改为:
function searchBackwards(string, offset, regex) {
var adjust = 0
var result
string = string.substring(0, offset)
while (result = regex.exec(string)) {
offset = result.index
adjust = result[0].length
}
return adjust ? offset + adjust : 0
}
在我对Chrome的测试中,它的速度是我原来的两倍。
可测试示例:https://jsfiddle.net/77np9gp9/
工作代码:
var selection = window.getSelection()
document.body.onmouseup = selectWholeWords
function selectWholeWords() {
if (selection.rangeCount) {
var range = selection.getRangeAt(0)
// RegExp to detect word boundaries but to allow ' and - in
// the middle of words
// ^['-] - match a single-quote or a hyphen
// at the beginning
// [\s!-/:-@\[-`\{-~'-]{2,} - match a whole range of non-word
// characters pairs possibly
// including a ' or a -
// [\s!-/:-@\[-`\{-~] - match a whole range of non-word
// characters on their own
var regex = /^['-]|[\s!-/:-@\[-`\{-~'-]{2,}|[\s!-/:-@\[-`\{-~]/
var container = range.startContainer
var string = container.textContent
var offset = searchBackwards(string, range.startOffset)
range.setStart(container, offset)
container = range.endContainer
string = container.textContent
offset = range.endOffset
offset += string.substring(offset).search(regex)
if (offset < 0) {
offset = string.length
}
range.setEnd(container, offset)
selection.removeAllRanges()
selection.addRange(range)
}
function searchBackwards (string, offset) {
string = string.substring(0, offset)
var reverseString = ""
var ii = string.length
var backSet
while (ii--) {
reverseString += string[ii]
}
backSet = reverseString.search(regex)
offset = backSet < 0 ? 0 : offset - backSet
return offset
}
}