Javascript综合应用小案例(续)
上一篇文章,弄了一個 取詞?和 標紅 功能的小應用,但是存在一些bug,今天修修補補,順便也把ajax部分補上了~
?
Demo地址::http://qianduannotes.sinaapp.com/getKeyword/
?
代碼部分:
var GetKeywords = {str: "",limit: 11,keywords:[],url: "./tool.php",//page idgetId: function(){this.id = this._("wp").getAttribute("data-page");},init : function(){var box = this._("article"),_this = this;//獲取已經存在的關鍵詞this.getAllKeyWord();//獲取頁面IDthis.getId();//讓rmKeyWord函數(shù)全局化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){_this.removeBtn();return;} if(_this._("btn")) {_this.removeBtn();if(GetKeywords.str == "") return;_this.createBtn(evt);return;}_this.createBtn(evt);}var types = document.getElementsByTagName("input");for(var j = 0, len = types.length; j < len; j++){(function(j){types[j].onchange = function(){_this.sendData(j + 1, "change");}})(j);}},//工具函數(shù)_: 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 '';},//創(chuàng)建按鈕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.sendData(_this.str);_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='#' οnclick='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;res = GetKeywords.sendData(word, "del");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);var evt = arguments.callee.caller.arguments[0];try{evt.preventDefault();}catch(e){window.event.returnValue = false;}},//ajaxsendData: function(data, action){var xmlhttp,action = action || "add",_this = this;if (window.XMLHttpRequest){xmlhttp = new XMLHttpRequest();}else{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}xmlhttp.open("GET", this.url + "?" + action + "=" + data + "&id=" + this.id, true);xmlhttp.onreadystatechange = function(){if (xmlhttp.readyState == 4 && xmlhttp.status == 200){_this.sendSuccess(xmlhttp.responseText);}}xmlhttp.send();},sendSuccess:function(data){window.console && window.console.log && window.console.log(data);} }GetKeywords.init();
一、ajax部分
sendData: function(data, action){var xmlhttp,action = action || "add",_this = this;if (window.XMLHttpRequest){xmlhttp = new XMLHttpRequest();}else{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}xmlhttp.open("GET", this.url + "?" + action + "=" + data + "&id=" + this.id, true);xmlhttp.onreadystatechange = function(){if (xmlhttp.readyState == 4 && xmlhttp.status == 200){_this.sendSuccess(xmlhttp.responseText);}}xmlhttp.send();},sendSuccess:function(data){window.console && window.console.log && window.console.log(data); }感覺這里真心就沒什么好說的,因為這玩意兒涉及到數(shù)據(jù)的提交、刪除、和更新,所以GET的狀態(tài)也分為add、del、change。
默認的提交狀態(tài)是add,代碼中已經標紅。
?
二、刪除關鍵詞
上次也說了這個部分,但是里邊用到了一個splice,在這里稍微詳細描述下。
rmkeyWord: function (obj){var target = obj.parentNode,word = obj.previousSibling.innerHTML,i = 0, len;res = GetKeywords.sendData(word, "del");GetKeywords.rmRed(word);for(len = GetKeywords.keywords.length; i < len; i++){if(GetKeywords.keywords[i] == word){GetKeywords.keywords.splice(i,i); //刪除第i個元素}continue;}target.parentNode.removeChild(target);var evt = arguments.callee.caller.arguments[0];try{evt.preventDefault();}catch(e){window.event.returnValue = false;} },splice() 方法用于插入、刪除或替換數(shù)組的元素。
這個方法可刪除從 index 處開始的零個或多個元素,并且用參數(shù)列表中聲明的一個或多個值來替換那些被刪除的元素。
arrayObject.splice(index,howmany,element1,.....,elementX)| index | 必需。規(guī)定從何處添加/刪除元素。 該參數(shù)是開始插入和(或)刪除的數(shù)組元素的下標,必須是數(shù)字。 |
| howmany | 必需。規(guī)定應該刪除多少元素。必須是數(shù)字,但可以是 "0"。 如果未規(guī)定此參數(shù),則刪除從 index 開始到原數(shù)組結尾的所有元素。 |
| element1 | 可選。規(guī)定要添加到數(shù)組的新元素。從 index 所指的下標處開始插入。 |
| elementX | 可選。可向數(shù)組添加若干元素。 |
1)插入
ArrayObj.splice(2, 0, "addObj");即為在數(shù)組第三個位置插入一個名為“addObj”的字符串。
?
2)刪除
ArrayObj.splice(2, 2);即為刪除從第三個開始的連續(xù)兩個數(shù)組元素。
?
3)插入
ArrayObj.splice(2, 1,"replaceObj");即為替換第三個元素(也可以說是刪除從第三個元素開始的連續(xù)一個元素,然后添加一個名為“replaceObj”的字符串)。
?
來一個綜合應用的:
ArrayObj.splice(2, 2,"replaceObj_1","replaceObj_2");?即為刪除從第三個元素開始的連續(xù)兩個元素,然后在剛才刪除的位置,添加名為“replaceObj_1”,“replaceObj_2”的兩個字符串。相信應該已經比較清楚了吧~O(∩_∩)O~
注:splice() 方法與 slice() 方法的作用是不同的,splice() 方法會直接對數(shù)組進行修改。
?
三、遇到的問題
1. this指定的對象
對象方法中this并不一定指向對象本身,即使寫了
f: function(){var _this = this; //然后在閉包中使用_thisfunction name(){_this.doSomething();//這是的_this也不一定是對象本身 } }這是_this也不一定是指向該對象,[object global],有可能指向的是這個對象~
?
2. event的兼容性
相信evt = evt || window.event,大家都明白,但是在FF下:
function test(evt){var evt = evt || window.event;//... }在調用test()的時候,如果沒有加參數(shù),evt為undefined,使用過程需要test(evt);當然也可以這樣:
function test(){var evt = argument.callee.caller.argument[0];//... }?
4. for-in的問題
for(i in csses){if(csses.hasOwnProperty(i)){cssList += i + ":" + csses[i] + ";";//button.style[i] = csses[i];
}
}
button.style.cssText = cssList;
開始的時候,我用的是注釋里的方法button.style[i] = csses[i],但在IE下報錯了,后來就用的上面方式實現(xiàn),具體為什么我也不知道。。
?
5. 標簽解析的問題
IE載入DOM之后,會把所有的標簽解析成大寫的,這個至少在IE7和8是如此,IE9以上沒測試,就不知道了~
?
6. JS一些常見的瀏覽器兼容問題
這里提到的有:
- evt || window.event
- evt.target || evt.srcElement
- evt.x || evt.pageX || evt.layerX
- evt.preventDefault() Vs window.event.returnValue = false
- XMLHttpRequest ||?ActiveXObject("Microsoft.XMLHTTP")
- obj.innerText || obj.textContent
- window.getSelection || document.selection
?
四、參考
- W3School splice
?
五、結語
我認為,對象里的數(shù)據(jù),能單獨提取出來盡量單獨提出來,不要把所有的常量都當做字面量放置在有需求的地方,用一個變量緩存的話,修改起來也十分方便。對象里的方法,能分離的分離,盡量不要一個嵌套著一個,搞不好就是一個泄露內存的閉包,分離出來,作為對象的直接方法,既可以方便多次利用,又不至于搞的太復雜。
好吧,要學的東西真的很多很多,但是只要把看到的不明白弄明白,然后準備好下一個不明白到來,這樣就行了。
?
轉載于:https://www.cnblogs.com/hustskyking/archive/2013/05/05/getKeywords-2.html
總結
以上是生活随笔為你收集整理的Javascript综合应用小案例(续)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 各种促销背后的精明算术
- 下一篇: 模拟/usaco 1.1.4 Broke