电话切换功能原理及需求

这是去年的一个需求,没事儿整理了一下;因公司业务需求,需要判断用户首次进入的站点在页面显示相应的电话,由于站点不同所以显示的电话也是不一样的,具体需求如下:

用户首次进入公司网站,判断用户浏览器客户端是否存在电话切换所需的 cookie;如果存在,则直接将页面中的电话显示为该 cookie 所对应的电话;如果不存在,则判断当前站点域名,根据域名对应的客服风格显示对应的电话,同时在用户客户端设置电话切换所需 cookie,cookie有效期为7天;
每个域名可能对应对个客服风格,每个客服风格在 cookie 中有一个唯一值,通过判断这个唯一值来切换显示电话,同时电话切换的 cookie 和客服风格的 cookie 的有效期要保持同步,同时失效;
客服风格的唯一 cookie 值存在指定的主站点之下,该值是移动存在的;

功能点:

  • 封装 cookie 设置/获取/删除方法;
  • 判断 cookie/域名/客服风格,显示对应的电话;
  • 跨域同步 cookie,由于公司有多个站点,不同的网站主域不同,必须要保证用户首次进入网站后,在随后其他站点浏览时显示的是同一个电话,所以就需要跨域同步 cookie;

方案:

1、现有3个不同域名的站点:www.aaa.com(A站/主站)、www.bbb.com(B站)、www.ccc.com(C站);每个站点有对应的电话和 cookie 值;

2、用户进入网站,首先判断用户客户端 cookie 是否存在;

  • 若存在,判断 cookie 值对应修改页面中显示的电话;
  • 若不存在,请求服务器,通过服务器获取主站点下客服风格的唯一值以及客服风格 cookie 的失效日期;
  • 根据服务器获取的 cookie 判断页面中显示的电话,并在当前域名下设置 cookie 及失效日期;

小二儿,上代码~

服务端(php):

<?php 
/**
 * @跨域获取Cookie分析 http://varyu.com/notes/54.html
 * @网站头部按 指定类型 "$_COOKIE['xiaoma_tel_cookie']",换电话号码 400-0123-267
 * @2014.08.20 js 调用客户端的 cookie 信息
 */

header("content-type:text/html;charset=utf-8");

$cb=$_GET['callback'];  //getJSON('xxx.com?callback=?') 中的callback

if($_COOKIE['xiaoma_tel_cookie']==""){
   $_COOKIE['xiaoma_tel_cookie'] = "404";
}
if($_COOKIE['tel_cookie_overdue'] == ""){
   $_COOKIE['tel_cookie_overdue'] = "404";
}

$result = "{".xiaoma_tel_cookie.":".$_COOKIE['xiaoma_tel_cookie'].",".tel_cookie_overdue.":".$_COOKIE['tel_cookie_overdue']."}";

echo($cb."(".$result.")");
exit();

?>

切换脚本:重构之后的电话切换功能[续]

// 封装 cookie 设置/获取/删除 方法
var CookieUtil = {
    get: function(name) {
        var cookie = document.cookie;
        var cookieName = encodeURIComponent(name) + "=";
        var start = cookie.indexOf(cookieName);
        var value = null;
        if (start > -1)
        {
            var end = cookie.indexOf(";", start);
            if (end == -1)
                end = cookie.length;
            value = decodeURIComponent(cookie.substring(start + cookieName.length, end));
        }
        return value;
    },
    set: function(name, value, expires, path, domain, secure) {
        var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
        if (expires instanceof Date)
            cookieText += "; expires=" + expires.toGMTString();
        if (path)
            cookieText += "; path=" + path;
        if (domain)
            cookieText += "; domain=" + domain;
        if (secure)
            cookieText += "; secure";
        document.cookie = cookieText;
    },
    unset: function(name, path, domain, secure) {
        this.set(name, "", new Date(0), path, domain, secure);
    }
};


function getReferrer() {
    windowAlias = window;
    documentAlias = document;
    var referrer = '';
    try {
    referrer = windowAlias.top.document.referrer;
    } catch (e) {

        if(windowAlias.parent) {
            try {
                referrer = windowAlias.parent.document.referrer;
            } catch (e2) {
                referrer = '';
            }
        }

    }

    if(referrer === '') {
        referrer = documentAlias.referrer;
    }

    return referrer;
}


function getHostName(url) {
    // scheme : // [username [: password] @] hostame [: port] [/ [path] [? query] [# fragment]]
    var e = new RegExp('^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)'),
    matches = e.exec(url);

    return matches ? matches[1] : url;
}


function changeTelToSemWithTagName(ag_obj,sourceNum,targetNum) {
    if(ag_obj){
        ag_length = ag_obj.length;

        for(i = 0; i<ag_length; i++) {
            var ag_phone_html=ag_obj[i].innerHTML;
            if(ag_phone_html.indexOf(sourceNum) == 0) {
                ag_obj[i].innerHTML=ag_phone_html.replace(sourceNum,targetNum);
            }
        }

    }
}


