個人待辦事項工具的設計和搭建(IFE前端2015春季 任務3)

来源:http://www.cnblogs.com/djtao/archive/2017/05/08/6826985.html
-Advertisement-
Play Games

這是我幾個月之前的項目作品,花了相當的時間去完善。博客人氣不高,但拿代碼的人不少,所以一直處於保密狀態。沒有公開代碼。但如果對你有幫助,並能提出指導意見的,我將十分感謝。 IFE前端2015春季 任務3 綜合練習 任務描述 參考 "設計稿" 實現一個簡單的個人任務管理系統:如下圖 " " 任務需求描 ...


這是我幾個月之前的項目作品,花了相當的時間去完善。博客人氣不高,但拿代碼的人不少,所以一直處於保密狀態。沒有公開代碼。但如果對你有幫助,並能提出指導意見的,我將十分感謝。

IFE前端2015春季 任務3

綜合練習

任務描述

參考設計稿實現一個簡單的個人任務管理系統:如下圖

設計稿

任務需求描述:

  • 最左側為任務分類列表,支持查看所有任務或者查看某個分類下的所有任務
  • 初始時有一個預設分類,進入頁面時預設選中預設分類
  • 分類支持多層級別。
  • 分類支持增加分類、刪除分類兩個操作在左側分類最下方有添加操作,點擊後彈出浮層讓輸入新分類的名稱,新分類將會被添加到當前選中的分類下。浮層可以為自行設計實現,也可以直接使用prompt。當滑鼠hover過某一個分類時,右側會出現刪除按鈕,點擊後,彈出確認是否刪除的浮層,確認後刪除掉該分類。彈出的確認浮層可以自行設計實現,也可以直接使用confirm。不能為預設分類添加子分類,也不能刪除預設分類
  • 每一個分類名字後顯示一個當前分類下的未完成任務總數量。
  • 中間列為任務列表,用於顯示當前選中分類下的所有未完成任務
  • 任務列表按日期(升序或者降序,自行設定)進行聚類
  • 用不同的字體顏色或者圖標來標示任務的狀態,任務狀態有兩張:已完成未完成
  • 下方顯示新增任務的按鈕,點擊後,右側列會變成新增任務編輯界面。
  • 單擊某個任務後,會在右側顯示該任務的詳細信息。
  • 在任務列表的上方有任務篩選項,可以選擇在任務列表中顯示所有任務,或者只顯示已完成或者未完成的任務。
  • 右側為任務詳細描述部分
  • 第一行顯示任務標題,對於未完成的任務,在標題行的右側會有完成任務的操作按鈕及編輯任務的按鈕。
  • 點擊完成任務按鈕時,彈出確認是否確認完成的浮層,確認後該任務完成,更新中間列任務的狀態。彈出的確認浮層可以自行設計實現,也可以直接使用confirm
  • 點擊編輯任務操作後,右側變更為編輯視窗。
  • 新增及編輯任務視窗描述
  • 有3個輸入框:分別是標題輸入框,完成日期輸入框及內容輸入框
  • 標題輸入框:輸入標題,為單行,需要自行設定一個標題輸入限制的規則(如字數),並給出良好提示。
  • 日期輸入框:單行輸入框,按照要求格式輸入日期,如yyyy-mm-dd
  • 內容輸入框:多行輸入框,自行設定一個內容輸入的限制(如字數),並給出良好提示。
  • 確認按鈕:確認新增或修改。
  • 取消按鈕:取消新增或修改。

任務實現要求:

  • 整個界面的高度和寬度始終保持和瀏覽器視窗大小一致。當視窗變化高寬時,界面中的內容自適應變化。
  • 左側列表和中間列表保持一個固定寬度(自行設定),右側自適應。
  • 需要自行設定一個最小寬度和最小高度,當瀏覽器視窗小於最小值時,界面內容的高度和寬度不再跟隨變化,允許瀏覽器出現滾動條。
  • 通過本地存儲來作為任務數據的保存方式。
  • 不使用任何類庫及框架。
  • 儘可能符合代碼規範的要求。
  • 瀏覽器相容性要求:Chrome、IE8+。

註意

