上週產品經理提出一個需求:javascript
在編輯框中,用戶雙擊或直接選中左括號(右引號)或左引號(有引號),對其包含的全部字符(含括號或引號字符在內)進行高亮;前端
聽到這個需求的時候,個人心理活動是這樣的:「臥槽,這什麼需求,歷來沒見過。前端作得了嗎?」。 臉上笑嘻嘻,內心媽賣批,僞裝淡定的對產品經理說,沒那麼快作,排到3月份的計劃去吧~java
雙手撓頭,開始頭腦風暴
首先想到的是,搜索時,在搜索結果中對關鍵詞的進行高亮。這個思路很簡單,就是在搜索結果的文本中匹配關鍵詞,用個span標籤包裹,並給span標籤加個樣式便可。這個,好像跟需求相去甚遠啊!
百度了半天也沒找到相關的案例,沒事,咱們還有時間,能夠本身來造個輪子。數組
正確思路:spa
target.value.substring(selectionStart, selectionEnd); // target是文本對象
複製代碼
知道了怎麼獲取選中的文本和如何選中部分文本,接下來就是去實現了。設計
有了思路,實現就不難了,代碼很簡單,相信你們應該看一下就懂了,我就不在囉嗦了。
源碼:code
/** * 選中括號、引號,對其包含的全部字符進行高亮顯示 * @param target 目標對象 */
function keywordHighlight(target) {
var selectionStart = target.selectionStart, // 選中的文本的起始位置
selectionEnd = target.selectionEnd, // 選中的文本的結束位置
text = target.value, // 輸入框中的文本內容
selectValue = target.value.substring(selectionStart, selectionEnd); // 選中的文本
var tmpValue, // 待匹配的文本
tmpArr = [], // 用於存放切割後的待匹配文本的數組
stack = [], // 棧
endIndex; // 結束位置在tmpArr中的下標
// selectValue === '(',從前向後匹配
if (selectValue === '(') {
tmpValue = text.slice(selectionStart);
tmpArr = tmpValue.split("");
for (var i = 0, len = tmpArr.length; i < len; i++) {
if (tmpArr[i] === '(') {
stack.push(tmpArr[i]);
} else if (tmpArr[i] === ')') {
stack.pop();
if (stack.length === 0) {
endIndex = i + 1;
break;
}
}
}
if (endIndex) {
target.setSelectionRange(selectionStart, selectionStart + endIndex);
}
}
// selectValue === ')',從後向前匹配
if (selectValue.trim() === ')') {
tmpValue = text.slice(0, selectionEnd);
tmpArr = tmpValue.split("");
for (var j = tmpArr.length - 1; j >= 0; j--) {
if (tmpArr[j] === ')') {
stack.push(tmpArr[j]);
} else if (tmpArr[j] === '(') {
stack.pop();
if (stack.length === 0) {
endIndex = j;
break;
}
}
}
if (endIndex || endIndex === 0) {
target.setSelectionRange(endIndex, selectionEnd);
}
}
if (selectValue.trim() === '"') {
// 獲取引號出現次數
var count = (text.slice(0, selectionEnd).split('"')).length-1;
if (count % 2 !== 0) { // 引號出現次數爲奇數,從前向後匹配
// slice獲取匹配文本時length+1,獲取匹配下標時length+1,故最後 +1+1
endIndex = text.slice(selectionStart + 1,text.length).indexOf('"') + 1 + 1;
if (endIndex) {
target.setSelectionRange(selectionStart, selectionStart + endIndex);
}
} else { // 引號出現次數爲偶數,從後向前匹配
tmpValue = text.slice(0, selectionEnd).trim();
endIndex = tmpValue.slice(0,tmpValue.length-1).lastIndexOf('"');
if (endIndex || endIndex === 0) {
target.setSelectionRange(endIndex, selectionEnd);
}
}
}
};
複製代碼
參考文獻:《javascript高級程序設計》第三版對象