简体   繁体   中英

How to use closest() in a proper way in js

Student here! Lets say i have function append() which generates <li> items inside an <ol> ,those li items contain 2 buttons,one for removing the <li> that lies within and one for creating the same item but inside itself this time,in order to make another list layer. Both by using the closest() method.

i cant figure out how to use the ADD <button> ,i can call it but i cannot it make it work the way i want to. I get this : 在此处输入图像描述 But i want to get something like this : 在此处输入图像描述

this is how i'm trying to do it:

 function append() { var ol = document.getElementById("ol1"); var li = document.createElement("li"); li.innerHTML = (`LIST ITEM <input class=input><button class=add>ADD</button><button class=remove>REMOVE</button>`); ol.append(li) document.getElementById("ol1").addEventListener("click",function(e) { const tgt = e.target; if (tgt.classList.contains("remove")) tgt.closest("li").remove(); if (tgt.classList.contains("add")) tgt.closest("li").appendChild(li); }) }
 <html> <body> <button id="btn1" onclick="append()">Append</button> <ol id="ol1"> </ol> </body> </html>

To number with 1. , 1.1 , 1.2 , 2. , 2.1 , 3. , you need to use CSS . The counters function, obtains the number of the li . Each time an ol appears, the counter is reset to 1. . When a li appears, the top counter is used, concatenated with the new next new number of the previous li .

ol {
  counter-reset: item
}
li {
  display: block;
}
li:before {
  content: counters(item, ".") ". ";
  counter-increment: item;
}

In the append function, we add the li ... For this, we call another function, which we will call create_li() which does the creation of the li .

function append() {
  document.querySelector("#ol1").append( create_li() )
}

In the create_li() function, we create the li and return it with return li . In li , we add the two button elements, add and remove , but instead of doing it through a string, we do it with the function we already know, that is to say, document.createElement() , and also, on each button, we can add una función que llamaremos button_click function, used to receive the click event through addEventListener .

function create_li(){
  var li = document.createElement("li")
  var add = document.createElement("button")
  var remove = document.createElement("button")

  li.innerHTML = "LIST ITEM <input class=input>"

  add.className = "add"
  remove.className = "remove"
  add.innerHTML = "+"
  remove.innerHTML = "-"
  add.addEventListener("click",button_click)
  remove.addEventListener("click",button_click)

  li.appendChild(add)
  li.appendChild(remove)
  
  return li
}

The button_click function, what it does is create the ol and li structure. In addition, it detects if the button clicked is the add or remove .

function button_click(e) {

  const tgt = e.target;
  var litg = tgt.closest("li")
  var oltg = litg.querySelector("ol")

  if(oltg==null){
    var ol = document.createElement("ol")
    litg.appendChild(ol)
    oltg = ol
  }

  if (tgt.classList.contains("remove")){
    litg.remove()
  }
  if (tgt.classList.contains("add")){
    oltg.appendChild( create_li() )
  }
}

The HTML structure is based on the li has to be inside the ol , and each sublist has to have an ol inside the li .

<ol>
    <li>
        1.
        <ol>
            <li>1.1</li>
            <li>1.2</li>
            <li>1.3</li>
        </ol>
    </li>
    <li>
        2.
        <ol>
            <li>2.1</li>
            <li>2.2</li>
            <li>2.3</li>
        </ol>
    </li>
    <li>
        3.
        <ol>
            <li>3.1</li>
            <li>3.2</li>
            <li>3.3</li>
        </ol>
    </li>
</ol>

Finished code:

 function button_click(e) { const tgt = e.target; var litg = tgt.closest("li") var oltg = litg.querySelector("ol") if(oltg==null){ var ol = document.createElement("ol") litg.appendChild(ol) oltg = ol } if (tgt.classList.contains("remove")){ litg.remove() } if (tgt.classList.contains("add")){ oltg.appendChild( create_li() ) } } function create_li(){ var li = document.createElement("li") var add = document.createElement("button") var remove = document.createElement("button") li.innerHTML = "LIST ITEM <input class=input>" add.className = "add" remove.className = "remove" add.innerHTML = "+" remove.innerHTML = "-" add.addEventListener("click",button_click) remove.addEventListener("click",button_click) li.appendChild(add) li.appendChild(remove) return li } function append() { document.querySelector("#ol1").append( create_li() ) }
 ol { counter-reset: item } li { display: block; } li:before { content: counters(item, ".") ". "; counter-increment: item; }
 <button id="btn1" onclick="append()">Append</button> <ol id="ol1"></ol>

This is probably what you want?

 function append() { var ol = document.getElementById("ol1"); var li = document.createElement("li"); li.innerHTML = (`LIST ITEM <input class="input"><button class="add" onclick="add(this)">ADD</button><button class="remove" onclick="remove(this)">REMOVE</button><ol></ol>`); ol.append(li) } function add(e) { var li = document.createElement("li"); li.innerHTML = (`LIST ITEM <input class="input"><button class="add" onclick="add(this)">ADD</button><button class="remove" onclick="remove(this)">REMOVE</button><ol></ol>`); e.parentElement.getElementsByTagName("ol")[0].appendChild(li); } function remove(e) { e.parentElement.parentElement.removeChild(e.parentElement); }
 <html> <body> <button id="btn1" onclick="append()">Append</button> <ol id="ol1"> </ol> </body> </html>

Instead of using 'closest' in the add method, you can simply find the parent and append in that.

EG: tgt.parentNode().appendchild(childLi)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM