实现产品列表的友好展示

       在交易下单的页面中,如产品过多则会影响页面展示,影响用户体验效果;所以通过对产品恰当归类与良好的用户交互,会给用户体验度带来大大的提升,而静态无刷新互动体验效果则更好;据说如果你的客户被吸引,久而久之,你客户的客户也会成为你的客户(有点虚J),不论是什么样的交易(B2C、C2C,抑或是纯DEMO的产品网站)。

本文通过示例详细描述客户端产品展示处理过程,主要以游戏产品充值下单为例,

技术实现:DIV +CSS + JS +JQUERY+XML

§、实现效果

1、shop.sdo.com

 上面的仅仅为产品展示,相对简单一下。

2、pay.sdo.com


3、pay.sdo.com



§、分析设计

1、 Process Flow:

UI    ------>         Handler       ------>         XML

UI    <------          Handler      <------          XML

类似局部MVC,Handler为控制器、XML数据对象为模型、UI为视图

UI响应事件发送至Handler,由Handler负责与XML交互、组织数据结构,控制UI显示。

2、 根据输入自动过滤相关产品,且按字母排序

     支持字母、汉字检索

3、 点击显示分类产品遮罩,按字母排序

4、 选中产品自动完成表单填充

账号类型、游戏区、服务器、服务组、充值方式、充值金额(线性、非线性)etc.

5、 弹出层需要遮罩高优先级对象:select、flash等

6、 自动记录点选产品历史

7、 支持回调,自定义代码处理片段

可根据不同的产品显示不同的公告

可自定义不同的产品、子产品、子项配置,创建不同的UI、特殊业务显示etc.

8、 不同浏览器的兼容性问题

9、父页面自适应处理

10、……

§、设计实现

将以上几部分,分类处理:

1、 用于支持JQUERY的辅助类:

主要处理兼容性、XMLDOM、元素优先级、其他扩展信息。

代码片段:

<span style="font-family:Microsoft YaHei;">var ItemDom;
(function($) { // hide the namespace
    $.LoadXml = function(dname) {        
        try { //Internet Explorer
            var xmlDoc;
            if (window.ActiveXObject) {
                xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
                xmlDoc.async = false;
                xmlDoc.load(dname);
            } else if (document.implementation && document.implementation.createDocument) {
                var xmlhttp = new window.XMLHttpRequest();
                xmlhttp.open("GET", dname, false);
                xmlhttp.send(null);
                // var xmlDoc = xmlhttp.responseXML.documentElement;
                var xmlDoc = xmlhttp.responseXML;
            } else {
                return null;
            }
            return xmlDoc;
        }
        catch (e) {
            //alert(e.message)
        }
        return (null);
    };
    //根据path,attribute name获得指定节点的属性值
    $.GetXmlAttr = function(Xml, path, attr) {
        var depositItemsDom;
        if (typeof Xml == "object") {
            depositItemsDom = Xml;
        }
        else {
            depositItemsDom = this.LoadXml(Xml);
        }
        if (depositItemsDom != null) {
            var record = depositItemsDom.selectNodes(path);
            if (record && record[0]) {
                return record[0].getAttribute(attr);
            }
        }
        return null;
    };
   $.GetNameById = function(value) {
        if (ItemDom == null) {
            ItemDom = $.LoadXml("../Config/DepositItems.xml");
        }
        return $.GetXmlAttr(ItemDom, "//items/item[@id='" + $.trim(value) + "']", "name");
    };
    //根据充值项名称获得充值项ID
    $.GetIdByName = function(value) {
        if (ItemDom == null) {
            ItemDom = $.LoadXml("../Config/DepositItems.xml");
        }
        return this.GetXmlAttr(ItemDom, "//items/item[@name='" + $.trim(value) + "']", "id");
    };
    /* common */
    $.fn.addOption = function(text, value) {
        if ($(this).length > 0) $(this).get(0).options.add(new Option(text, value));
    };
    $.Message = { Info: "", Error: "" };
    $.extend({
        getWidth: function(object) {
            return object.offsetWidth;
        },
        getLeft: function(object) {
            var go = object;
            var oParent, oLeft = go.offsetLeft;
            while (go.offsetParent != null) {
                oParent = go.offsetParent;
                oLeft += oParent.offsetLeft;
                go = oParent;
            }
            return oLeft;
        },
        getTop: function(object) {
            var go = object;
            var oParent, oTop = go.offsetTop;
            while (go.offsetParent != null) {
                oParent = go.offsetParent;
                oTop += oParent.offsetTop;
                go = oParent;
            }
            return oTop;
        }
    });
})((jQuery));</span>

