I have a div that is created on a button pressed and I'm trying to have it deleted by clicking outside of it but it takes the original button press as clicking outside and immediately closes the div.
closediv();
}
function closediv() {
document.addEventListener("click", (evt) => {
const maindiv = document.getElementById('div3');
let targetElement = evt.target;
do {
if (targetElement == maindiv.childNodes[1]) {
return;
}
targetElement = targetElement.parentNode;
} while (targetElement);
var viewpost = maindiv.childNodes[1];
viewpost.parentNode.removeChild(viewpost);
});
}
In your button click handler, you could use
theButton.addEventListener("click", function(ev) {
ev.stopPropagation();
// rest of the code
});
and the click event would not propagate to the parent containers.
just add a click event on body to close your div and then add prevent default into your div to block closing action when user click on your div
document.body.addEventListener('click', (e) =>{
//close your div here
})
document.addEventListener("click", (evt) => {
evt.preventDefault()
// your code
}
Related
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 need to prevent hiding of a modal dialog when user clicks on the dialog, then moves the mouse outside of the dialog, and releases it. The dialog is placed inside outer div on which the click event is registered. Here is the example of the modal dialog and its setup.
So I've done the following:
var pointerDownElement = null;
$('.d1').on('mousedown', function(event) {
// this is how I do it to prevent triggering of click event
pointerDownElement = event.target;
// this is how a browser does it
pointerDownElement = event.currentTarget;
});
$('.d1').on('mouseup', function(event) {
var element = event.target;
if (element === pointerDownElement) {
console.log('triggering click');
}
});
Is this approach correct?
You're definitely on the right track. Slightly modified code:
var pointerDownElement = null;
$('.d1').on('mousedown', function(event) {
event.preventDefault();
pointerDownElement = event.currentTarget;
return false;
});
$('.d1').on('mouseup', function(event) {
if (event.target=== pointerDownElement) {
console.log('triggering click');
}
});
No need to assign a value to a variable if you're only going to use it once. Also, event.preventDefault(); and return false; will guarantee the default behavior of the event doesn't take place (not that there typically is one for mousedown, but I'm assuming you have a reason for including this code).
I have a button that a user is supposed to click to upload files:
window.URL = window.URL || window.webkitURL;
var button = document.getElementById("button"),
fileElem = document.getElementById("fileElem"),
fileList = document.getElementById("fileList");
button.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();
}
e.preventDefault();
}, false);
function handleFiles(files) {
if (!files.length) {
fileList.innerHTML = "<p>No files selected!</p>";
} else {
fileList.innerHTML = "";
for (var i = 0; i < files.length; i++) {
var videoFile = document.createElement("video");
videoFile.setAttribute("id", "recording");
videoFile.src = window.URL.createObjectURL(files[i]);
videoFile.height = 240;
videoFile.width = 320;
videoFile.setAttribute("controls", true);
videoFile.onload = function() {
window.URL.revokeObjectURL(this.src);
}
fileList.appendChild(videoFile);
}
}
}
Then the user is supposed to use the space bar to pause/play a video. My problem is after the user clicks the button, the button stays clicked so when he or she pushes the space bar, the button is liked again. To solve this problem, the user would have to click somewhere else on the screen (except for the button) and then the space bar will work to pause/play the video. But I do not want the user to click somewhere else. So I tried to click a span element using JS but it did not work:
document.getElementById("spanElement").click();
This click is supposed to simulate the click the user would on the screen, but it doesn't work because when the spacebar is pressed, the button is clicked.
Any suggestions to solve this?
Thank you
Using HTMLElement.blur() should have the desired effect.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur
button.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();
}
e.preventDefault();
e.target.blur();
}, false);
This will remove focus from the element once clicked.
That happen because after the click on the button it still focused, so to solve that behavior you could use .blur() in the end of click event.
The blur() method is used to removes keyboard focus from the current element.
button.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();
}
e.target.blur(); //Remove focus after click
e.preventDefault();
}, false);
Hope this helps.
You could also add css to the button - pointer events
to disable button: $("#buttonId").css("pointer-events", "none");
to reactivate button: $("#buttonId").css("pointer-events", "auto");
I'm working a site using this Bootstrap example, with a simple slide in sidebar navigation.
http://ironsummitmedia.github.io/startbootstrap-simple-sidebar/#
It is slightly modified, so I have a button for the menu to open:
// Opens the sidebar menu
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#sidebar-wrapper").toggleClass("active");
});
And a button for the menu to close:
// Closes the sidebar menu
$("#menu-close").click(function (e) {
e.preventDefault();
$("#sidebar-wrapper").toggleClass("active");
});
I want to add functionality, so it will close if I click anywhere outside the sidebar. So far I have this:
// Close the menu on click outside of the container
$(document).click(function (e) {
var container = $("#sidebar-wrapper");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0 // ... nor a descendant of the container
&& event.target.id !== "menu-toggle") // for the functionality of main toggle button
{
container.removeClass("active");
}
});
But it seems to remove the "active" class this way.
Best regards.
So the solution should be that if you click anywhere inside the container the click handler should do nothing and just return. But if the click is outside the container then it should close it.
Below is the click handler code which might help you.
$(document).click(function(e) {
var node = e.target;
// loop through ancestor nodes to check if the click is inside container.
// If yes then return from the handler method without doing anything
while(node.parentNode) {
if (node === container) {
return;
}
node = node.parentNode;
}
container.removeClass('active')
});
Try this
$(document).click(function (e)
{
var container = $("#wrapper");
if (!container.is(e.target) && container.has(e.target).length === 0 && event.target.id!=="menu-toggle")
{
container.addClass("toggled");
}
});
So what basically it is doing is if e is element you want to toggle the class and if the clicked e is also that then the class wil not toggle otherwise it will.
You can use a recursive function that check if a element clicked exists in cointainer from sidebar menu:
function hasElement(node, element) {
return node == element
|| (node.childNodes || []).length && Array.from(node.childNodes)
.filter(x => x.nodeType == 1)
.some(x => hasElement(x, element));
}
$('body').click(function (event) {
var container = Array.from($("#sidebar")); //Add another containers that would be clicked wihtout close sidebar
var exists = container.some(node => hasElement(node, event.target));
if (!exists)
//TODO Close sidebar here...
});
I am using the following code to create a popup bubble when a user double-clicks on the webpage:
function displaySomething(x, y) {
var div = document.createElement("div");
div.id = "displaySomething_div";
....
}
var listener = function (event) {
if (event.button == 0 ) {
var div = document.getElementById("displaySomething_div");
if (div) {
document.body.removeChild(div);
}
displaySomething(event.pageX, event.pageY);
}
};
document.addEventListener("dblclick", listener, false);
Currently, the popup bubble will only be dismissed when I double-click on the page or on the bubble.
Is it possible to dismiss the popup bubble only when a single-click over non-bubble area of the page is made? That is, if I click or select over the bubble, the bubble will stay there.
Add a click handler to the popup div which stops propagation of the click event, and then you can safely attach a click handler to the document parent.
Example: http://jsfiddle.net/M6asx/
function displaySomething(x, y) {
var div = document.createElement("div");
div.id = "displaySomething_div";
...
div.addEventListener('click', function(e) { e.stopPropagation(); }, false);
}
var listener = function (event) {
if (event.button == 0) {
var div = document.getElementById("displaySomething_div");
if (div) {
document.body.removeChild(div);
} else {
displaySomething(event.pageX, event.pageY);
}
}
};
document.addEventListener('click', listener, false);