該設計稿僅為線框原型示意圖,所有的視覺設計不需要嚴格按照示意圖。如果有設計能力的同學,歡迎實現得更加美觀,如果沒有,也可以按照線框圖實現。以下內容可以自行發揮:

  • 背景顏色
  • 字體大小、顏色、行高
  • 線框粗細、顏色
  • 圖標、圖片
  • 高寬、內外邊距

解決方案

整個環境應該通過後端的交互實現。但是簡單地實現就是ajax方法。

項目要求不用任何類庫框架,但是任務2中的$d類庫是自己寫的。可以檢驗$d類庫的可靠性,所以用了也問題不大。

待辦事項列表是一個相當典型的數據結構,再設計數據結構時,顯然應該用面向對象的思路觸發操作。

基本樣式和交互

第一個問題就是高度自填充。

和寬度一樣,一個元素要在父級高度有數值時才能設定百分比高度。

分類列表

分類列表的方法應該是ul-li體系

  • ul.classify-list
  • li
    • h3.title-list
    • a.title1:點擊標簽,包含分類一級標題,點擊時給h3加上激活樣式。
    • a.close:關閉刪除按鈕(正常時隱藏,滑鼠划過時顯示)
    • ul classify-list2
    • li (以下是二級分類標題結構)

其中特殊分類是“預設分類”,不能刪除

點擊標題出現激活樣式:

我覺得這隻需要考慮當前點選邏輯,當點擊了二級分類,再點擊其它一級分類時,激活樣式顯示在所點擊的一級分類上。原來的二級分類激活樣式消失。

$('.title1').on('click',function(){
        $('.title-list').removeClass('classify-active');
        $(this.parentNode).addClass('classify-active');
    });

    $('.title2').on('click',function(){
        $('.title-list').removeClass('classify-active');
        $('.title-list',this.parentNode.parentNode.parentNode.parentNode).addClass('classify-active');

        $('.title-list2').removeClass('classify-active2');
        $(this.parentNode).addClass('classify-active2');
    });

註:兩次點擊的效果不同,所以考慮寫一個toggle方法。

//toggle方法:
$d.prototype.toggle=function(_event){
    var _arguments=Array.prototype.slice.call(arguments).slice(1,arguments.length);//把toggle的arguments轉化為數組存起來,以便在其它函數中可以調用。
    //console.log(_arguments);
    //私有計數器,計數器會被一組對象所享用。
    function addToggle(obj){
        var count=0;
        addEvent(obj,_event,function(){
            _arguments[count++%_arguments.length].call(obj);
        });
    }

    each(this.objs,function(item,index){
        addToggle(item);
    });
};

    //使用示例:
    $('.title1').toggle('click',function(){
        $('.classify-list2',this.parentNode.parentNode).obj.style.display='block';
    },function(){
        $('.classify-list2',this.parentNode.parentNode).obj.style.display='none';
    });

然後再寫一個hover方法

//hover方法
$d.prototype.hover=function(fnover,fnout){
    var i=0;
    //對於返回器數組的內容
    each(this.objs,function(item,index){
        addEvent(item,'mouseover',fnover);
        addEvent(item,'mouseout',fnout);
    });
    return this;
};

//使用示例
$('.title-list').hover(function(){
        if($('.classify-close',this.parentNode).obj){
            $('.classify-close',this.parentNode).move({'opacity':100});
        }
    },function(){
        if($('.classify-close',this.parentNode).obj){
            $('.classify-close',this.parentNode).move({'opacity':0});
        }
    });

還有一個狀態,如果點擊某個分類,下麵沒有子分類,就什麼都不顯示

$('.title1').toggle('click',function(){
        if($('.classify-list2',this.parentNode.parentNode).obj){
            $('.classify-list2',this.parentNode.parentNode).obj.style.display='block';
        }
    },function(){
        if($('.classify-list2',this.parentNode.parentNode).obj){
            $('.classify-list2',this.parentNode.parentNode).obj.style.display='none';
        }
    });

基本邏輯如下

待辦事項列表

篩選欄有三個按鈕和一個搜索框,其中,這三個按鈕應該擁有激活狀態

    $('.todo-btn').on('click',function(){
        $('.todo-btn').removeClass('todo-btn-active');
        $(this).addClass('todo-btn-active');
    });

後面的基本結構是這樣的——已完成和未完成都應該以不同的樣式顯示

