【DOM编程艺术】综合示例 global.js

function addLoadEvent(func){
    var oldonload = window.onload;
    if(typeof window.onload != 'function'){
        window.onload = func;
    }else{
        window.onload = function(){
            oldonload();
            func();
        }
    }    
}

function insertAfter(newElement,targetElement){
    var parent = targetElement.parentNode;
    if( parent.lastChild == targetElement){
        parent.appendChild(newElement);
    }else{
        parent.insertBefore(newElement,targetElement.nextSibling);
    }
}

function addClass(element,value){
    if(!element.className){
        element.className = value;
    }else{
        newClassName = element.className;
        newClassName += ' ';
        newClassName += value;
        element.className = newClassName;
    }
}

/*高亮*/
function highlightPage(){ if( !document.getElementById) return false; if( !document.getElementsByTagName ) return false; var headers = document.getElementsByTagName('header'); if( headers.length == 0) return false; var navs = headers[0].getElementsByTagName('nav'); if( navs.length == 0 ) return false; var links = navs[0].getElementsByTagName('a'); var url = window.location.href; for(var i=0;i<links.length;i++){ var linkurl = links[i].getAttribute('href'); if( url.indexOf(linkurl) != -1 ){ links[i].setAttribute('href','#'); links[i].className = 'here' ; } } }
/*幻灯片*/
function prepareSlideshow(){ if(!document.getElementById('intro')) return false; var slideshow = document.createElement('div'); slideshow.setAttribute('id','slideshow'); var frame = document.createElement('img'); frame.setAttribute('id','frame'); frame.setAttribute('src','images/frame.gif'); slideshow.appendChild(frame); var preview = document.createElement('img'); preview.setAttribute('id','preview'); preview.setAttribute('src','images/slideshow.gif'); slideshow.appendChild(preview); var intro = document.getElementById('intro'); insertAfter(slideshow,intro); var links = document.getElementsByTagName('a'); for(var i=0;i<links.length;i++){ links[i].onmouseover=function(){ var destiation = this.getAttribute('href'); if( destiation.indexOf('index.html') != -1){ moveElement('preview',0,0,10); } if( destiation.indexOf('about.html') != -1){ moveElement('preview',-150,0,10); } if( destiation.indexOf('photos.html') != -1){ moveElement('preview',-300,0,10); } if( destiation.indexOf('live.html') != -1){ moveElement('preview',-450,0,10); } if( destiation.indexOf('contact.html') != -1){ moveElement('preview',-600,0,10); } } } } function moveElement(elementID,final_x,final_y,interval){ var elem = document.getElementById(elementID); if( !elem.style.left) {elem.style.left = 0;} if( !elem.style.top) {elem.style.top = 0;} var xpos = parseInt(elem.style.left); var ypos = parseInt(elem.style.top); var dist; if(elem.movement) { clearTimeout(elem.movement)}; if( xpos == final_x && ypos == final_y ){ return true; } if( xpos < final_x){ dist = Math.ceil((final_x - xpos)/10); xpos = xpos + dist; } if( xpos > final_x){ dist = Math.ceil((xpos - final_x)/10); xpos = xpos - dist; } if( ypos < final_y){ dist = Math.ceil((final_y - ypos)/10); ypos = ypos + dist; } if( ypos > final_y){ dist = Math.ceil((final_y - ypos)/10); ypos = ypos - dist; } elem.style.left = xpos +'px'; elem.style.top = ypos +'px'; var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")"; elem.movement = setTimeout(repeat,interval); } //About
/*标签切换*/ function prepareShowSection(){ if( !document.getElementById) return false; if( !document.getElementsByTagName) return false; var article = document.getElementsByTagName('article'); if( article.length == 0 ) return false; var nav = article[0].getElementsByTagName('nav'); if( nav.length == 0 ) return false; var links = nav[0].getElementsByTagName('a'); for(var i=0;i<links.length;i++){ document.getElementsByTagName('section')[i].style.display = 'none'; var sectionId = links[i].getAttribute('href').split('#')[1]; links[i].destination = sectionId; if( !document.getElementById(sectionId)) continue; links[i].onclick = function(){ showSection(this.destination); return false; } } } function showSection(id){ var sections = document.getElementsByTagName('section'); for(var i=0;i<sections.length;i++){ if(sections[i].getAttribute('id') != id){ sections[i].style.display = 'none'; }else{ sections[i].style.display = 'block'; } } } //photos
/*图片库*/
function preparePlaceholder(){ if( !document.getElementById) return false; if( !document.getElementsByTagName ) return false; if( !document.getElementById('imagegallery')) return false; var placeholder = document.createElement('img'); placeholder.setAttribute('id','placeholder'); placeholder.setAttribute('src','images/placeholder.gif'); var description = document.createElement('p'); description.setAttribute('id','description'); var text = document.createTextNode('choose an image'); description.appendChild(text); var imagegallery= document.getElementById('imagegallery'); insertAfter(description,imagegallery); insertAfter(placeholder,description); } function prepareGallery(){ if( !document.getElementById('imagegallery')) return false; var imagegallery = document.getElementById('imagegallery'); var links = imagegallery.getElementsByTagName('a'); for(var i=0;i<links.length;i++){ links[i].onclick = function(){ return showpic(this); } } } function showpic(whichpic){ if( !document.getElementById('placeholder')) return true; var imageurl = whichpic.getAttribute('href'); var placeholder = document.getElementById('placeholder'); placeholder.setAttribute('src',imageurl); if( !document.getElementById('description')) return false; if( !whichpic.getAttribute('title')){ var title = ''; }else{ var title = whichpic.getAttribute('title'); } var description = document.getElementById('description'); if( description.firstChild.nodeType == 3){ description.firstChild.nodeValue = title; } return false; } //live
/*隔行换色*/
function stripeTables(){ var tables = document.getElementsByTagName('table'); for(var i=0;i<tables.length;i++){ var rows = tables[i].getElementsByTagName('tr'); var odd = false; for(var j=0;j<rows.length;j++){ if( odd == false ){ odd = true; }else{ addClass(rows[j],'odd'); odd = false; } } } } function highlightRows(){ var tables = document.getElementsByTagName('table'); for(var i=0;i<tables.length;i++){ var rows = tables[i].getElementsByTagName('tr'); for(var j=0;j<rows.length;j++){ var oldClassname = rows[j].className; rows[j].onmouseover = function(){ addClass(this,'highlight'); } rows[j].onmouseout = function(){ this.className = oldClassname; } } } } /*显示abbr*/ function displayAbbreviations(){ if( !document.getElementsByTagName('abbr')) return false; var defs = new Array(); var abbrs = document.getElementsByTagName('abbr'); if( abbrs.length ==0) return false; for(var i=0;i<abbrs.length;i++){ if( abbrs[i].childNodes.length <1) continue; var key = abbrs[i].firstChild.nodeValue; var definition = abbrs[i].getAttribute('title'); defs[key] = definition; } var dlist = document.createElement('dl'); for(var key in defs){ var dtitle = document.createElement('dt'); var dtitle_text = document.createTextNode(key); dtitle.appendChild(dtitle_text); var ddtitle = document.createElement('dd'); var definition = defs[key]; var ddtitle_text = document.createTextNode(definition); ddtitle.appendChild(ddtitle_text); dlist.appendChild(dtitle); dlist.appendChild(ddtitle); } var header = document.createElement('h3'); var header_text = document.createElement('Abbreviations'); header.appendChild(header_text); var articles = document.getElementsByTagName('article'); if( articles.length == 0) return false; articles[0].appendChild(header); articles[0].appendChild(dlist); } /*contact*/
/*单击label对应的输入框聚焦*/
function focusLabels(){ var labels = document.getElementsByTagName('label'); for( var i=0;i<labels.length;i++){ if( !labels[i].getAttribute('for') ) continue; labels[i].onclick = function(){ var id = this.getAttribute('for'); if( !document.getElementById(id)) return false; var elem = document.getElementById(id); elem.focus(); } } }
/*表单*/
function prepareForms(){ for(var i=0;i< document.forms.length;i++){ var thisform = document.forms[i]; resetFields(thisform); //聚焦和失去焦点的操作 thisform.onsubmit = function(){ if(!validateForm(this)) return false; //在验证表单不通过的情况下,禁止提交表单 var article = document.getElementsByTagName('article')[0]; if(submitFormWithAjax(this,article)) return false; return true; } } } function resetFields(whichform){ if( Modernizr.input.placeholder ) return; for(var i=0;i< whichform.elements.length; i++){ var element = whichform.elements[i]; if(element.type == 'submit') continue; var check = element.placeholder || element.getAttribute('placeholder'); if( !check) continue; var placeholder = element.getAttribute('placeholder'); //element.className = 'placeholder'; //element.value = placeholder; element.onfocus= function(){ var text = this.placeholder || this.getAttribute('placeholder'); if( this.value == text){ this.value = ''; } } element.onblur = function(){ if( this.value == ''){ this.className = 'placeholder'; this.value = this.placeholder || this.getAttribute('placeholder'); } } element.onblur(); } } /*表单*/ function validateForm(whichform){ for(var i=0;i<whichform.elements.length;i++){ var elem = whichform.elements[i]; var elem_required = elem.required || elem.getAttribute('required'); if( elem_required == '' || elem_required == 'required'){ var elem_name = elem.name || elem.getAttribute('name'); if( !isFilled(elem) ){ alert('please fill in '+elem_name +' '+'field.'); //elem.name火狐会出现undefined return false; } if( elem.getAttribute('id') == 'email'){ //或者elem.type == 'email' if( !isEmail(elem)){ alert('请输入正确的邮箱地址'); return false; } } } } return true; } function isFilled(field){ if(field.value.replace(' ','').length == 0) return false; var placeholder = field.placeholder || field.getAttribute('placeholder'); return (field.value != placeholder); } function isEmail(field){ return (field.value.indexOf('@') != -1 && field.value.indexOf('.') != -1); } /*ajax*/ function submitFormWithAjax(whichform,thetarget){ var request = getHTTPObject(); if(!request) return false; displayAjaxLoading(thetarget); //加载loading.gif,并删除article下的所有元素 var dataParts = []; for(i=0;i<whichform.elements.length;i++){ var elem = whichform.elements[i]; dataParts[i] = elem.getAttribute('name') + '=' + encodeURIComponent(elem.value); //encodeURIComponent 函数把值编码成URL安全的字符串。 } var data = dataParts.join('&'); // var data = name=%220……&email=%30……&message=%202%2b2%3d4; request.open('POST',whichform.getAttribute('action'),true); request.setRequestHeader('Content-type','application/x-www-form-urlencoded'); request.onreadystatechange = function(){ if(request.readyState == '4'){ if( request.status ==200 || request.status ==0 ){ var matches = request.responseText.match(/<article>([\s\S]+)<\/article>/); if( matches.length > 0){ thetarget.innerHTML = matches[1];//innerHTML内 }else{ thetarget.innerHTML = '<p>Oops,there was an error.Sorry.</p>'; } }else{ thetarget.innerHTML = '<p>' + request.statusText + '</p>'; } } } request.send(data); return true; } function getHTTPObject(){ if(typeof XMLHttpRequest == 'undefined'){ try{ return new ActiveXObject('Msxml2.XMLHTTP.6.0');} catch(e){} try{ return new ActiveXObject('Msxml2.XMLHTTP.3.0');} catch(e){} try{ return new ActiveXObject('Msxml2.XMLHTTP');} catch(e){} return false; }else{ return new XMLHttpRequest(); } } function displayAjaxLoading(element){ while(element.hasChildNodes()){ element.removeChild(element.lastChild); } var content = document.createElement('img'); content.setAttribute('src','images/loading.gif'); content.setAttribute('alt','Loading^'); element.appendChild(content); console.log(element); } addLoadEvent(highlightPage); addLoadEvent(prepareSlideshow); addLoadEvent(prepareShowSection); addLoadEvent(preparePlaceholder); addLoadEvent(prepareGallery); addLoadEvent(stripeTables); addLoadEvent(highlightRows); addLoadEvent(displayAbbreviations); addLoadEvent(focusLabels); addLoadEvent(prepareForms);

 讲解:displayAjaxLoading(element) 函数作用:把article的所有子元素都删除掉。删除之后,再把loading.gif图像添加到该元素中。

function prepareForms(){
    for(var i=0;i< document.forms.length;i++){
        var thisform = document.forms[i];
        resetFields(thisform);
        thisform.onsubmit = function(){
            if(!validateForm(this)) return false;
            var article = document.getElementsByTagName('article')[0];
            if(submitFormWithAjax(this,article)) return false;
            return true;
        }
    }
}

讲解:如果正确的提交了表单,表单就会打开submit显示感谢信息。如果表单能够发送一个ajax请求,而感谢信息能以前乳房是添加到表单所在的页面,那种体验想必会更好。

   说白了,就是表单提交成功之后,不打开新页面了,而是拦截提交请求,自己显示结果。

    然后,创建一个加载图像,在Ajax请求刚启动时把它添加到文档中。-------displayAjaxLoading(element)

   submitFormWithAjax(this,article)-----this是指form表单,第二个参数是指目标对象article

       功能:(1) 首先先检查是否存在有效的XMLHttpRequest对象。

          (2) 调用displayAjaxLoading函数,删除目标元素的子元素,并添加loading.gif图像。

          (3) 把表单的值组织成URL编码的字符串,以便通过ajax请求发送。

          (4) 创建方法为POST的Ajax请求,把表单的值发送给submit.html

          (5) 如果请求成功,解析响应并在目标元素中显示结果。

          (6) 如果请求失败,显示错误信息。

dataParts[i] = elem.getAttribute('name') + '=' + encodeURIComponent(elem.value);

  例如:表单中包含信息"why does 2+2=4?",字符串类似如下显示:message= Why does 2+2=4?&name=me&email=me@example.com

           这里的加号(+)、等于号(=)和问号(?)都会带来问题:

    ■ 等于号的意思是不是说表单里有一个字段名叫2,,而它的值是4呢?

    ■ 加号是一个编码后的空格,还是一个普通的加号?

    ■ 问号表示它后面是参数列表吗?

    为了避免歧义,可以使用Javascript的encodeURIComponent函数把这些编码成URL安全的字符串。这个函数会把有歧义的字符转换成对应的ASCII编码:

    message=why%20does%202%2b2%304%3f%26&name=me&email=me%40example.com

 

    var dataParts = [];
    for(i=0;i<whichform.elements.length;i++){
        var elem = whichform.elements[i];
        dataParts[i] = elem.getAttribute('name') + '=' + encodeURIComponent(elem.value);   //encodeURIComponent 函数把值编码成URL安全的字符串。
    }
    var data = dataParts.join('&'); 

解析: 循环遍历表单中的每个字段,但这次不是验证,而是收集他们的名字和编码后的值,把结果保存在一个数组中。

   var data = dataParts.join('&'); 收集到所有的数据后,把数组中的项用和号(&)联结起来

request.open('POST',whichform.getAttribute('action'),true);

   然后,向原始表单的action属性指定的处理函数发送POST请求

request.setRequestHeader('Content-type','application/x-www-form-urlencoded');

   并在请求中添加application/x-www-form-urlencoded头部

  这个头部信息对于POST请求是必须的,它表示请求中包含URL编码的表单。

 

        服务器返回的响应就是submit页面。这个页面与站点中其他页面一样,也包含头部区域、导航和内容。因为我们是想把结果加载到到已有的页面中,所以就不需要头部区域和导航了。只要从页面中取得<article>元素就足够了。而完整的页面放在

  那里,就是预备着在Ajax无效的情况下,就直接返回submit.html页面。

       如果你在使用自己常用的服务器端脚本语言编写响应,那么可以只为Ajax请求输出必要的标记。但目前来讲,只能假设没有服务器端脚本,因此只能使用Ajax来增加一点用户体验。

       为了从响应中提取出<article>元素,你得考虑使用一种叫做正则表达式的技术。

var matches = request.responseText.match(/<article>([\s\S]+)<\/article>/);

   在article和</article>之间,是一个捕获组,用于捕获位于开始和结束标签之间的文本。捕获组中的方括号包含了要匹配的字符。

   简单地说,正则表达式模式/<article>([\s\S]+)<\/article>/ 可以理解如下:

   ■ 查找一个字符串,这个字符串以<article>开头,后跟一或多个空格或非空格字符,最后还有一个</article>

   ■ 把这个字符串中的空格及非空格字符包含在一个捕获组中,以便后面提取。

       数组matches的第一个元素(索引为0)是responseText中与整个模式匹配的部分,即包括<article>和</article>在内的部分。因为模式中包含了一个捕获组(一对圆括号),因此mathces的第二个元素(索引为1)是responseText中

  与捕获组中的模式匹配的部分。在这个例子中,只有一个捕获组,因此matches也只包含两个元素。

 

        thisform.onsubmit = function(){
            if(!validateForm(this)) return false;
            var article = document.getElementsByTagName('article')[0];
            if(submitFormWithAjax(this,article)) return false;
            return true;
        }

   解析:■ 如果表单没有通过验证,返回false;因为验证失败,所以不能提交表单。

      ■ 如果submitFormWithAjax函数成功发送了Ajax请求并返回true,则让submit事件处理函数返回false,以便组织浏览器重复提交表单。

      ■ 否则,说明submitFormWithAjax没有成功发送Ajax请求,因而让submit事件处理函数返回true,让表单像什么都没有发生一样继续通过页面提交。

posted @ 2014-05-03 14:10  Western Journey  阅读(343)  评论(0编辑  收藏  举报