jquery.dataTable.js 使用详解 二、sDom布局源码解析

dataTable是怎么利用aDom实现布局的,提出了疑问。由于很久以前看的源码,当时也没有跟他解释的很清楚,于是又重新梳理了一下源码,在这里做一下笔记。

首先看一下示例的实际效果:
在这里插入图片描述

源码中实现布局的方法是_fnAddOptionsHtml(),形参是oSettings

下面看_fnAddOptionsHtml()源码:


    function _fnAddOptionsHtml ( oSettings )  
    {  
        /* 
         * Create a temporary, empty, div which we can later on replace with what we have generated 
         * we do it this way to rendering the 'options' html offline - speed :-) 
         * 作者说:这里先创建一个临时的空div,后面会被完整的内容替换掉 
         */  
        var nHolding = $('<div></div>')[0];  
        /* 
         * 把上面生成的临时div插入到绑定dataTable插件的元素前面 
         * 这里的oSettings.nTable,追溯源码,发现是this,也就是绑定插件的对象 
         * 例如:$("#mainTable").dataTable({....});   oSettings.nTable 就是 id为mainTable的 
         */  
        oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable );  
        /*  
         * All DataTables are wrapped in a div 
         * 作者说:创建一个div作为根节点,将所有的元素都包裹进去,以<table>的id拼接'_wrapper' 
         */  
        oSettings.nTableWrapper = $('<div id="'+oSettings.sTableId+'_wrapper" class="'+oSettings.oClasses.sWrapper+'" role="grid"></div>')[0];  
        oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;  
      
        /* Track where we want to insert the option  
         * 将oSettings.nTableWrapper赋给变量nInsertNode,跟踪我们想插入的元素 
         */  
        var nInsertNode = oSettings.nTableWrapper;  
          
        /* Loop over the user set positioning and place the elements as needed */  
        /* 
         * 前方高能,重头戏开始了!!! 
         * 分割aDom,得到字符数组 
         * 示例中我们的aDom属性值为<lf>rt<lpi><"clear"> 
         */  
        var aDom = oSettings.sDom.split('');  
        var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j;  
        /* 
         * 迭代字符数组 
         */  
        for ( var i=0 ; i<aDom.length ; i++ )  
        {  
            iPushFeature = 0;  
            cOption = aDom[i];  
            /* 
             * 如果当前字符是'<'执行以下操作 
             */  
            if ( cOption == '<' )  
            {  
                /* New container div  
                 * 创建一个空div 
                 */  
                nNewNode = $('<div></div>')[0];  
                  
                /* Check to see if we should append an id and/or a class name to the container  
                 * 看看是否要给div添加id属性或者class属性 
                 * 如果<符号后面是'或"就要给div添加属性 
                 */  
                cNext = aDom[i+1];  
                if ( cNext == "'" || cNext == '"' )  
                {  
                    sAttr = "";  
                    j = 2;  
                    while ( aDom[i+j] != cNext )  
                    {  
                        sAttr += aDom[i+j];  
                        j++;  
                    }  
                      
                    /* Replace jQuery UI constants */  
                    if ( sAttr == "H" )  
                    {  
                        sAttr = oSettings.oClasses.sJUIHeader;  
                    }  
                    else if ( sAttr == "F" )  
                    {  
                        sAttr = oSettings.oClasses.sJUIFooter;  
                    }  
                      
                    /* The attribute can be in the format of "#id.class", "#id" or "class" This logic 
                     * breaks the string into parts and applies them as needed 
                     * 如果字符串里面有#号,就给div加上id属性,如果字符串里面有.号,就给div加上class属性 
                     */  
                    if ( sAttr.indexOf('.') != -1 )  
                    {  
                        var aSplit = sAttr.split('.');  
                        nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);  
                        nNewNode.className = aSplit[1];  
                    }  
                    else if ( sAttr.charAt(0) == "#" )  
                    {  
                        nNewNode.id = sAttr.substr(1, sAttr.length-1);  
                    }  
                    else  
                    {  
                        nNewNode.className = sAttr;  
                    }  
                      
                    i += j; /* Move along the position array */  
                }  
                /* 
                 * 将处理完成后的div放入根节点,并对根节点变量重新赋值为新创建的div 
                 */  
                nInsertNode.appendChild( nNewNode );  
                nInsertNode = nNewNode;  
            }  
            else if ( cOption == '>' )  
            {  
                /* End container div  
                 * 这里标识一个div的闭合  
                 */  
                nInsertNode = nInsertNode.parentNode;  
            }  
            else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange )  
            {  
                /* Length  
                 * 如果当前字符为l,则表示为dataTable增加可以操作每页显示行数的下来框 
                 * 前置条件为bLengthChange和bPaginate配置为true,即允许分页并且允许用户选择每页显示行数 
                 * 将在_fnFeatureHtmlFilter函数中创建class="mainTable_length"的元素,并且放入上面创建的div中 
                 */  
                nTmp = _fnFeatureHtmlLength( oSettings );  
                iPushFeature = 1;  
            }  
            else if ( cOption == 'f' && oSettings.oFeatures.bFilter )  
            {  
                /* Filter  
                 * 如果当前字符为f,则表示为dataTable增加跨行搜索框 
                 * 前置条件为bFilter配置为true,即启用内置搜索,可跨行搜索 
                 * 将在_fnFeatureHtmlFilter函数中创建class="dataTables_filter"的元素,并且放入上面创建的div中 
                 */  
                nTmp = _fnFeatureHtmlFilter( oSettings );  
                iPushFeature = 1;  
            }  
            else if ( cOption == 'r' && oSettings.oFeatures.bProcessing )  
            {  
                /* pRocessing  
                 * 如果当前字符为r,则表示为dataTable增加数据加载进度效果 
                 * 前置条件为bProcessing配置为true,即显示加载时进度条 
                 * 将在_fnFeatureHtmlProcessing函数中创建class="dataTables_processing"的元素,并且放入上面创建的div中 
                 */  
                nTmp = _fnFeatureHtmlProcessing( oSettings );  
                iPushFeature = 1;  
            }  
            else if ( cOption == 't' )  
            {  
                /* Table  
                 * 这就是table实体了,将在_fnFeatureHtmlTable函数中创建table元素,table的属性、样式将沿用html代码中的定义 
                 */  
                nTmp = _fnFeatureHtmlTable( oSettings );  
                iPushFeature = 1;  
            }  
            else if ( cOption ==  'i' && oSettings.oFeatures.bInfo )  
            {  
                /* Info  
                 * 如果当前字符为i,则表示为dataTable增加表格相关信息,例如翻页信息等。 
                 * 前置条件为bInfo配置为true,即显示表格相关信息 
                 * 将在_fnFeatureHtmlInfo函数中创建class="dataTables_info"的元素,并且放入上面创建的div中 
                 * */  
                nTmp = _fnFeatureHtmlInfo( oSettings );  
                iPushFeature = 1;  
            }  
            else if ( cOption == 'p' && oSettings.oFeatures.bPaginate )  
            {  
                /* Pagination  
                 * 如果当前字符为p,则表示为dataTable增加分页功能。 
                 * 前置条件为bPaginate配置为true,即开启分页功能 
                 * 将在_fnFeatureHtmlPaginate函数中创建分页所需的元素,并且放入上面创建的div中  
                 * */  
                nTmp = _fnFeatureHtmlPaginate( oSettings );  
                iPushFeature = 1;  
            }  
            else if ( DataTable.ext.aoFeatures.length !== 0 )  
            {  
                /* Plug-in features */  
                var aoFeatures = DataTable.ext.aoFeatures;  
                for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )  
                {  
                    if ( cOption == aoFeatures[k].cFeature )  
                    {  
                        nTmp = aoFeatures[k].fnInit( oSettings );  
                        if ( nTmp )  
                        {  
                            iPushFeature = 1;  
                        }  
                        break;  
                    }  
                }  
            }  
              
            /* Add to the 2D features array */  
            if ( iPushFeature == 1 && nTmp !== null )  
            {  
                if ( typeof oSettings.aanFeatures[cOption] !== 'object' )  
                {  
                    oSettings.aanFeatures[cOption] = [];  
                }  
                oSettings.aanFeatures[cOption].push( nTmp );  
                nInsertNode.appendChild( nTmp );  
            }  
        }  
          
        /* Built our DOM structure - replace the holding div with what we want  
         * 将上面的临时div换成我们最后生成的div 
         */  
        nHolding.parentNode.replaceChild( oSettings.nTableWrapper, nHolding );  
    }  