<div class="todo-content">
                    <ul class="todo-date">
                        <span>2017-1-24</span>
                        <li class="completed"><a href="javascript:;">任務1</a></li>
                        <li class="uncompleted"><a href="javascript:;">任務2</a></li>
                        <li class="completed"><a href="javascript:;">任務3</a></li>
                    </ul>

                    <ul class="todo-date">
                        <span>2017-1-25</span>
                        <li class="completed"><a href="javascript:;">任務1</a></li>
                        <li class="completed"><a href="javascript:;">任務2</a></li>
                        <li class="uncompleted"><a href="javascript:;">任務3</a></li>
                    </ul>
                </div>

界面大致是這個樣子

要求篩選欄通過keyUp事件輸入或點擊按鈕,下麵的框動態顯示結果。

這些交互是通過數據特性來設置的,所以沒必要在這裡寫。

主體顯示區

類似Ps畫板。註意畫板去允許出現垂直滾動條。

    <div class="content">
                <div class="content-outer">
                    <div class="content-info">
                        <div class="content-header">
                            <h3>待辦事項標題</h3>
                            <a href="javascript:;">編輯</a>
                        </div>
                        <div class="content-substract">
                            任務日期:2017-1-25
                        </div>
                    </div>
                    
                    <div class="content-content">
                        <div class="content-paper">
                            <h4>啊!今天是個好日子</h4>
                            <p>完成task3的設計和樣式實現。</p>
                        </div>
                    </div>
                </div>

            </div>

佈局樣式

.content{
    width: auto;
    height: inherit;
    padding-left: 512px;
}
.content-outer{
    height: 100%;
    position: relative;
}
.content-info{
    height: 91px;
}
.content-content{
    position: absolute;
    width: 100%;
    top:91px;
    bottom: 0;
    background: #402516;
    overflow-y: scroll;
}

利用絕對定位的方式實現畫板區(.content-content)的高度自適應,然後.paper通過固定的margin實現區域延伸。

那麼整個界面就出來了。

前端組件開發

嚴格點說說“前端組件開發”這個名字並不准確。這裡只涉及了本項目中組件的控制邏輯,並不展示數據結構部分的邏輯。

靜態的模態彈窗

給分類列表和任務欄添加一個“添加”按鈕,要求添加時彈出一個模態彈窗。

彈窗提供最基本的功能是:一個輸入框,自定義你的分類名或任務名,一個取消按鈕,一個確定按按鈕。

模態彈窗是由兩個部分組成

  • 遮罩層(黑色,半透明)
  • 彈窗體

採用的是動態創建的方式可以給指定的彈窗添加id,兩個都是用絕對定位實現。

            <div class="add-mask"></div>
            <div id="(自定義)" class="add">
                <div class="add-title">
                    <h4>添加內容</h4>
                </div>
                <div class="add-content">
                    <span>名稱:</span>
                    <input type="text" name="" value="">
                    <div class="btns">
                        <button id="exit" type="button">取消</button>
                        <button id="submit" type="button">確定</button>
                    </div>
                </div>
            </div>

這個應該直接放到body標簽結束前。

組件結構

寫一個面向對象的組件,可以想象它的調用過程是怎樣的:

// 以添加分類為例:
var addCategoryModal=new Modal();

// 初始化
addCategoryModal.init({
  //這裡放配置
});
// 生成視窗
categoryModal.create();

new 出一個新的組件,然後進行初始化,傳入必要的參數,如果不傳配置,組件有自身的配置。

function Modal(){
    this.settings={
        // 這裡放預設的配置
    };
}

轉入的配置疊加可以通過一個擴展函數來實現:

function extend(obj1,obj2){
    for(var attr in obj2){
        obj1[attr]=obj2[attr];
    }
}
// ...
//這裡是以自定義的option配置覆蓋內部配置
Modal.prototype.init=function(option){
    extend(this.settings,option);
};

那麼這個框架就搭建起來了。

彈窗需要哪些配置?

在這個項目中,只需要指定彈窗提示內容title和彈窗類型type(這裡就三個,一個是目錄addCtategory,另一個是任務addMission,最後一個是通用提示框tips)就可以了。

其中,type將成為模態彈窗頂層容器的id值。

組件實現

生成視窗無非是給DOM追加一個節點。

