Mi código actual abre una entrada mediante un clic al agregar una clase. Tengo problemas para agregar un segundo clic que elimine la clase agregada cuando el usuario hace clic en la entrada. Agregué un segundo evento de clic, pero simplemente detiene el funcionamiento de mi primer evento de clic.
¿Hay alguna forma diferente de abordar esto usando JavaScript puro?
(Comentado intento fallido.)
let searchElement = document.querySelector('#searchElement'); let offCanvas = document.querySelector('#main'); searchElement.addEventListener('click', () => { searchElement.classList.add('extendInputSearch'); }); // offCanvas.addEventListener('click', () => { // searchElement.classList.remove('extendInputSearch'); // }); * { padding: 0; margin: 0; } html, body { height: 100%; width: 100%; } main { display: flex; align-items: center; justify-content: center; height: 100%; background-color: #e1e2f1; } form { display: flex; align-items: center; justify-content: center; width: 100%; } input { width: 100%; height: 32px; border: none; outline: none; font-size: 1rem; } .inputSearch { display: flex; align-items: center; width: 100%; max-width: 15px; padding: 8px 20px; background-color: #ffffff; border: 1px solid transparent; border-radius: 6px; transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1); } .inputSearch:hover { border: 1px solid #7e51fa; } .inputSearch i { color: #7e51fa; margin-right: 20px; } .extendInputSearch { max-width: 400px; } <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/> <main id="main"> <form> <div id="searchElement" class="inputSearch"> <i class="fas fa-search"></i> <input type="text" placeholder="Search"> </div> </form> </main>El problema con su intento es que el detector de eventos para eliminar la clase se aplica a todo el elemento #main , que incluye searchElement. Eso significa que ambos detectores de eventos se aplican al elemento de búsqueda, y cuando hace clic en el elemento de búsqueda, la clase primero se agrega (con el primer detector) y luego se elimina (con el segundo detector).
Para que funcione, debe cambiar el segundo oyente para excluir específicamente el elemento de búsqueda. Por ejemplo, en este código, agregamos un detector de clics a todo el documento. En el oyente, verificamos si el clic está fuera del elemento de búsqueda usando la función Node.contains() en el parámetro del evento. Si el elemento en el que se hizo clic no es un elemento secundario de searchElement (es decir, el clic está fuera de searchElement), eliminamos la clase extendInputSearch de searchElement.
let searchElement = document.querySelector('#searchElement'); searchElement.addEventListener('click', () => { searchElement.classList.add('extendInputSearch'); }); document.addEventListener('click', (e) => { if(!searchElement.contains(e.target)){ searchElement.classList.remove('extendInputSearch'); } }); * { padding: 0; margin: 0; } html, body { height: 100%; width: 100%; } main { display: flex; align-items: center; justify-content: center; height: 100%; background-color: #e1e2f1; } form { display: flex; align-items: center; justify-content: center; width: 100%; } input { width: 100%; height: 32px; border: none; outline: none; font-size: 1rem; } .inputSearch { display: flex; align-items: center; width: 100%; max-width: 15px; padding: 8px 20px; background-color: #ffffff; border: 1px solid transparent; border-radius: 6px; transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1); } .inputSearch:hover { border: 1px solid #7e51fa; } .inputSearch i { color: #7e51fa; margin-right: 20px; } .extendInputSearch { max-width: 400px; } <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/> <main id="main"> <form> <div id="searchElement" class="inputSearch"> <i class="fas fa-search"></i> <input type="text" placeholder="Search"> </div> </form> </main>intentalo:
let searchElement = document.querySelector('#searchElement'); let offCanvas = document.querySelector('#main'); searchElement.addEventListener('click', () => { searchElement.classList.add('extendInputSearch'); }); document.addEventListener('click', (e) => { const searchElement = document.querySelector('#searchElement'); if (e.target != searchElement && e.target != searchElement.querySelector('i') && e.target != searchElement.querySelector('input')) { searchElement.classList.remove('extendInputSearch'); } }); * { padding: 0; margin: 0; } html, body { height: 100%; width: 100%; } main { display: flex; align-items: center; justify-content: center; height: 100%; background-color: #e1e2f1; } form { display: flex; align-items: center; justify-content: center; width: 100%; } input { width: 100%; height: 32px; border: none; outline: none; font-size: 1rem; } .inputSearch { display: flex; align-items: center; width: 100%; max-width: 15px; padding: 8px 20px; background-color: #ffffff; border: 1px solid transparent; border-radius: 6px; transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1); } .inputSearch:hover { border: 1px solid #7e51fa; } .inputSearch i { color: #7e51fa; margin-right: 20px; } .extendInputSearch { max-width: 400px; } <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/> <main id="main"> <form> <div id="searchElement" class="inputSearch"> <i class="fas fa-search"></i> <input type="text" placeholder="Search"> </div> </form> </main>