iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
Modern Web

30天每天寫網站系列 第 29

Day29-用jQuery寫得出ToDoList嗎_4_單機版ToDoList沒有問題!

  • 分享至 

  • xImage
  •  

這篇來說剩下的重要功能

先來寫刪除的部分
就叫做removeTodo吧
加在a連結上,一樣需要回傳this
JS的部分
概念比較好理解
一樣抓取到id之後,去掉我們多加上的文字
然後在todos中找到它刪除掉,再更新就好了

function removeTodo(todo) {
    var Mid = todo.id.replace("mybutton_", "")
    todos.splice(result.indexOf(Mid), 1);
    update()
}

https://i.imgur.com/Lkhw4Wa.gif

最後我們寫一個更動List內容的部分
如果我們雙擊List的label的話,讓使用者可以更換List內容
我的作法是隱藏一個input在label前,然後用function抓取label文字給input
更新完後按確定,一樣使用function換成抓取input文字給label,並更新到陣列中

先更改HTML
要新增input跟一個確定用的按鈕,並把它們加在同一個div中
然後把之前的label跟刪除按鈕也綁在另一個div中

<div id="AID_HERE" class="text_css" style="display: none;">
    <input type="text" id="TID_HERE"> - 
    <a href="#" class="ok_css" id="FID_HERE" onclick="confirm(this)">
        確定
    </a>
</div>
<div id="DID_HERE" class="text_css">
    <label id="LID_HERE" ondblclick="alter(this)">CONTENT_HERE</label> - 
    <a href="#" class="remove_css" id="AID_HERE" onclick="removeTodo(this)">
        刪除
    </a>
</div>

兩個新增個div都要設ID讓jQuery幫忙設定與隨機碼相關的id
等等會新增兩個function
一個叫做alter給label使用,我用的是ondblclick,因為我希望雙擊label才會啟動,需要給this值
另一個叫做confirm給確認使用,一樣需要給this值

接著進入JS
剛剛新增的id就記得去取幫它們名字嘿,不然會抓不到

先寫雙擊的部分

function alter(todo) {
    var Mid = todo.id.replace("mylabel_", "")
    $("#mydolist_" + Mid).css("display", "none");
    $("#mytext_" + Mid).val(todo.innerText);
    $("#myalter_" + Mid).css("display", "block");
    $("#mycheckforlabel_" + Mid).addClass("dbclick")
}

這個函式首先一樣要把隨機碼取出來,然後我們把含有label的那個div隱藏
並把label中的字放到要顯示的input,在把含有input的div顯示出來
這樣便能打字啦~

https://i.imgur.com/QOghORF.gif

接著要讓確認鍵有效果

function confirm(todo) {
    var Mid = todo.id.replace("myconfirm_", "")
    todos[result.indexOf(Mid)].content = $("#mytext_" + Mid).val()
    $("#mylabel_" + Mid).html($("#mytext_" + Mid).val());
    $("#myalter_" + Mid).css("display", "none");
    $("#mydolist_" + Mid).css("display", "block");
}

基本就是剛剛隱藏的顯示,剛剛顯示的隱藏,文字換成input的給label
多一行是要把新打的文字傳給陣列做更新
這邊我同步給大家看console.log
https://i.imgur.com/CBbB8KW.gif

然後我要把剛剛在input設的確定鍵做刪除,改成按下enter時會直接送出不用按確定了
這個部份很簡單,先把確定鍵刪除掉
然後在雙擊更改的alter()後面加上偵測,偵測在input打字的狀態
如果按下enter送出,就呼叫confirm()這個確認函式
(按下enter送出的部分,我有把一開始加入List的部分偷偷改成這樣使用噢噢)
另外我有加了一行addClass的,是我為了避免打字時還能點擊checkbox先把它隱藏了,後續確認再removeClass就好
(dbclick是一個display: none; 的CSS樣式)

增加後的alter()長這樣

function alter(todo) {
    var Mid = todo.id.replace("mylabel_", "")
    $("#mydolist_" + Mid).css("display", "none");
    $("#mytext_" + Mid).val(todo.innerText);
    $("#myalter_" + Mid).css("display", "block");
    $("#mycheckfor_" + Mid).addClass("dbclick")
    $("#myalter_" + Mid).keydown(function (event) {
        if (event.which == 13) {
            confirm(Mid)
        }
    });
}

這邊我傳給confirm函式的是label的隨機碼,跟input是同一組,所以可以直接傳給confirm
然後因為傳進去的數值跟點擊按鈕時給的this不一樣,所以確認函式也要做更改
改成不用特別去抓id或是處理數值,可以直接做使用了

function confirm(todo) {
    var Mid = todo;
    todos[result.indexOf(Mid)].content = $("#mytext_" + Mid).val()
    $("#mylabel_" + Mid).html($("#mytext_" + Mid).val());
    $("#myalter_" + Mid).css("display", "none");
    $("#mydolist_" + Mid).css("display", "block");
    $("#mycheckfor_" + Mid).removeClass("dbclick")
}

為了統一好找所以我還是跟其他函式一樣弄成了Mid這個變數去抓~
https://i.imgur.com/TOvxIPB.gif
這樣處理後就可以快速地做更動不用一直反覆拿回滑鼠了

最後我要加一個避免多個List同時被點擊更改的限制
概念是如果你在更改List的狀態下,點擊了該List的input以外的地方,我就會直接幫你存檔然後確認送出去
程式碼是長這樣

$("body").click(function (e) {
    if (input != 0) {
        var container = $("#myalter_" + input);
        if (!container.is(e.target) && container.has(e.target).length == 0) {
            confirm(input)
        }
    }
});

直接放在ready中就好,但是為了避免被不斷偵測或是偵測不到東西,有多設置一個變數較做input
預設var input = 0; 放在最外層
然後在雙擊函式的最後加上一行input = Mid; 把目前隨機碼的數值給到input變數
讓點擊body時可以去看現在是有打開"更改List的input"的狀態,需要偵測是否點到"目標input"以外
也把這個input變數給到點擊body的程式碼中,用以判斷點擊的是"目標input"以外的地方
最後在確認函式的最後一行加上input = 0; 用以代表目前已經不再是"更改List的input"的狀態了,不用去偵測我點到哪了
https://i.imgur.com/P0A0LTb.gif

這樣基本上我們的單機版(?)ToDoList便完成了

接下來我幫它加了一些CSS美化啦~
https://i.imgur.com/CLFCYQH.gif


上一篇
Day28-用jQuery寫得出ToDoList嗎_3_id的重要性與作用
下一篇
Day30-我也想要寫感言_終於解脫啦
系列文
30天每天寫網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言