2、 行为交互类

点选、输入控件事件绑定

初始化配置化参数

XML、DOM分类处理

内部辅助方法

为减少HTTP连接数,将以上处理合并至一个文件中。

代码片段:

(function($) { // hide the namespace
    $.Inputer = {
        InitConfig: function(parameters) {
            $.extend($.InitConfig, parameters || {});
            cg.id = $.InitConfig.inputid;
            cg.pmd = $.InitConfig.paymethod;
            cg.cdiv = $.InitConfig.clickdiv;
            cg.sdiv = $.InitConfig.selectdiv;
            if ($("#" + cg.id).length == 0) { return; }; //alert('config is Invalid');
            //绑定控件
            IBindControl();
            IBindBody();
            if (cg.pmd == 90) $.InitConfig.paymethodcmd = 90;
            else $.InitConfig.paymethodcmd = 60;
            //页面初始化(bank首页服务端特殊处理)
            if (cg.pmd != "60") PageRender.PageInit();
        }
    };
    $.InitConfig = {
        paymethod: '', //充值渠道
        paytype: '', //充值类型:bindpay,bank
        inputid: 'inputGame', //输入控件ID
        imageid: 'imgGame', //下拉图片ID
        selectdiv: 'SelectDiv', //用户输入字符时显示的DIV 默认
        clickdiv: 'ClickDiv', //用户点击输入框时输入的DIV
        CallBackEvent: function() { }, //触发自定义事件
        configpath: '/Config',
        clickcss: '',
        selectcss: 'AllBrow',
        isBindArea: true,
        DisableItem: '', //不显示的充值项
        PlayerTypeEvent: null,
        ConsumeEvent: null,
        paymethodcmd: 60
    };
    IBindControl = function() {
        $("#" + $.InitConfig.imageid).bind("click", IClick);
        $("#" + cg.id).bind("keyup", ISelect);
        $("#" + cg.id).bind("focus", IFocus);
        $("#" + cg.id).bind("blur", IBlur);
    };
    IClick = function() {
        $("#popup").css("display", "none"); //热血传奇提示
        if (cg.pmd == "60") PageRender.PageInit(); //bank首次为服务端,所以重新初始化
        var obj = $("#" + cg.id).get(0);
        if ($("#" + cg.cdiv).length == 0) {
            var left = right = 0;
            if ($.browser.msie && $.browser.version.search("7.0") != -1) { left = 25; right = 19; }
            else if ($.browser.msie && $.browser.version.search("6.0") != -1) { left = 30; right = 12; }
            else { left = 8; right = 18; }
            $("<div id='" + cg.cdiv + "'></div>").appendTo($("body")).css({ left: $.getLeft(obj) - left + 'px', top: $.getTop(obj) + right + 'px', display: '' });
        }
        else { $("#" + cg.cdiv).show(); }
        //hide select div
        $("#" + cg.sdiv).hide();
        //fill data
        GetClickData();
    };
    ISelect = function(event) {
        if (cg.pmd == "60") PageRender.PageInit();
        $("#" + cg.id).val($.trim($("#" + cg.id).val()));
        if ($("#" + cg.id).val() == '') return;
        if ($("#" + cg.sdiv).length == 0) {
            $("<div id='" + cg.sdiv + "' onkeydown='return PageRender.selectKeyDown(event)'></div>").appendTo($("body")).css({ left: $.getLeft(this) + 'px',
                top: $.getTop(this) + 20 + 'px', display: ''
            });
        }
        else { $("#" + cg.sdiv).show(); }
        //hide click div
        $("#" + cg.cdiv).hide();
        //获取下拉数据
        GetSelectData(event);
    };
    IFocus = function() {
        $("#popup").css("display", "none"); //热血传奇提示
        $("#" + cg.id).css({ color: '#000000' });
        $("#" + cg.id).select();
    };
    IBlur = function() {
        var str = "汉字| 拼音 |字母";
        if ($(this).val() == "") $(this).val(str);
        else if ($(this).val() == str) $(this).css({ color: '#a7a7a7' });
    };
    //异步获取点击数据
    GetClickData = function() {
        $("#" + cg.cdiv).show();
        $(cg.cdiv).remove("iframe");
        if ($(cg.cdiv).html() == "") return;
        else $("#" + cg.cdiv).html(PageRender.createList());
        $("#" + cg.cdiv).bgiframe();
    };
    //异步获取过滤数据
    GetSelectData = function(e) {
        $("#" + cg.sdiv).show();
        PageRender.getFilterList(e);
        $("#" + cg.sdiv).bgiframe();
    };
    IBindBody = function() {
        $("body").bind("click",
        function(event) {
            var e = event || window.event;
            var srcElement = e.srcElement || e.target;
            if (srcElement.type != "name" && srcElement.tagName != "A"
                    && srcElement.id == "") {
                $("#" + cg.cdiv + ",#" + cg.sdiv).hide();
            }
            PageRender.AutoIframe();
        }
        );
    };
    $.Reset = function() {
        Game = GameID = PlayerType = PlayerName = ConsumeMode = GameArea = GameAreaID = GameServer = GameServerID = ParValue = BankID = null;
    };
    $.IsNull = function(obj) {
        if (!obj || obj == null || typeof obj == "undefined") return true;
        return false;
    };
})((jQuery))


