Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                  <div class="todo">
    <header>
      <h4>待辦事項</h4>
      <div class="form">
        <input type="text" placeholder="add todos" class="newTodo">
        <button class="btn addButton">新增</button>
      </div>
    </header>
    <ul class="pending">
      <!-- 待辦事項新增區域 -->
    </ul>
    <h4>完成事項</h4>
    <ul class="done">
      <!-- 完成事項區域 -->
    </ul>
  </div>
              
            
!

CSS

              
                * {
/*   outline: 1px solid blue; */
  color: #5E5A54;
}

.todo {
  width: fit-content;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid #e0e0e0;
  border-radius: 15px;
  background-color: #FFE4B8;
/*   background-color: #FAB419; */
  box-shadow: 1px 1px 5px 2px rgba(0,0,0, 0.5)
}

header {
  margin-bottom: 15px;
}

.newTodo {
  background-color: #E6D1B1;
  padding: 7px;
  border-radius: 5px;
  margin-right: 15px;
}

.addButton {
  background-color: #FFCFAD;
  background-color: #CF7C76;
  color: snow;
}

.checked {
  color: #888;
  text-decoration: line-through;
  font-style: italic;
}

.fa {
  margin: 0 5px;
  color: #074887;
}

li>input {
  width: 210px;
}

li>label[for='done'] {
  width: 210px;
}


.done, .pending {
  list-style: none;
  padding: 0;
}

input {
  background-color: #FFE4B8;
/*   background-color: #FAB419; */
  outline-color: #FFE4B8;
  border: 0;
}

.pending input {
  outline: none;
}

li {
  margin-bottom: 10px;
  display: flex;
  justify-content: space-between;
  border-bottom: 1px dotted;
}

.check {
  color: #00A6A6;
}


              
            
!

JS

              
                // 初始變數
let pending = document.querySelector('.pending')
let addButton = document.querySelector('.addButton')
let input = document.querySelector('.newTodo')
let done = document.querySelector('.done')

// 放待辦事項資料的陣列: 測試用的假資料
const todos = ['寫今天的鐵人賽文章', '寫明天的鐵人賽文章', '寫後天的鐵人賽文章']

function displayDummyData(todos) {
  for (let todo of todos) {
      addTodo(todo)
  }
}

displayDummyData(todos);



// 函式
function addTodo (text) {
  const newTodo = document.createElement('li')
  
  newTodo.innerHTML = `
  <input value ="${text}">
    <div class="icon-group">
      <i class="delete fa fa-trash"></i>
      <i class="check fa fa-check-circle"></i>
    </div>
  `
  pending.appendChild(newTodo)
}


//監聽新增按鈕,判斷有輸入字串再加入
addButton.addEventListener("click", function () {
  const inputValue = input.value
  if (inputValue.trim().length > 0) {
    addTodo(inputValue)
    input.value = ""
  }
})


pending.addEventListener('click', changeState)

function changeState (e) {
  const list = e.target.closest('li')
  
  if (e.target.classList.contains('delete')) {
    list.remove();
  } 
  else if (e.target.classList.contains('check')) { 
    list.remove()
    
    const itemDone = document.createElement('li')
    
    const content = list.children[0].value
    itemDone.innerHTML += `<input value ="${content}" class="checked" disabled="disabled">
    <div class="icon-group">
      <i class="delete fa fa-trash"></i>
      <i class="check fa fa-check-circle"></i>
    </div>`
      

    done.appendChild(itemDone)
  }
}


// Delete and unchecked in the Done list
done.addEventListener ('click', restorePendingState)
done.addEventListener ('click', remove)


// 回復到pending的狀態
function restorePendingState (e){
  const list = e.target.closest('li')    
  
  if (e.target.tagName === 'INPUT' || e.target.classList.contains('check') ) {
    list.remove()
    const itemUnfinished = document.createElement('li')
    const content = list.children[0].value;
    itemUnfinished.innerHTML += `<input value ="${content}" class="">
    <div class="icon-group">
      <i class="delete fa fa-trash"></i>
      <i class="check fa fa-check-circle"></i>
    </div>`
    
    pending.appendChild(itemUnfinished)
  } else {
    return
  }
}


// 抽出移除功能
function remove(e) {
  if (e.target.classList.contains('delete')) {
    const list = e.target.closest('li') 
    list.remove()
  } else {
    return
  }
}



//按下 Enter 鍵時,一樣可以新增 to-do
document.addEventListener('keypress', function(){
  let inputValue = input.value
  if (event.code === "Enter" && inputValue.trim().length > 0) {
      addTodo(inputValue)
      input.value = ""
   }
})


//測試 code & keyCode 差異
document.addEventListener('keypress', function (e) {
  console.log(e.code)
  console.log(e.keyCode)
  }
)

              
            
!
999px

Console