【jquery模仿net控件】简单的dropdownlist与datalist
各位大哥晚上好,好久不見。小弟實習(xí)了三個月了,由.net轉(zhuǎn)成了java,工作期間正在努力學(xué)習(xí)。
但是有一點非常痛苦,我不止一次聽到一個聲音,”.net真的很簡單,我原來也學(xué)過。直接拖就是了......“
啊!!!感覺好沒有技術(shù)含量啊!莫法,小弟技術(shù)不行,無力辯駁什么。
并且就技術(shù)層次本身來說,不論我確實還有很多路要走,就不多說了。
起因
?
我們最近在做一個項目,其中核心模塊需要用到類似于igoogle中那種小工具的功能,當時經(jīng)過眾人商議,
最后決定用jquery寫控件。
控件!!!好機會啊!我發(fā)現(xiàn)項目需要的功能和.net中的datalist真的非常像,于是很想插進去.......
但是,我那淺薄的水平,以及我那悲劇的實習(xí)生頭銜,在其他同事面前確實不大說得上話。
最后眼睜睜看著別人寫了1more js代碼,然后讓我去讀。
呵呵,不是那個前輩代碼寫的不好,相反我在他的代碼中學(xué)了很多東西,當然是帶著極其抵觸的情緒在努力的看!
總覺得這也不好,那也不好,甚至有時候在摳人家命名規(guī)范的問題,總是想推翻一點加上自己的思路......
說到這里,我深刻的感覺團隊合作,團隊交流,團隊協(xié)作真的很重要!
?你有一個想法,你要如何表達自己的思路,如何寫出代碼,如何讓別人接受你的想法,接受你的代碼,
甚至讓別人幫助你充實你的想法,真的是一門大學(xué)問!
你若是做了一個東西,確實不錯,但是你不表現(xiàn)的謙虛,其他同事必定不會買賬,根本不會認同你的想法。
而且,一個你覺得很好的點子,在人家的分析后,肯定會發(fā)現(xiàn)很多問題,那就要看你如何獲得人家的認同與幫助了!
?
項目過程
?
就那前輩的代碼,我其實發(fā)現(xiàn)了一些問題,項目過程中他的代碼也確實遇到了一點問題,主要原因就是代碼除他之外,沒人想去動。
然后站在設(shè)計模式的高度來看,他的代碼可維護性,可擴展性有點問題,當然我設(shè)計模式看了一次也忘得車不多了。
最后在學(xué)習(xí)前輩的代碼,再加上.net控件思路的高度,我自己花了點時間寫了兩個控件模擬.net中的dropdownlist與datalist。
再次交出代碼,拋磚引玉,請各位大哥弄點更好的東西出來吧!!!
因為我也是才學(xué)js,代碼寫的不好,請各位大哥提點下吧!
Dropdownlist
?
一、效果圖()
因為這個控件是練手的,我需要的是datalist,所以就算起一個探索作用,沒有寫太多。
其功能就算想模擬.net中的控件,根據(jù)不同數(shù)據(jù)源,生成不同的代碼。
最主要是想把事件控制權(quán)交出來,讓使用這個控件的人不用去關(guān)注控件本身,(這也是前輩的主要問題)
二、簡單代碼
?核心代碼:
?
var item = function (value, text) {this.attribute = {id: '',value: value ? value : '',text: text ? text : '',title: '',selected: ''};this.htmlElement = null;this.callBack = {onClick: null}; }item.prototype.bindEvent = function () {var sender = this;// alert(sender.dataSource);var element = sender.htmlElement;if (sender.callBack.onClick) {element.unbind("click");element.bind("click", function () {sender.callBack.onClick.call(sender);});} }var dropDownList = function (id) {this.attribute = {id: id};this.style = {width: '',height: ''};this.callBack = {onSelectedChanged: null,onClick:null};this.htmlElement = null;this.items = [];this.selectedValue = '';this.selectedItem = {};this.dataSourceType = '';this.dataSource = {}; //應(yīng)該支持不同數(shù)據(jù)源this.dataTextField = '';this.dataValueField = '';this.dataTitleField = ''; }dropDownList.prototype.bindEvent = function () {var sender = this;// alert(sender.dataSource);var element = sender.htmlElement;if (sender.callBack.onSelectedChanged) {element.unbind("change");element.bind("change", function () {sender.callBack.onSelectedChanged.call(sender);});}if (sender.callBack.onClick) {element.unbind("click");element.bind("click", function () {sender.callBack.onClick.call(sender);});} } dropDownList.prototype.dataBind = function (element) {var sender = this;sender.htmlElement = $('<select id="' + sender["attribute"]["id"] + '"></select>');$.each(sender.dataSource, function (itemKey, itemValue) {// alert(itemKey + ":" + itemValue);var _item = new item();_item["attribute"]['value'] = itemValue[sender['dataValueField']];_item["attribute"]['text'] = itemValue[sender['dataTextField']];_item["attribute"]['title'] = itemValue[sender['dataTitleField']];sender.items.push(_item);sender.insertItem(_item);});//呈現(xiàn)前,樣式加載sender.styleLoad();element.append(sender.htmlElement); }dropDownList.prototype.styleLoad = function () {var sender = this;var element = sender.htmlElement;$.each(sender["style"], function (styleKey, styleValue) {// alert(styleKey + ":" + styleValue);if (styleValue) {element.css(styleKey, styleValue);}}); }dropDownList.prototype.insertItem = function (optionItem) {var sender = this;var element = sender.htmlElement;var itemSender = optionItem;// alert(element["id"]);var option = $('<option></option>');var optrinAtrribute = optionItem["attribute"];var id = optrinAtrribute["id"];var value = optrinAtrribute["value"];var text = optrinAtrribute["text"];var title = optrinAtrribute["title"];var selected = optrinAtrribute["selected"];if (id && id.length > 0) {option.attr("id", id);}if (value && value.length > 0) {option.attr("value", value);}if (title && title.length > 0) {option.attr("title", title);}if (selected && selected.length > 0) {option.attr("selected", selected);}if (text && text.length > 0) {option.text(text);}itemSender.htmlElement = option;element.append(option); }
前端調(diào)用:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title></title><script src="scripts/jquery-1.4.1.js" type="text/javascript"></script><script src="js/dropDownList.js" type="text/javascript"></script><script type="text/javascript">$(document).ready(function () {var data = [];for (var i = 0; i < 3; i++) {data[i] = {};data[i]["v"] = "value_" + i.toString();data[i]["t"] = "text_" + i.toString();}var $div = $("#divwl");var drop1 = new dropDownList("drop1");drop1.dataSource = data;drop1.dataValueField = "v";drop1.dataTextField = "t";drop1.dataTitleField = "v";drop1.dataBind($div);for (var i = 0; i < 3; i++) {var v = "inertValue_" + i;var t = "insertText_" + i;var _item = new item(v, t);drop1.insertItem(_item);}drop1.style.width = '300px';drop1.style.height = '50px';drop1.style.background = 'green';drop1.styleLoad();var funClick = function () {var dropSender = this.htmlElement;var selectedValue = dropSender.val()var $div = $("#text");$div.html(selectedValue);};var funChange = function () {var dropSender = this.htmlElement;var selectedValue = dropSender.val()alert(selectedValue);};drop1.items[1].callBack.onClick = funClick;drop1.items[1].bindEvent();drop1.callBack.onSelectedChanged = funChange;drop1.bindEvent();});</script> </head> <body><div id="divwl"></div><div id="text"> </div></body> </html>
?
Datalist
?
?好了,開始進入本文重點,這也是項目真正需要的,這個版本沒有完全完成,在得到大家意見后再改吧!
?一、效果圖:
?所用數(shù)據(jù)源:
二、思路
?原來也讀過.net 控件開發(fā)一書,對控件開發(fā)知識有個大概了解,所以做起來時候還是比較順手。
① datalist首先提供了一個公共的模板,就是itemtemplate中可以寫任何代碼包括數(shù)據(jù)綁定代碼,
然后依次循環(huán)調(diào)用,所以我覺得這個控件需要一個模板保存類似于.net中的html代碼,以及數(shù)據(jù)綁定代碼。
當然,我們不可能寫在js代碼中,于是出現(xiàn)了一下模板文件:
itemTemplate.spt:
<table><tr><td>新聞ID</td><td>{%newsId%}</td></tr><tr ><td >新聞標題</td><td>{%newsName%}</td></tr><tr ><td>新聞?wù)?lt;/td><td><input id="contentMore" value="詳情" type="button"/></td></tr><tr ><td colspan="2" style=" display:none;" class="content">{%newsContent%}</td></tr> </table> <hr/>{%newsName%} 是模擬Eval("")的寫法,后期作為數(shù)據(jù)綁定使用
② 然后每次循環(huán)生成具體的模板js代碼如下:itemTemplate.js
/// <reference path="../scripts/jquery-1.4.1.js" />var itemTemplate = function () {//源模板文本,現(xiàn)在為itemTemplate.spt//可能是文本,可能是js文件,可能是字符串//最終形成字符串傳給htmlTemplateTextthis.htmlTemplateText = "";//最終會形成一獨立html字符串,dom結(jié)構(gòu)的標簽this.htmlElement = null;this.idPrefix = "id_"; //id前綴this.parentId = "";this.id = "";this.event = {onClick: null,onMousemove: null};//將要執(zhí)行// this.evetElementSource = {};this.elementEvent = null; }; itemTemplate.prototype.getItemElement = function (elementKey) {var sender = this;var id = "#" + sender.id + " " + elementKey;var element = $(id);return element; } //elementKey #id、 .className、 htmlElement itemTemplate.prototype.bindElementEvent = function (elementKey, eventType, funcName) {var sender = this;var id = "#" + sender.id + " " + elementKey;var element = $(id);if (funcName) {element.unbind(eventType);element.bind(eventType, function () {funcName.call(sender);});} }//elementKey #id、 .className、 htmlElement itemTemplate.prototype.bindAllElementEvent = function () {var sender = this;var itemElementEvents = sender.elementEvent;// alert(element+"=="+id);//數(shù)據(jù)項元素事件綁定$.each(itemElementEvents, function (eventObjKey, eventObj) {var elementKey = eventObj.elementKey;var eventType = eventObj.eventType;var funcName = eventObj.funcName;sender.bindElementEvent(elementKey, eventType, funcName);}); }itemTemplate.prototype.bindEvent = function () {var sender = this;var element = sender.htmlElement;var events = sender.event;$.each(events, function (eventKey, funcName) {// alert(funcKey + "---" + funcValue);if (funcName) {var _event = eventKey;_event = _event.substring(2, _event.length);_event = _event.toLowerCase();element.unbind(_event);element.bind(_event, function () {funcName.call(sender);});}}); };itemTemplate.prototype.load = function (itemIndex, itemDataSource) {var sender = this;var id = sender.parentId + "_" + sender.idPrefix + itemIndex;sender.id = id;var element = $("<div id='" + id + "'></div>");var html = "";var _templateText = sender.htmlTemplateText;tempHtm = _templateText;$.each(itemDataSource, function (i, item) {var id = item;var regStr = "/\\{%" + i + "%\\}/g";var reg = eval(regStr);tempHtm = tempHtm.replace(reg, item);});html = tempHtm;element.append($(html))sender.htmlElement = element;sender.bindEvent();};
技術(shù)細節(jié)便不說了,其主要采用正則表達式方式替換相應(yīng)內(nèi)容,所以完全根據(jù)我們提供的數(shù)據(jù)源而定:
③ 外層datalist代碼:dataList.js
/// <reference path="../scripts/jquery-1.4.1.js" />/* 思考: 1 如何給數(shù)據(jù)項某個html標簽添加事件 因為我們并不知道生成的dom樹是什么,所以模板里面的html標簽無法綁定事件,暫時只能后期綁定*/ /* 控件生成流程*/var dataList = function (id, templateUrl) {this.attribute = {id: id};this.style = {width: "",height: ""};this.itemEvent = {onClick: null,onDblclick: null,onKeydown: null,onKeypress: null,onKeyup: null,onMousedown: null,onMousemove: null,onMouseout: null,onMouseover: null,onMouseup: null};this.itemElementEvent = {};// this.itemElementEvent = {// one: {// elementKey: "",// eventType: "",// funcName: null// }// };this.htmlElement = null;this.templateUrl = templateUrl ? templateUrl : ""; //提供項目模板地址this.htmlTemplateText = "";this.items = [];this.dataSource = {}; //應(yīng)該支持不同數(shù)據(jù)源 };dataList.prototype.init = function () {var sender = this;var templateUrl = sender.templateUrl;if (!templateUrl || templateUrl.length == 0)templateUrl = "itemTemplate/itemTemplate.spt";this.htmlTemplateText = getAjaxStr(templateUrl);var htmlElement = $("<div id='" + sender.attribute.id + "'></div>");sender.htmlElement = htmlElement; };dataList.prototype.dataBind = function (element) {this.init();var sender = this;var templateText = sender.htmlTemplateText;var itemEvent = sender.itemEvent;var itemElementEvents = sender.itemElementEvent;//需要替換itemTemplatevar itemIndex = 0;$.each(sender.dataSource, function (dataKey, dataValue) {var _item = new itemTemplate();_item.parentId = sender.attribute.id;_item.htmlTemplateText = templateText;_item.event = itemEvent;_item.elementEvent = itemElementEvents;//傳遞父ID ,當前模板編號,源模板,當前項數(shù)據(jù)項源,事件綁定源_item.load(itemIndex, dataValue);var _itemElement = _item.htmlElement;sender.items.push(_item);sender.insertDomItem(_itemElement);itemIndex++;});//呈現(xiàn)前,樣式加載sender.styleLoad();element.append(sender.htmlElement);//模板中的html標簽的事件綁定var items = sender.items;$.each(items, function (i, item) {item.bindAllElementEvent();}); };dataList.prototype.styleLoad = function () {var sender = this;var element = sender.htmlElement;$.each(sender.style, function (styleKey, styleValue) {// alert(styleKey + ":" + styleValue);if (styleValue) {// alert(element);element.css(styleKey, styleValue);}}); }dataList.prototype.insertDomItem = function (domItem) {var sender = this;var element = sender.htmlElement;element.append(domItem); }; //dataList.prototype.bindItemEvent = function (domItem) { // var sender = this; // var element = sender.htmlElement; // element.append(domItem); //}; //dataList.prototype.bindEvent = function () { // var sender = this; // var element = sender.htmlElement; // var events = sender["event"]; // $.each(events, function (eventKey, funcName) { // // alert(funcKey + "---" + funcValue); // if (funcName) { // var _event = eventKey; // _event = _event.substring(2, _event.length); // _event = _event.toLowerCase(); // element.unbind(_event); // element.bind(_event, function () { // funcName.call(sender); // }); // } // }); //};//異步獲取文件 function getAjaxStr(url) {var templateStr = "";$.ajax({url: url,async: false,dataType: "html",success: function (result) {templateStr = result;if (templateStr)return templateStr;},error: function (e) {alert("模板加載錯誤:" + e.toString());}});return templateStr; }
③ 前臺調(diào)用界面代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title></title><script src="scripts/jquery-1.4.1.js" type="text/javascript"></script><script src="js/itemTemplate.js" type="text/javascript"></script><script src="js/dataList.js" type="text/javascript"></script><script type="text/javascript">$(document).ready(function () {var dataSource = {};$.ajax({type: "post",url: "Ajax.aspx",type: "json",async: false,success: function (data) {dataSource = data;}});var $divHtml = $("#html");var $div = $("#wl");var $div1 = $("#wl1");var itemElementEvents = {contentClick: {elementKey: "#contentMore",eventType: "click",funcName: contentMoreClick}};var list = new dataList("divwl");list.itemEvent.onMousemove = itemmousemove;list.itemEvent.onMouseout = itemmouseout;list.itemElementEvent = itemElementEvents;list.style.width = "700px";list.dataSource = dataSource;list.dataBind($div);function contentMoreClick() {var sender = this;var newsContent = sender.getItemElement(".content");var contentMore = sender.getItemElement("#contentMore");if (newsContent.css("display") == "none") {contentMore.attr("value", "隱藏");newsContent.css("display", "");} else {contentMore.attr("value", "詳情");newsContent.css("display", "none");}}function itemmousemove() {var sender = this;var $ee = sender.htmlElement;$ee.css("background", "Gray");}function itemmouseout() {var sender = this;var $ee = sender.htmlElement;$ee.css("background", "white");}});</script> </head> <body><div id="html" style="display: block"></div><div id="wl"></div><div id="wl1"></div> </body> </html>大概代碼如上,看一下調(diào)用界面基本知道如何使用的。
在此我有個沒有解決的問題,請各位大哥幫下忙:
除模板之中的html dom 結(jié)構(gòu)沒有前期事件綁定外,其他生成的dom都是在展現(xiàn)前便綁定事件:
?
//呈現(xiàn)前,樣式加載sender.styleLoad();element.append(sender.htmlElement);//模板中的html標簽的事件綁定var items = sender.items;$.each(items, function (i, item) {item.bindAllElementEvent();});其實這個代碼最先是寫在itemTemplate.js文件中的,在沒有將dom append到頁面中,但是因為dom結(jié)構(gòu)沒有生成,我無法通過除以上的方法找到
對應(yīng)html標簽,所有無法做事件綁定,這里把我弄模糊了。各位大哥有興趣看了代碼便和我說說吧,代碼會跟進。
?
今天又更新了一點代碼,有點變化,現(xiàn)在先弄上datalist嵌套的用法,具體的代碼后面點看有沒有需要弄出來
效果:其實就是新聞類型嵌套一個新聞列表
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title></title><script src="scripts/jquery-1.4.1.js" type="text/javascript"></script><script src="js/itemTemplate.js" type="text/javascript"></script><script src="js/dataList.js" type="text/javascript"></script><script type="text/javascript">$(document).ready(function () {var dataItems = {};$.ajax({type: "post",url: "Ajax.aspx?sql=select top 5 * from Item where ItemKind=1 ",type: "json",async: false,success: function (data) {dataItems = data;}});var $div = $("#wl");var listItem = new dataList("newsItem", "itemTemplate/items.spt");var itemElementEvents = {loadItemNews: {elementKey: "#itemNews",eventType: "ready",funcName: elementDatabind}};listItem.itemElementEvent = itemElementEvents;listItem.dataSource = dataItems;listItem.dataBind($div);function elementDatabind() {var sender = this;var $itemId = sender.getItemElement("#itemId");var $itemNews = sender.getItemElement("#itemNews");var listItemNews = new dataList("news", "itemTemplate/itemTemplate.spt");var _itemElementEvents = {contentClick: {elementKey: "#contentMore",eventType: "click",funcName: contentMoreClick}};var id = $itemId.html();var s = $itemNews.html();var dataNews = {};$.ajax({type: "post",url: "Ajax.aspx?sql=select top 3 newsId,newsName, newsContent from news where itemId='" + id + "' ",type: "json",async: false,success: function (data) {dataNews = data;}});listItemNews.itemEvent.onMousemove = itemmousemove;listItemNews.itemEvent.onMouseout = itemmouseout;listItemNews.itemElementEvent = _itemElementEvents;listItemNews.dataSource = dataNews;listItemNews.dataBind($itemNews);}function contentMoreClick() {var sender = this;var newsContent = sender.getItemElement(".content");var contentMore = sender.getItemElement("#contentMore");if (newsContent.css("display") == "none") {contentMore.attr("value", "隱藏");newsContent.css("display", "");} else {contentMore.attr("value", "詳情");newsContent.css("display", "none");}}function itemmousemove() {var sender = this;var $ee = sender.htmlElement;$ee.css("background", "Gray");}function itemmouseout() {var sender = this;var $ee = sender.htmlElement;$ee.css("background", "white");}});</script> </head> <body><div id="wl"></div> </body> </html>
等以后代碼完善了,我在整理發(fā)出吧。
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/yexiaochai/archive/2012/01/22/2328729.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的【jquery模仿net控件】简单的dropdownlist与datalist的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python2.7开发环境搭建_wind
- 下一篇: 输入文字加下划线_Word中被很多职场人