Modal.prototype.create=function(){
    var oDialog=document.createElement('div');

    oDialog.className='add';
    oDialog.id=this.settings.type;
    if(this.settings.type=='tips'){
        oDialog.innerHTML =
            '<div class="add-title">'+
                '<h4>信息提示</h4>'+
            '</div>'+
            '<div class="add-content">'+
                '<span>'+this.settings.tips+'</span>'+
                '<div class="btns">'+
                    '<button id="exit" type="button">我知道了</button>'+
                '</div>'+
            '</div>';
    }else{
        oDialog.innerHTML =
            '<div class="add-title">'+
                '<h4>添加內容</h4>'+
            '</div>'+
            '<div class="add-content">'+
                '<span>'+this.settings.title+'名稱:</span>'+
                '<input class="input" type="text" value="">'+
                '<div class="btns">'+
                    '<button id="exit" type="button">取消</button>'+
                    '<button class="submit" type="button">確定</button>'+
                '</div>'+
            '</div>';
    }

    // 顯示效果
    document.body.appendChild(oDialog);
    $('.add-mask').obj.style.display='block';

    //彈窗位置指定,絕對居中
    var clientWidth=document.documentElement.clientWidth;
    var clientHeight=document.documentElement.clientHeight;

    oDialog.style.left=(clientWidth)/2-175+'px';
    oDialog.style.top=(clientHeight)/2-75+'px';

    //關閉按鈕
    function remove(){
        document.body.removeChild(oDialog);
        $('.add-mask').obj.style.display='none';
        $(this).un('click',remove);
    }
    $('#exit').on('click',remove);
};

好了。我們給一個#addCategory的按鈕添加點擊事件:

$('#addCategory').on('click',function(){
        var categoryModal=new Modal();
        categoryModal.init(
            {
                type:newCategory,
                title:'目錄'
            }
        );
        categoryModal.create();
    });

效果就出來了:

組件完善

要讓這個組件具有基本的功能,還需要寫遮罩層,取消按鈕等。

註意:以下效果全部在create方法中完成

遮罩

遮罩(.mask):遮罩是一個隱藏的,不需要動態顯示。

.add-mask{
    position: absolute;
    left: 0;
    top:0;
    right: 0;
    bottom:0;
    background: rgba(0,0,0,0.5);
    z-index: 99;/*註意.add的層級應該大於99*/
}
<div class="add-mask" style="display:none;"></div>

然後添加一個顯示效果:

    // 顯示效果
    document.body.appendChild(oDialog);
    $('.add-mask').obj.style.display='block';