最后附上一张,aDom字符与界面元素的对应关系图:
在这里插入图片描述

jquery.datatable是一款常用的前端表格插件,它支持前端和后端分页两种方式。在后端分页的情况下,数据请求和处理都在服务器端完成,前端只需要展示和呈现数据。 在使用jquery.datatable进行后端分页时,我们需要进行以下步骤: 1.准备后端接口:需要在服务器端提供一个接口来处理数据请求。这个接口需要接受一些参数,例如当前页码、每页显示数量等。接口会根据这些参数查询数据库,并返回相应的数据结果。 2.前端配置datatable插件:在前端页面中,需要引入jquery.datatable的相应脚本文件,并配置datatable的参数。其中,重要的参数包括ajax配置项,用于指定后端接口的URL,以及服务器端接口需要的参数。 3.发送数据请求:当用户操作表格进行翻页或者其他操作时,jquery.datatable会根据配置的ajax参数自动发送数据请求到后端接口。请求参数中包含当前页码、每页显示数量等信息。 4.服务器处理请求:后端接口接收到数据请求后,根据请求参数进行相应的查询和处理操作。可以使用数据库查询语言等方式查询数据库,并返回结果给前端。 5.前端展示数据:jquery.datatable会自动根据后端返回的数据结果,生成对应的表格展示。同时,它还提供了丰富的功能和样式配置选项,使得表格的展示更加灵活和美观。 总结来说,使用jquery.datatable进行后端分页需要准备后端接口,配置前端datatable,并进行数据请求和处理。这样就能够实现在前端页面展示由后端数据查询而来的分页表格。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值