var MyXml = {
    ConsumesPath: function() {
        return "//deposititem/paymethods/paymethod[@id='" + $.InitConfig.paymethodcmd + "']/consumes/consume";
    },
    //根据游戏ID获得游戏名称
    GetNameById: function(value) {
        if (DepositItemsDom == null) {
            DepositItemsDom = this.GetDepositItem();
        }
        return $.GetXmlAttr(DepositItemsDom, "//items/item[@id='" + $.trim(value) + "']", "name");
    },
    //根据充值项名称获得充值项ID
    GetIdByName: function(value) {
        if (DepositItemsDom == null) {
            DepositItemsDom = this.GetDepositItem();
        }
        return $.GetXmlAttr(DepositItemsDom, "//items/item[@name='" + $.trim(value) + "']", "id");
    },
    GetDefaultDom: function() {
        return $.LoadXml($.InitConfig.configpath + "/Default.xml");
    }
};


//----------------------------------- 页面输出 -----------------------------------//
var PageRender = {
    //
};

§、调用

<span style="font-family:Microsoft YaHei;">$(document).ready(function() {
        //配置绑定到页面控件、初始信息
        $.Inputer.InitConfig({ paymethod: 60, inputid: 'inputGame', imageid: 'imgGame', selectdiv: 'SelectDiv', clickdiv: 'ClickDiv',
            CallBackEvent: function(paras) { BindGameEvent(paras); Bulletin.SetDepositItemTip(paras); }
        });

   BankDeposit.PageInit();
   Bulletin.SetDepositItemTip(GameID);
});

var SubmitOrder = {
    PageInit: function() {
        PageRender.setValue(GameID); //重置游戏项
    }
};</span>

§、示例

http://download.youkuaiyun.com/download/webwalker/7470335

      

§、总结

      当然产品展现方式有很多种,根据实际情况与特殊业务决定,除了以上的JS+XML的方式来实现,通过JS+JSON组织数据也是不错的选择。

总体实现下来,更多的复杂业务上实现,由于时间关系,这块并未有完全剥离,代码上也有并不到位之处:全局变量、样式配置etc.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值