function changeTelNoToFreeWithTagName(ag_obj,sourceNum,targetNum){
    if(ag_obj){
        ag_length = ag_obj.length;

        for (i = 0; i<ag_length; i++){
            var ag_phone_html=ag_obj[i].innerHTML;
            if (ag_phone_html.indexOf(sourceNum) == 0){
                ag_obj[i].innerHTML=ag_phone_html.replace(sourceNum,targetNum);
            }
        }

    }
}


function changeTelNo(){
    var ag_obj = document.getElementsByTagName("span");
    changeTelToSemWithTagName(ag_obj,agrantsemPPC.freeNo,agrantsemPPC.semNo);
    var ag_obj2 = document.getElementsByTagName("b");
    changeTelToSemWithTagName(ag_obj2,agrantsemPPC.freeNo,agrantsemPPC.semNo);
}


function changeTelNoToFree(){
    var ag_obj = document.getElementsByTagName("span");
    changeTelNoToFreeWithTagName(ag_obj,agrantsemPPC.semNo, agrantsemPPC.freeNo);
    var ag_obj2 = document.getElementsByTagName("b");
    changeTelNoToFreeWithTagName(ag_obj2,agrantsemPPC.semNo, agrantsemPPC.freeNo);
}


// 按
function getElementByClass (className, parent) {
    parent || (parent = document);
    var descendants= parent.getElementsByTagName('*'), i=-1, e, result=[];

    while (e=descendants[++i]) {
        ((' '+(e['class']||e.className)+' ').indexOf(' '+className+' ') > -1) && result.push(e);
    }

    return result;
}

// 电话/域名/客服风格
temlist = new Array("400-663-1986","400-6969-256", "400-0123-267", "400-663-1986", "4008-116-356", "4008-118-059", "4006-025-056", "4000-256-029", "4006-123-226", "400-0699-025", "400-6969-256", "4000-289-015", "400-6969-256", "400-6969-256", "4008-116-069")

reg_xsat = new RegExp("www\.xuesat\.com");
reg_xm = new RegExp(".*.\.xiaoma\.com");
reg_cg = new RegExp("www\.xiaomachuguo\.com");

cook_seo = new RegExp("103608619|103609219|103609522");
cook_bbs = new RegExp("103608719|103609019|103609520|103609521|103609622|103609623");
cook_kc = new RegExp("103608819|103609119|103609319|103609419|103609519|103609588|103609589");
cook_ys = new RegExp("103608919");
cook_zt = new RegExp("103609540");
cook_sh = new RegExp("103609549|103609533");
cook_xsat = new RegExp("103609543");
cook_yd = new RegExp("103609523");
cook_cg = new RegExp("103609552|103609553|103609554|103609581");
cook_wm = new RegExp("103609524");
cook_wk1 = new RegExp("103609525");
cook_wk = new RegExp("103609575");
cook_360 = new RegExp("103609527|103609537|103609538|103609582|103609586|103609587");
cook_sg = new RegExp("103609529|103609530|103609531|103609536");


function changeElementTelFromList(taglist, type) {
    for(var i = 0; i < taglist.length; i++){
        var eml = taglist[i]
        var eml_tag = eml.tagName;

        if (eml_tag == 'img' || eml_tag == 'IMG') {
            var img_src = eml.src
            var fileName = img_src.substring(img_src.lastIndexOf('\/')+1,img_src.lastIndexOf('.'));

            // 修改最后一个值
            var tmpname = fileName.substring(0,fileName.length-1)
            tmpname = tmpname + type

            // 替换掉原来的名字
            img_src = img_src.replace(fileName, tmpname)
            eml.src = img_src +'?'+Math.random()
        } else if (eml_tag == 'span' || eml_tag == 'SPAN' || eml_tag == 'em' || eml_tag == 'EM' || eml_tag == 'i' || eml_tag == 'I') {
            eml.innerHTML = temlist[type]
        }

    }
}


function changeElementTelBGFromList(taglist, type) {

    for(var i = 0; i < taglist.length; i++){
        var eml = taglist[i]
        eml_style = eml.currentStyle || window.getComputedStyle(eml, false);
        img_src = eml_style.backgroundImage
        var fileName = img_src.substring(img_src.lastIndexOf('\/')+1,img_src.lastIndexOf('.'));
        var tmpname = fileName.substring(0,fileName.length-1)
        tmpname = tmpname + type

        // 替换掉原来的名字
        img_src = img_src.replace(fileName, tmpname)
        eml.style.backgroundImage=img_src
    }

}


function changeElementTelkf(taglist, type) {

    for(var i = 0; i < taglist.length; i++){
        var eml = taglist[i]
        var href_val = eml.href;
        var tmpname = href_val.substring(0,href_val.length-1)
        tmpname = tmpname + type
        eml.href=tmpname
    }

}

// 按指定的类型换电话号码  1 对应sem 2对应seo 3对应bbs
function changeTelByType(teltype){
    changeElementTelFromList(getElementByClass('telnumbcls'), teltype);
    changeElementTelBGFromList(getElementByClass('telnumbclsbg'), teltype);
}