取消按鈕(#exit)

本著清理乾凈的精神,除了把oDialog從document中清掉。

    //關閉按鈕
    function remove(){
        document.body.removeChild(oDialog);
        $('.add-mask').obj.style.display='none';
    }
    $('#exit').on('click',remove);

那麼取消就寫完了。

確定按鈕

確定按鈕也可以寫一個手動關閉彈窗的方法:

Modal.prototype.exit=function(){
    document.body.removeChild($('.add').obj);
    $('.add-mask').obj.style.display='none';
}

實際上

到此可以認為,這個靜態的模態彈窗完成。

效果:

markdown組件

雖然任務要求不用任何框架,但是我們的需求在當前來說已經開始超越了任務本身的需求,不用jQuery勉強可以接受,但是前端渲染你的content部分內容,marke.js顯然是最好的選擇。關於marked.js的用法,可以參照marked.js簡易手冊

實際上這已經是第三次在項目中用到mark.js,用起來水到渠成。

當然不想做任何處理的話,也可以跳過這節。

引入marked.js和highlight.js

現在把它拖進來。並引用一個基本能搭配當前頁面風格的樣式庫。

    <link rel="stylesheet" type="text/css" href="css/css.css"/>
    <link rel="stylesheet" type="text/css" href="css/solarized-dark.css"/>


    <script type="text/javascript" src="js/dQuery.js"></script>

    <script type="text/javascript" src="js/marked.js"></script>
    <script type="text/javascript" src="js/highlight.pack.js"></script>
    <script >hljs.initHighlightingOnLoad();</script>

    <script type="text/javascript" src="js/js.js"></script>

然後:

    // 渲染頁面模塊
    var rendererMD = new marked.Renderer();
    marked.setOptions({
        renderer: rendererMD,
        highlight: function (code,a,c) {
            return hljs.highlightAuto(code).value;
        },
        gfm: true,
        tables: true,
        breaks: false,
        pedantic: false,
        sanitize: false,
        smartLists: true,
        smartypants: false
    });

    //用於測試效果
    $('.content-paper').obj.innerHTML=marked('# 完成markdown模塊開發\n---\nRendered by **marked**.\n\n```javascript\nfunction(){\n  console.log("Hello!Marked.js!");\n}\n```\n這是響應式圖片測試:\n![](http://images2015.cnblogs.com/blog/1011161/201701/1011161-20170127184909206-861797658.png)\n1\. 傳進去前端的代碼結構必須符合樣式庫的要求。\n2\. 我要把頁面的代碼統統是現貨高亮顯示——比如這樣`alert(Hello!)`');
重寫樣式庫

儘管有了樣式庫的支持,但是這個樣式庫只是定義了配色。而瀏覽器預設的樣式被當初的css-reset給幹掉了。

markdown最常用的效果就是代碼高亮,搭配圖片顯示,

在過去的項目(Node.js博客搭建)中,我已經使用了marked.js重寫了一個還算漂亮的樣式庫(基於marked.js樣式庫和bootstrap樣式庫code和pre部分)。現在把重寫CSS的要點簡單歸納如左:

  • 響應式圖片
.content-paper img{
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid #ccc;
}
  • 列表效果(其實也包括ol-li)
.content-paper ul li{
  list-style: disc;
  margin-left: 15px;
}
.content-paper ol li{
  list-style: decimal;
  margin-left: 15px;
}
  • 文本間距,行間距,比如,p標記,h1-h6的間距等等。大小最好用em和百分比顯示,比如我的p標記字體大小為1.05em

效果如下:

那麼效果立刻有了。

搜索(過濾)組件

搜索組件只做一件事情:根據代辦事項列表窗(ul.todo-content)中的文本節點,通過監聽文本輸入框(input.search)的內容,綁定keyUp事件綁定,查找數據集。

如果按照封裝對象的思路來寫,一個是監聽模塊,一個是顯示模塊。為了方便起見,給各自的元素加上同名id。

思路

就實現上來說似乎很簡單,查找#todo-content裡面的文本節點,然後轉化為數組:

// 搜索組件
function Search(listener,shower){
    this.listener=$(listener);
    this.shower=$(shower);
}
Search.prototype.filter=function(){
    var value=this.listener.obj.value;
    var content=this.shower.obj.innerText;
    console.log(content.split('\n'));
};

$(funciton(){
  $('#search').on('keyup',function(){
        var search=new Search('#search','#todo-content');
        search.filter();
    });
});

然而不幸的事情發生了:

居然把任務日期打出來了。此外還有一個空文本。

因為html代碼結構是這樣的:

            <div id='todo-content' class="todo-content">
                    <ul class="todo-date">
                        <span>2017-1-24</span>
                        <li class="completed"><a href="javascript:;">任務1</a></li>
                        <li class="uncompleted"><a href="javascript:;">任務2</a></li>
                        <li class="completed"><a href="javascript:;">任務3</a></li>
                    </ul>

                    <ul class="todo-date">
                        <span>2017-1-25</span>
                        <li class="completed"><a href="javascript:;">任務1</a></li>
                        <li class="completed"><a href="javascript:;">任務2</a></li>
                        <li class="uncompleted"><a href="javascript:;">任務3</a></li>
                    </ul>
                </div>

既然這樣,就查找var search=new Search('#search','#todo-content li');把,然後對li對象做一個for迴圈。沒有的就設置display為none:

// 搜索組件
function Search(listener,shower){
    this.listener=$(listener);
    this.shower=$(shower);
}

Search.prototype.filter=function(){
    var value=this.listener.obj.value;

    var content=[];
    for(var i=0;i<this.shower.objs.length;i++){
        this.shower.objs[i].style.display='block';
        content.push(this.shower.objs[i]);
        if(this.shower.objs[i].innerText.indexOf(value)==-1){
            this.shower.objs[i].style.display='none';
        }
    }
};

// 調用
var search=new Search('#search','#todo-content li');
$('#search').on('keyup',function(){
    search.filter();
});

效果:

其它組件的實現

目前搜索組件有一個很大的問題,就是無法實現數據的雙向綁定。

輸入框搜索組件是獨立的判斷條件。下麵的三個按鈕是公用一套判斷信息。

思路是活用html元素的data屬性。給所有節點添加data-searchdata-query兩個屬性,所有html元素初始的兩個屬性都是true。當不同的按鈕被點選,就執行query方法把符合條件的元素的data-xxx設置為true。然後再進行渲染render,兩個屬性都為true的才不給添加.hide樣式(hide的樣式就是display為none)。

// 搜索組件
function Search(listener,shower){
    this.listener=$(listener);
    this.shower=$(shower);
    this.key='all';
}

Search.prototype.filter=function(){
    var value=this.listener.obj.value;
    // 先全部設置為true
    for(var j=0;j<this.shower.objs.length;j++){
        this.shower.objs[j].setAttribute('data-search', "true");
    }
    //綁定當前按鈕的搜索條件
    this.query(this.key);


    for(var i=0;i<this.shower.objs.length;i++){
        if(this.shower.objs[i].innerText.indexOf(value)==-1){
            this.shower.objs[i].setAttribute('data-search', 'false');
        }
    }

    this.renderer();

};

Search.prototype.query=function(key){
    this.key=key;
    for(var j=0;j<this.shower.objs.length;j++){
            //this.shower.objs[i].style.display='block';
        this.shower.objs[j].setAttribute('data-key',"true");
    }
    this.renderer();


    for(var i=0;i<this.shower.objs.length;i++){
        this.shower.objs[i].setAttribute('data-key',"true");
        if(key!=='all'){
            if(this.shower.objs[i].className!==key){
                this.shower.objs[i].setAttribute('data-key',"false");
            }
        }
    }
    this.renderer();
};
// 最後是渲染方法
Search.prototype.renderer=function(){
    for(var i=0;i<
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 持續的故事更新, 轉載 建造者模式(Builder)定義: 將一個複雜的對象的構造與它的表示分離, 是同樣的構建過程可以創建不同的表, 這樣的設計模式稱之為建造者模式 建造者模式主要需要註意的是 建造者模式解決的問題 建造者模式的使用場景 註釋 構建意思就是對象的創建 表示指的是構建對象的各種組合 ...
  • 在網上百度了很久,都是一樣的答案,而且根本執行不了~~~每次都會報錯,最後總算找到一個對的....不容易啊! 重點1:方法要寫在iframe onload裡面,載入完成再執行 重點2:用id獲取iframe元素,contentWindow獲取文檔對象 方法如下: var iFrame=documen ...
  • 最近在弄框架,用到了webpack打包,當然不可避免的遇到了開發實際問題。在實際開發中,我們不可能改一個文件,就去構建一次,於是想到了實時更新。查看webpack,看到了webpack-dev-server。 webpack-dev-server webpack已經想到了開發流程中的自動刷新,這就是 ...
  • HTML API localstorage在瀏覽器的API有兩個:localStorage和sessionStorage,存在於window對象中:localStorage對應window.localStorage,sessionStorage對應window.sessionStorage。loca ...
  • 一:不同空格符合的區別 &nbsp; 半形的不斷行的空白格(推薦使用) &ensp; 半形的空格 &emsp; 全形的空格 詳細的含義: &nbsp;:這是我們使用最多的空格,也就是按下space鍵產生的空格。在HTML中,如果你用空格鍵產生此空格,空格是不會累加的(只算1個)。要使用html實體表 ...
  • 軟體工程第二次作業——結對編程 ================================ 團隊 學號:1500802014;姓名:孟祥磊;博客地址: "http://www.cnblogs.com/MXLei1/" 學號:1500802013;姓名:劉哲乾;博客地址: "http://www ...
  • 今天在下載一個比較大的項目,經常shasum check failed,太煩了,於是想切淘寶源,分別嘗試nrm切換和傳遞 registry,結果都出現Unexpected end of JSON input錯誤。這是比較奇怪的,看起來是JSON數據沒有傳完。結合以前SwitchyOmega走priv ...
  • 1.圖片 <img / > 圖片的格式: 1.1BMP 占用空間大,顏色豐富。 1.2JPEG 有損壓縮,占用空間較小。 1.3GIF 多幀動圖,支持透明色。 1.4PNG 無損壓縮,點陣圖(由無數小點組成)支持透明色/半透明色。 <img /> 屬性: src="PATH” PATH:圖片的所在路徑 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...