按需求弄了一個 取詞 以及 標紅 的小應用。
先上demo :http://qianduannotes.sinaapp.com/getKeyword/
很多平時常用的東西,都用上了,所以拿出來說說。
一、代碼
var GetKeywords = {
str: "",
limit: 11,
keywords:[],
init : function(){
var box = this._("article"),
_this = this;
//獲取已經存在的關鍵詞
this.getAllKeyWord();
//讓rmKeyWord函數全局化
window.rmkeyWord = this.rmkeyWord;
//取詞事件
box.onmouseup = function(evt){
var evt = evt || window.event,
target = evt.target || evt.srcElement;
//如果鼠標是在button上彈起,則忽略
if(target.id == "btn") return;
GetKeywords.str = _this.getSelectionText();
if(_this.str.length == 0) return;
if(_this._("btn")) {
_this.removeBtn();
if(GetKeywords.str == "") return;
_this.createBtn(evt);
return;
}
_this.createBtn(evt);
}
},
//工具函數
_: function(obj){
return document.getElementById(obj);
},
//獲取選中文本
getSelectionText: function(){
if(window.getSelection) {
return window.getSelection().toString();
} else if(document.selection && document.selection.createRange) {
return document.selection.createRange().text;
}
return '';
},
//創建按鈕
createBtn: function(evt){
var button = document.createElement("div"),
evt = evt || window.event,
x = evt.pageX || evt.x,
y = evt.pageY || evt.y,
i, j, len,
cssList = "",
_this = this,
csses = {
"height" : "30px",
"line-height" : "30px",
"position": "absolute",
"top": y + 10 + "px",
"left": x + 10 + "px",
"cursor": "pointer",
"border": "1px solid #000",
"background": "#EEE",
"padding": "2px 8px",
"border-radius": "3px"
};
for(i in csses){
if(csses.hasOwnProperty(i)){
cssList += i + ":" + csses[i] + ";";
}
}
button.style.cssText = cssList;
button.innerHTML = "添加到關鍵詞列表";
button.setAttribute("id", "btn");
this._("article").appendChild(button);
button.onclick = function(){
if(_this.str.length > _this.limit){
alert("關鍵詞長度最長為11,可以通過設置GetKeywords.limit來控制長度。");
_this.removeBtn();
return;
}
for(j = 0, len = GetKeywords.keywords.length; j < len; j++){
if(GetKeywords.keywords[j] == _this.str){
alert("已經存在該關鍵詞了~");
_this.removeBtn();
return;
}
continue;
}
_this.keywords.push(_this.str);
_this.setRed(_this.str);
_this.addTo();
_this.removeBtn();
};
},
//刪除按鈕
removeBtn: function(){
var btn = this._("btn");
btn.parentNode.removeChild(btn);
},
//加入到關鍵詞里列表
addTo: function(){
var word = this._("wordList");
word.innerHTML += "<span><font>" + this.str + "</font><a href='#' onclick='rmkeyWord(this);'></a></span>";
},
//關鍵詞標紅
setRed: function(str){
var content = this._("article"),
temp = '(' + str + ')';
reg = new RegExp(temp,'g');
content.innerHTML = content.innerHTML.replace(reg, "<span style='color:red;'>$1</span>");
},
//刪除標紅
rmRed: function(str){
var content = this._("article"),
temp = "(<span[^<]*" + str + "</span>)";
reg = new RegExp(temp,'gi');
content.innerHTML = content.innerHTML.replace(reg, str);
},
//獲取已經存在的關鍵詞(也可以用來獲取所有關鍵詞)
getAllKeyWord: function (){
var spans = this._("wordList").getElementsByTagName("span"),
key = [], i = 0, len;
for(len = spans.length; i < len; i++){
var font = spans[i].getElementsByTagName("font")[0];
var temp = font.innerText || font.textContent;
this.setRed(temp);
key.push(temp);
}
this.keywords = key;
},
//刪除關鍵詞
rmkeyWord: function (obj){
var target = obj.parentNode,
word = obj.previousSibling.innerHTML,
i = 0, len;
GetKeywords.rmRed(word);
for(len = GetKeywords.keywords.length; i < len; i++){
if(GetKeywords.keywords[i] == word){
GetKeywords.keywords.splice(i,i);
}
continue;
}
target.parentNode.removeChild(target);
return;
}
}
GetKeywords.init();
以上是所有js代碼,比較長,下面將列舉一些比較突出的點(望高人多多指點)。
二、代碼分析
1.獲取文本
getSelectionText: function(){ if(window.getSelection) { return window.getSelection().toString(); } else if(document.selection && document.selection.createRange) { return document.selection.createRange().text; } return ''; }
這個在以前(JavaScript操控光標,你會么?)的文章里也說過,就不贅述了。
2.創建控制框
createBtn: function(evt){ var button = document.createElement("div"), //... csses = { "height" : "30px", "line-height" : "30px", "position": "absolute", "top": y + 10 + "px", "left": x + 10 + "px", "cursor": "pointer", "border": "1px solid #000", "background": "#EEE", "padding": "2px 8px", "border-radius": "3px" }; for(i in csses){ if(csses.hasOwnProperty(i)){ cssList += i + ":" + csses[i] + ";"; } } button.style.cssText = cssList; button.innerHTML = "添加到關鍵詞列表"; button.setAttribute("id", "btn"); //... }
這里有一點我想說說,在寫js的時候,會經常涉及到對DOM對象style的處理,如果不想額外加入一個plugins.css之類的文件,可以像上面一樣,將樣式放置在一個對象中,然后利用for in將其寫入,本來開始我用的是
obj.style[i] = csses[i];
不知道為什么,在IE下報錯了,后來便用cssText代替。
效果:
3.標紅
//關鍵詞標紅 setRed: function(str){ var content = this._("article"), temp = '(' + str + ')'; reg = new RegExp(temp,'g'); content.innerHTML = content.innerHTML.replace(reg, "<span style='color:red;'>$1</span>"); }
這里主要就是正則表達式的事情了,正則的話,推薦兩篇文章
哈哈,相信用過正則的人不需要我來解釋這個$1了吧,他的意思就是匹配到的第一個。
當然,刪除標紅和這個原理是差不多的。
//刪除標紅 rmRed: function(str){ var content = this._("article"), temp = "(<span[^<]*" + str + "</span>)"; reg = new RegExp(temp,'gi'); content.innerHTML = content.innerHTML.replace(reg, str); }
這里是寫完這篇blog才發現的一個bug, IE下如果rmRed中的正則是'g',貌似該函數會無效,在IE8控制台下查看,NND,輸出innerHTML中的標簽全部變成大寫了,無奈,只好改成'gi'。
4.獲取所有關鍵詞和刪除關鍵詞
//獲取已經存在的關鍵詞(也可以用來獲取所有關鍵詞) getAllKeyWord: function (){ //... }, //刪除關鍵詞 rmkeyWord: function (obj){ //... GetKeywords.rmRed(word); for(len = GetKeywords.keywords.length; i < len; i++){ if(GetKeywords.keywords[i] == word){ GetKeywords.keywords.splice(i,i); } continue; } //... }
這個地方,有一個疑問,在調用的時候,使用this.keywords沒反應,但是改成GetKeywords就行了,還沒研究具體原因是什么~
5.初始化
GetKeywords.init();
init()為總入口,進去之后,先獲取已經存在的關鍵詞,然后標紅,接着綁定onmouseup事件。
三、然后
當然咯,這個案例的ajax部分還沒寫,弄完之后還得給后台送過去。。好吧,明天接着弄吧。
寫這玩意兒還是花了點功夫,不過鄙人寫代碼的水平還在初級階段,望大神們不要吐槽,多提寶貴意見,謝謝!
然后,還是那個demo,http://qianduannotes.sinaapp.com/getKeyword/
順便,推廣下,團隊做的一個網站,主要技術是爬蟲,高峰期PV穩定在120W以上,找工作的童鞋可以多去踩踩~
P.S:剛讓隊友測試,還是發現了不少bug,果然考慮問題還是不全面啊~還要繼續加油。。。