// 判断客服风格
function kefuStyle(kefu_cookie_type) {
    var tel_type = 1;
    if(cook_kc.test(kefu_cookie_type)){

        tel_type = 1;

    }else if(cook_ys.test(kefu_cookie_type)){

        tel_type = 4;

    }else if(cook_zt.test(kefu_cookie_type)){

        tel_type = 5;

    }else if(cook_sh.test(kefu_cookie_type)){

        tel_type = 6;

    }else if(cook_xsat.test(kefu_cookie_type)){

        tel_type = 7;

    }else if(cook_yd.test(kefu_cookie_type)){

        tel_type = 8;

    }else if(cook_cg.test(kefu_cookie_type)){

        tel_type = 9;

    }else if(cook_wm.test(kefu_cookie_type)){

        tel_type = 10;

    }else if(cook_wk1.test(kefu_cookie_type)){

        tel_type = 11;

    }else if(cook_360.test(kefu_cookie_type)){

        tel_type = 12;

    }else if(cook_sg.test(kefu_cookie_type)){

        tel_type = 13;

    }else if(cook_wk.test(kefu_cookie_type)){

        tel_type = 14;

    }else{

        tel_type = 1;

    }

    return tel_type;
}


function changeTelNumAll(){
    cookie_tel_type = CookieUtil.get("xiaoma_tel_cookie");

    if(cookie_tel_type != null && cookie_tel_type != undefined && cookie_tel_type != '' && cookie_tel_type != '0'){

        // cookie存在 ,换电话
        changeTelByType(cookie_tel_type);
    }else{

        // cookie 不存在
        var fulldomain = window.location.host;
        if(reg_xm.test(fulldomain)){ // 判断主机名:xiaoma.com

            var kefu_cookie_type = CookieUtil.get("xiaoma_style_id");
            var tel_cookie_overdue = parseInt(CookieUtil.get("xiaoma_style_id_overdue") + "000");
            var tel_type = kefuStyle(kefu_cookie_type);
            changeTelByType(tel_type);
            var tel_expires = new Date(tel_cookie_overdue);
            CookieUtil.set("xiaoma_tel_cookie", tel_type, tel_expires, "/", "xiaoma.com");

        }else{

            $.getJSON("http://www.xiaoma.com/didiadmin/test_telchange.php?callback=?", function(data){

                var kefu_cookie_num = data.xiaoma_style_id;
                var date_now = parseInt(data.xiaoma_style_id_overdue + "000");
                var tel_type = kefuStyle(kefu_cookie_num);
                changeTelByType(tel_type);
                var tel_expires = new Date(date_now);
                if(reg_xsat.test(fulldomain)) {
                    domain_url = "xuesat.com";
                // }else if(reg_jy.test(fulldomain)) {
                //     domain_url = "xiaomajiaoyu.com";
                }else if(reg_cg.test(fulldomain)) {
                    domain_url = "xiaomachuguo.com";
                }else{
                    domain_url = "xiaoma.com";
                };
                CookieUtil.set("xiaoma_tel_cookie", tel_type, tel_expires, "/", domain_url);

            })

        }
    }

}



/*
 * 传递函数给whenReady()
 * 当文档解析完毕且为操作准备就绪时,函数作为document的方法调用
 */
var whenReady = (function() {               //这个函数返回whenReady()函数
    var funcs = [];             //当获得事件时,要运行的函数
    var ready = false;          //当触发事件处理程序时,切换为true

    //当文档就绪时,调用事件处理程序
    function handler(e) {
        if(ready) return;       //确保事件处理程序只完整运行一次

        //如果发生onreadystatechange事件,但其状态不是complete的话,那么文档尚未准备好
        if(e.type === 'onreadystatechange' && document.readyState !== 'complete') {
            return;
        }

        //运行所有注册函数
        //注意每次都要计算funcs.length
        //以防这些函数的调用可能会导致注册更多的函数
        for(var i=0; i<funcs.length; i++) {
            funcs[i].call(document);
        }
        //事件处理函数完整执行,切换ready状态, 并移除所有函数
        ready = true;
        funcs = null;
    }
    //为接收到的任何事件注册处理程序
    if(document.addEventListener) {
        document.addEventListener('DOMContentLoaded', handler, false);
        document.addEventListener('readystatechange', handler, false);            //IE9+
        window.addEventListener('load', handler, false);
    }else if(document.attachEvent) {
        document.attachEvent('onreadystatechange', handler);
        window.attachEvent('onload', handler);
    }
    //返回whenReady()函数
    return function whenReady(fn) {
        if(ready) { fn.call(document); }
        else { funcs.push(fn); }
    }
})();


whenReady(changeTelNumAll);

页面结构:

<!-- 文字形式--固定标签包含 -->
<span class="telnumbcls">400-6969-256</span>
<em class="telnumbcls">400-6969-256</em>
<i class="telnumbcls">400-6969-256</i>

<!-- 图片形式 -->
<img class="telnumbcls" src="tel_01.png" alt="" />

<!-- 背景图片形式 -->
<div class="telnumbclsbg" style="background:url(tel_01.png) no-repeat;">内容内容内容内容内容</div>
发表评论
* 昵称
* Email
* 网址
* 评论