I can't figure out what's going on. Below is the JS code that is responsible for closing and opening the search box running in the JS application. Closing occurs by pressing a button with a cross, Esc keyboard and anywhere in this window
const btn = document.querySelector('.head__search-icon'),
body = document.body,
search = document.querySelector('.search'),
searchInner = document.querySelector('.search__inner'),
searchOverlay = document.querySelector('.search__overlay'),
searchInput = document.querySelector('#search__input'),
btnClose = document.querySelector('.search__closed-button');
body.classList.add('no-search'),
search.style.display = 'none';
function searchOpen() {
btn.addEventListener('click', () => {
body.classList.remove('no-search');
body.classList.add('is-search');
search.style.display = 'block';
setTimeout(() => searchInput.focus(), 100);
if (body.classList.contains('is-head-open')) {
body.classList.remove('is-head-open');
}
});
}
searchOpen();
function searchClose() {
body.classList.add('no-search');
body.classList.remove('is-search');
searchInput.value = '';
searchInput.blur();
}
function searchRemove(e) {
if(e.code === "Escape" && body.classList.contains('is-search') || e.target === searchOverlay || e.target === searchInner) {
searchClose();
}
}
document.addEventListener('keydown', searchRemove);
search.addEventListener('click', searchRemove);
btnClose.addEventListener('click', searchClose);
The fact is that if there is a search result, and press Esc, then everything works, the focus from the input disappears, and the input itself is cleared. But if you click anywhere in the window ( e.target === searchOverlay || e.target === searchInner ), then the window itself closes, the input is cleared, as I need, except that with a visually clean input, the search results remain. That is, you open the window again and see the same search results, although the input is empty. When working with Esc, the input is actually cleared. Where is the jamb in the script?
In general, I made it easier, added a construction to the searchClose() function to remove the search result using innerHTML = ' '
Related
I have an input field with the name box. I can move forward after input by
box.addEventListener('input', function () {
if(!isNaN(parseInt(box.value))){
box.value = "";
}else if(box != null){
box.nextSibling.focus();
}
});
And it's working alright. I wish to move to the previous sibling of the input by backspace, and I am doing it by the previous sibling and kind of the same logic
box.addEventListener('keyup', function (e) {
if(e.key == 'Backspace' && box != null){
box.previousSibling.focus();
}
})
But doing this only works for the first backspace properly, for the rest of the inputs I need to backspace twice. I tried with the keydown event too and even that wasn't perfect.
The problem is that (in the browsers you and I are using) input events are processed before keyup events, so you press backspace on a non-empty box and a character is deleted, so input is processed then the next sibling is selected, then the keyup is processed and you move to the previous sibling, which looks like going nowhere.
You can fix this by storing the box where the value changed, then if that reference is not null on backspace keyup you can move to the previous sibling of the box where the keyup event fired, otherwise move to the previous sibling of the box where the input event fired.
const boxes = document.getElementById('boxes');
let inputInput = null;
for(let i = 0; i < 12; i++)
{
const box = document.createElement('input');
box.type="text"
box.addEventListener('input', function (e)
{
if(!isNaN(parseInt(box.value)))
{
box.value = "";
}
else if(box != null)
{
inputInput = box;
box.nextSibling.focus();
}
});
box.addEventListener('keyup', function (e)
{
if(e.key == 'Backspace' && box != null)
{
if(inputInput == null)
{
box.previousSibling.focus();
}
else
{
inputInput.previousSibling.focus();
inputInput = null;
}
}
});
boxes.appendChild(box);
}
<div id="boxes">
</div>
The problem with this solution is that event precedence is not part of the specification, so this is not necessarily cross browser compatible, i.e. in some browsers keyup might happen before input.
I'm currently studying a full stack course and my modal isn't behaving as expected
I'm a bit lost on what to do as I can't find any documentation anywhere and while clicking on the close button or pressing ESC works, clicking outside of the box doesn't.
The following code is how it has been suggested I approach the issue but, it doesn't work. I've honestly stared at this for about an hour and just can't connect the dots on what is (not) happening? Please excuse all the commenting and additional code as I'm still learning so, it's how I'm able to follow what's going on:
function showModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.add('is-visible');
}
function hideModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.remove('is-visible');
}
//modal IFFE
document.querySelector('#modal-button').addEventListener('click', () => {
showModal();
});
//-- show modal --
function showModal(title, text) {
var $modalContainer = document.querySelector('#modal-container');
//Selects the element with the associated id
// Clear all content for the selected element
$modalContainer.innerHTML = '';
var modal = document.createElement('div'); //creates a div element withing selected element
modal.classList.add('modal'); //assigns new class to the div element
// Add the new modal content
var closeButtonElement = document.createElement('button'); //creates the close button
closeButtonElement.classList.add('modal-close'); //assigns a class to the new (close) button
closeButtonElement.innerHTML = "×"; //inserts text within the new(close) button
closeButtonElement.addEventListener('click', hideModal);
var titleElement = document.createElement('h1');
titleElement.innerText = title;
var contentElement = document.createElement('p');
contentElement.innerText = text;
modal.appendChild(closeButtonElement);
modal.appendChild(titleElement);
modal.appendChild(contentElement);
$modalContainer.appendChild(modal);
$modalContainer.classList.add('is-visible');
}
document.querySelector('#modal-button').addEventListener('click', () => {
showModal('PokéMon', 'Here is all of the info about your PokéMon');
});
window.addEventListener('keydown', (e) => {
var $modalContainer = document.querySelector('#modal-container');
if (e.key === 'Escape' && $modalContainer.classList.contains('is-
visible')) {
hideModal();
}
});
$modalContainer.addEventListener('click', (e) => {
var target = e.target;
if (target === $modalContainer) {
hideModal();
}
});
Expected result: User clicks outside of the modal (on the container) and the modal closed.
Current result: No change in state, modal remains active and visible. Only by clicking on the close button (x) or by pressing ESC is the desired result achievable.
By Looking at this code I am not sure what is actually supposed to make the modal visible or hide it. Without access to your css (if you have any). I am assuming that all you are doing is adding and removing the class .is-visible from the #modal-container element.
I would suggest that you apply this class to the modal itself, and then you could toggle this class on and off,
Modify your code to do this by doing something like this (added on top of your code):
function showModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.add('is-visible');
document.querySelector('.modal').classList.remove('hide-el')
}
function hideModal() {
var $modalContainer = document.querySelector('#modal-container');
$modalContainer.classList.remove('is-visible');
document.querySelector('.modal').classList.add('hide-el')
}
Where hide-el in your css is:
.hide-el {
display: none;
}
You could also modify your code to appply the is-visible class to your modal element. You should always try to attach the class/id to the element you want to manipulate if you have that option.
Or if you do not have access to a css file:
document.querySelector('.modal').style.display = "none"
and
document.querySelector('.modal').style.display = "block"
Also, your code seems very verbose, was this boilerplate part of the assignment?
heres a working example: https://codepen.io/mujakovic/pen/zVJRKG
The code was in the incorrect place in the end and should have looked something like this:
modal.appendChild(closeButtonElement);
modal.appendChild(titleElement);
modal.appendChild(contentImage);
modal.appendChild(contentHeight);
modal.appendChild(contentElement);
$modalContainer.appendChild(modal);
$modalContainer.classList.add('is-visible');
$modalContainer.addEventListener('click', (e) => { //listening for an event (click) anywhere on the modalContainer
var target = e.target;
console.log(e.target)
if (target === $modalContainer) {
hideModal();
}
});
};
window.addEventListener('keydown', (e) => { //listening for an event (ESC) of the browser window
var $modalContainer = document.querySelector('#modal-container');
if (e.key === 'Escape' && $modalContainer.classList.contains('is-visible')) {
hideModal();
}
});
This is because the action was originally being called on page load and targeted within the window instead of being called within the container and being loaded when the modal loads.
Thank for your help
I'm making text editor.
This is demo image what i made
Using contenteditable, I render code to dangerouslySetInnerHTML.
So the component look like this
But like figure1, I can access next to select
( In second figure, it is between </div> here <select ~~>
I want to prevent a user from accessing and writing at that point
But I did not found preventing access method.
So I thought when user write content then check the parent and execute event.preventDefault() except for left arrow and up arrow.
it works well in English and others.
But when I write Korean. PreventDefault is not working.
How can I execute preventDefault in Korean??
handleKeyDown = (event) => {
let key;
if(window.event) {
key = event.keyCode;
} else {
key = event.which; //For Firefox
}
const selection = document.getSelection();
if (selection.anchorNode) {
const check = selection.anchorNode.parentElement;
if (check.className.includes('src-components') && key !==37 && key !== 38) {
event.preventDefault();
event.stopPropagation();
}
}
}
P.S : the event.target.value return undefined.
I am trying to create an onblur event where any time some one clicks anywhere on the page it will stay focused on that element unless it is a specif element then it will refocus to that specific element.
I am probably way off but this is what I tried, and it just stays focused on the Barcode element no matter what.
function stayOnBarcode() {
var QTY = document.getElementById("QTY");
var Barcode = document.getElementById("Barcode");
if (Barcode.value === "") {
if (QTY.focus() === true) {
QTY.focus();
}
else if (document.hasFocus() === true) {
Barcode.focus();
}
}
else {
Barcode.focus();
}
}
How about something like this:
$(document).on("mousedown", function(e) {
clicked = $(e.target)
})
$("input").on("blur", function() {
if (!clicked.is("#QTY") && !clicked.is("#Barcode")) {
$(this).focus()
}
})
It stores the most recently clicked element in the variable clicked, then on blur event it checks if last_clicked is something other than #QTY or #Barcode. If so, it re-focuses the input being blurred.
You might need to tweak it to fit the exact conditions you have in mind, or feel free to add specifics to your question.
Check out this working fiddle: https://jsfiddle.net/oez0488h/63/
OK, so there's a question that gets asked around here a lot about Firefox not responding to window.event, where instead you need to add an extra parameter to the function. I have no problems with that; my problem is how the heck do I do that if I want to assign the event listeners from within a different Javascript function?
Basically, what I'm trying to do is the common effect when you can have a form box that has grey text that would say, for example, "Your name..." and then when you click the box the text disappears and the color changes to black; unfocus with the box still empty and the prompt text will return.
Now, instead of coding this directly for every page I want to use it on, I'm trying to make a function that I can call with the ID of the form and it will automatically apply this to every input element. Here's the code:
function fadingForm(formElementID, endColor)
{
var form = document.getElementById(formElementID);
for(var i = 0; i < form.elements.length; i++)
{
form.elements[i].originalValue = form.elements[i].value;
form.elements[i].originalColor = form.elements[i].style.color;
form.elements[i].changedColor = endColor;
// Somehow I need to get that event parameter in here I guess?
// I tried just putting the variable event in as a parameter,
// but as you'd expect, that doesn't work.
form.elements[i].onfocus = function() { focused(); };
form.elements[i].onblur = function() { blurred(); };
}
}
function focused(e)
{
evt = e || window.event;
element = evt.target;
if(element.value == "" || element.value == element.originalValue)
{
element.value = "";
element.style.color = element.changedColor;
}
}
function blurred(e)
{
evt = e || window.event;
element = evt.target;
if(element.value == "" || element.value == element.originalValue)
{
element.value = element.originalValue;
element.style.color = element.originalColor;
}
}
And of course, this works perfectly in Chrome, Safari, etc...just not Firefox.
Your event listeners focused and blurred accept an event object e, but you never provide an event object. The event object that is provided to the anonymous wrapper functions is never used nor passed to focused/blurred. Thus, e is always undefined.
Instead, when you set up your listeners, do:
form.elements[i].onfocus = function(e) { focused(e); };
form.elements[i].onblur = function(e) { blurred(e); };
Or even:
form.elements[i].onfocus = focused;
form.elements[i].onblur = blurred;
So that the event object is passed directly into your listener functions.