I'm working on a project in which a javascript function runs when either 1) a button is clicked or 2) the "return" key is pressed. The javascript function sets a div's visibility to "visible" and changes the "onclick" and "onKeyDown" attributes to run a different function when clicked/pressed a second time.
For example, clicking the button (or pressing return) once will make the div appear, and doing it twice should make it disappear.
The problem is that I cannot figure out how to make the javascript change the "onKeyDown" attribute when the function is triggered. Is this possible?
I based my code off of this answer: Call a function when the enter button is pressed via Javascript
Here is my code so far:
function visible() {
document.getElementById("box").style.visibility = "visible";
document.getElementById("button").onclick = hidden;
document.body.onKeyDown = "if(event.keyCode==13) hidden()";
}
function hidden() {
document.getElementById("box").style.visibility = "hidden";
document.getElementById("button").onclick = visible;
document.body.onKeyDown = "if(event.keyCode==13) visible()";
}
#box {
visibility:hidden;
width:200px;
height:200px;
background:red;
}
#button {
width:120px;
height:50px;
background:lightblue;
}
<html>
<body onKeyDown="if(event.keyCode==13) visible()">
<div id="box"></div>
<div id="button" onclick="visible()" ></div>
</body>
</html>
Clicking the blue box will make the red box appear, and so will pressing return; but pressing return again will not make the box disappear.
The onkeydown property for JavaScript is case sensitive. Thus, using onKeyDown will set a different function to hidden, while the body's keydown action is still visible().
To fix it, change onKeyDown to onkeydown in both files. It's kinda confusing at first since it doesn't follow the usual capitalization syntax, but all HTML attributes are lowercase.
Also, set onkeydown to a function, rather than a string:
document.body.onkeydown = function(){if (e.keyCode==13) visible()};
Lastly, e is not defined. Replace it with event, and it should work.
function visible() {
document.getElementById("box").style.visibility = "visible";
document.getElementById("button").onclick = hidden;
document.body.onkeydown = function() {
if (event.keyCode == 13) hidden()
};
}
function hidden() {
document.getElementById("box").style.visibility = "hidden";
document.getElementById("button").onclick = visible;
document.body.onkeydown = function() {
if (event.keyCode == 13) visible()
};
}
#box {
visibility: hidden;
width: 200px;
height: 200px;
background: red;
}
#button {
width: 120px;
height: 50px;
background: lightblue;
}
<html>
<body onKeyDown="if(event.keyCode==13) visible()">
<div id="box"></div>
<div id="button" onclick="visible()"></div>
</body>
</html>
Related
My question in the title probably looks vague. And I sketched an example for the question:
container.onclick = () => {
alert(0);
};
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
//how can I prevent parent event by content clicked?
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>k
This is a simple example. In a real project, I can't combine these two events into one, because the first one is programmatically assigned somewhere in the bowels of my framework and it shouldn't be removed from the EventListener after clicking on content
In General, is it possible to somehow interrupt the execution of the call chain event by clicking in the DOM layers? I tried to do this:
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
e.preventDefault();
return false;
//how can I prevent parent event by content clicked?
};
But this, of course, was not successful
You should pass the event by dependency injection to the specific method (content.onclick) and then stop the propagation of it.
container.onclick = () => {
alert(0);
};
content.onclick = (e) => {
e.stopPropagation();
alert("VoilĂ , this prevent that appears alert(0) from parent element event.");
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>
For this, you can use stop propogation of js like this
<div id="container">
<div id="content" onclick="event.stopPropagation();">
</div>
</div>
So when you click on content it will not trigger container event only.
I have a div with the attribute contenteditable = true. I can activate the div content editing by double clicking the div, this is because my div is draggable, so I use the dooble click event to activate the div edition. The fact is that I want to eliminate the complete div by clicking on it and then pressing the Delete key on the keyboard. How can I do that? How can I make it so that when I write something on the div and press the delete key, the entire div will not be deleted? I only want to delete the div when the div edition is not activated, just click on the div and then hit the delete key and voila, it is deleted.
This is my HTML Code:
$(document).ready(function() {
$('.draggable').draggable({
containment: "parent"
});
$(".draggable").resizable();
$('#MyFirstDiv').click(function() {
//HERE I WANT TO PUT THE CODE TO DELETE THE DIV.
});
$("#myContainer").on("dblclick", "#MyFirstDiv", function(e) {
e.preventDefault();
$(".draggable").draggable('disable');
this.querySelector(":scope > :first-child").focus();
});
$("#myContainer").on("blur", "#MyFirstDiv", function(e) {
e.preventDefault();
$(".draggable").draggable('enable');
});
});
#myContainer {
border: 1px solid black;
height: 400px;
width: 100%;
}
#DraggableDiv {
border: 1px solid blue;
}
<!DOCTYPE html>
<html>
<head>
<title>My Delete Div</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
</head>
<body>
<div id="myContainer">
<div id="MyFirstDiv">
<div class="draggable" contenteditable="true" id="DraggableDiv">
THIS IS MY TEXT INSIDE THE DIV
</div>
</div>
</div>
</body>
</html>
Easiest way to to capture the keydown on the delete key.
$('#MyFirstDiv').click(function(e){
e.preventDefault();
});
$('#MyFirstDiv').keydown(function(e){
e.preventDefault();
if(e.keyCode == 46) {
this.remove();
}
});
You could first just make a variable: divClicked, I store the clicked state of the div
var divClicked = false;
Then in your event listener, update divClicked (it'll be a toggled button):
$("#MyFirstDiv").click(function(e) {
e.preventDefault();
divClicked = !divClicked;
}
Finally, add a delete key event listener like so:
$("#MyFirstDiv").keydown(function(e) {
e.preventDefault();
if (e.keyCode == 46) {
if (divClicked) {
$(this).remove();
} else {
alert("Click the div first then press Delete to remove it");
}
}
})
Full code:
var divClicked = false;
$("#MyFirstDiv").click(function(e) {
e.preventDefault();
divClicked = !divClicked;
}
$("#MyFirstDiv").keydown(function(e) {
e.preventDefault();
if (e.keyCode == 46) {
if (divClicked) {
$(this).remove();
} else {
alert("Click the div first then press Delete to remove it");
}
}
})
It is not advisable to use Delete while the content is being edited. You will want to ensure that the user can click the <div> element itself without editing the content.
Since the <div> is draggable, I would advise using a handle since the click event and keypress events may get capture for content editing and not for your script.
$(function() {
function disDrag(part) {
var drag = part.closest(".draggable");
drag.draggable("disable");
$(".drag-content", drag).removeAttr("contenteditable").blur();
part.toggleClass("ui-icon-locked ui-icon-unlocked");
}
function enDrag(part) {
var drag = part.closest(".draggable");
drag.draggable("enable");
$(".drag-content", drag).attr("contenteditable", true).focus();
part.toggleClass("ui-icon-locked ui-icon-unlocked");
}
function delDrag(part) {
var drag = part.closest(".draggable");
var res = confirm("Are you sure you wish to delete this item?");
if (res) {
drag.remove();
}
}
$('.draggable')
.draggable({
containment: "parent",
handle: ".ui-drag-handle",
start: function() {
$(".ui-drag-handle", this).data("selectable", false);
},
stop: function() {
$(".ui-drag-handle", this).data("selectable", true);
}
})
.resizable();
$(".ui-drag-handle")
.data("selectable", true)
.click(function(e) {
var drag = $(this).closest(".draggable");
if ($(this).data("selectable")) {
drag.toggleClass("drag-selected");
}
});
$(".btn").click(function(e) {
switch (true) {
case $(this).hasClass("ui-icon-unlocked"):
disDrag($(this));
break;
case $(this).hasClass("ui-icon-locked"):
enDrag($(this));
break;
case $(this).hasClass("ui-icon-close"):
delDrag($(this));
break;
}
});
$(document).keyup(function(e) {
if (e.which == 46 && $(".drag-selected").length) {
delDrag($(".drag-selected"));
}
});
});
#myContainer {
border: 1px solid black;
height: 400px;
width: 100%;
}
.draggable {
border: 1px solid blue;
}
.draggable.drag-selected {
border: 1px solid #0f0;
}
.center {
margin-left: 50%;
}
.right {
float: right;
}
.ui-icon.btn {
border: 1px solid #ccc;
border-radius: 3px;
margin-top: 0px;
margin-left: 1px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div id="myContainer">
<div class="draggable ui-widget" id="DraggableDiv">
<div class="ui-widget-header">
<span class="right ui-icon ui-icon-close btn" title="Delete the item."></span>
<span class="right ui-icon ui-icon-unlocked btn" title="Lock and disable Drag"></span>
<div class="ui-drag-handle" style="width: calc(100% - 42px);">
<span class="center ui-icon ui-icon-grip-dotted-horizontal"></span>
</div>
</div>
<div class="drag-content" contenteditable="true">
THIS IS MY TEXT INSIDE THE DIV
</div>
</div>
</div>
You can see that this is draggable, resizable, and editable. The user can disable drag by clicking the lock icon. If the select the div and click Delete (or key code 46), or they click the close icon, they will be prompted to confirm that they want to delete the item. Once they confirm that Yes they want to, the item is removed.
Since the delete could be triggered by two different ways, I created a delete function.
In regards to structure, you may not be able to get away with such simple HTML structures when dealing with more complex UI interactions. This one <div> element had all sorts of interactions tied to the click event. The user clicks to edit, select, drag... It is better to make more specific targets for some of these events so that you can better script your events.
You could save yourself a lot of time by using Dialog Widget: https://jqueryui.com/dialog/
Hope that helps.
Test
Click on the text to select.
Press D to delete. [sadly delete key didn't work on stack overflow. Simply change the key code in the if statement to change the key from D to DELETE]
Explanation
There are two functions that help solve this problem.Select: Selected the div clicked.EventListener:Listens for the keypress and deletes the selected div.
Select function
Global variable selected stores the information on the div selected.
In select function we are fetching the id name of the div clicked by using currentTarget.id from the event object 'e'.
If statements inside the select function select and deselect the div.
EventListener
Uses event object from the keypress listener to fetch the key pressed.
e.keyCode gives the key. e.which is a fallback. [for ie users]
If they keyCode is 100 (D key), then use the selected variable to get the selected div and change its css display to 'none'.
Additionally there is a else statement, where u can add js to when nothing is selected and the key is pressed.Also the css for class selected is for feedback of when the div is selected.
Here is the code snippet:
let selected;
const select = e => {
//If already selected, this will deselect the div
if(selected == e.currentTarget.id) {
document.getElementById(selected).classList.remove('selected'); //some CSS
selected = null;
} else {
//select this div
selected = e.currentTarget.id;
document.getElementById(selected).classList.add('selected'); //some CSS
}
}
window.addEventListener('keypress', e => {
//Get key pressed
let key = e.keyCode || e.which;
if(selected != undefined) {
if(key == 100) {//If D is pressed
let target = document.getElementById(selected); //get the div
target.style.display = 'none'; //hide div
console.log('deleted: ' + selected);
}
} else {
//Runs if nothing is selected. Do as you please here.
}
})
.selected {
background: black;
color: white;
}
#DraggableDiv {
user-select: none;
cursor: pointer;
font-family: sans-serif;
width: 400px;
text-align: center;
padding: 10px 5px;
}
<!DOCTYPE html>
<html>
<head>
<title>My Delete Div</title>
</head>
<body>
<div id="myContainer">
<div id="MyFirstDiv">
<div id="DraggableDiv" onclick="select(event)">
Click me and press D
</div>
</div>
</div>
</body>
</html>
I have a div that displays a little popup menu when clicked. I want users to be able to click anywhere in the body of the site to close the popup, but when I add code for that, the popup cant be opened at all anymore.
So I tried adding an if-statement so that the closemenu() function will only try close the popup if its already open, but it seems like the statement is evaluating to false even if the popup is open.
Here is the HTML for showing the popup:
<div class="popcolor" onclick="showmenu()"> Click!
<span class="popupcolor" id="myPopup">Pop!</span>
</div>
Here is the css:
.popcolor .show {
visibility: visible;
-webkit-animation: fadeIn 0.5s;
animation: fadeIn 0.5s;
}
Here is the Javascript:
function showmenu() {
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
function closemenu() {
var popup = document.getElementById("myPopup");
if (popup.style.visibility == "visible") {
popup.classList.toggle("close");
};
}
Here is the HTML for closing the popup:
<body onclick="closemenu()">
I've been through every post I can find on this for solutions, and I'm still stuck. Any help is appreciated.
You can use the getComputedStyle() method on the window object, to calculate the style rules that result from the classes applied to your popup element.
This gives you a reliable way of determining the values of different styling rules that result from, say, the 'close' class being applied to popup
Something along the lines of this should work for you:
function closemenu() {
var popup = document.getElementById("myPopup");
// Get the computed style, that is the combination of styles
// resulting from your CSS classlist, etc
var computedStyle = window.getComputedStyle(popup, null);
// Get visibility value from computed styles
var visiblityValue = computedStyle.getPropertyValue("visibility")
if (visiblityValue == "visible") {
popup.classList.toggle("show"); // Correct this from "close" to "show"
};
}
There are also some other functional issues with your implementation which are causing problems. Consider updating your showmenu() method to:
function showmenu(event) {
// Prevent event propagation, which would cause closemenu to call
// after this method is called
event.stopPropagation()
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
For more information on getComputedStyle(), see the MDN documentation
Problem here is that click event triggered from div bubbles up to body which eventually closes the popup.
function showmenu(e) {
e.stopPropagation();
console.log('toggle');
document.getElementById("myPopup").classList.toggle("close");
}
function closemenu(e) {
e.stopPropagation();
console.log('hide');
document.getElementById("myPopup").classList.add("close");
}
#myPopup.close {
visibility: hidden;
}
body {
border: 1px solid #ccc;
padding: 2rem;
}
<body onclick="closemenu(event)">
<div class="popcolor" onclick="showmenu(event)"> Click!
<span class="popupcolor close" id="myPopup">Pop!</span>
</div>
</body>
P.S. Use event.stopPropagation() to cancel/consume event
Because the visibility property is being set at the class level, the style information isn't available in the style property of your element. Maybe instead of checking for a specific style, you can check to see if the 'show' class is currently assigned to your element like so:
function closemenu() {
var popup = document.getElementById("myPopup");
if (popup.classList.contains("show")) {
popup.classList.toggle("close");
};
}
Problem in your code is with the use of JavaScript functions.
Try this simple example I took from W3Schools and enhanced it for your case.
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_add_class
There seems to be some issue with W3CSchool TryIt Editor page. Here is the link to JSBin for the same code: https://jsbin.com/xefolinape/edit?html,output
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.mystyle {
width: 100%;
padding: 25px;
background-color: coral;
color: white;
font-size: 25px;
box-sizing: border-box;
}
</style>
</head>
<body>
<p>Click the "Try it" button to add the "mystyle" class to the DIV element:</p>
<button onclick="myFunction()">Try it</button>
<button onclick="myFunctionClose()">Close it</button>
<script>
function myFunction() {
var element = document.getElementById("myDIV");
element.classList.add("mystyle");
}
function myFunctionClose() {
var element = document.getElementById("myDIV");
element.classList.remove("mystyle");
}
</script>
</body>
</html>
Hope this helps!
I have the following code that detects if a user is hovering over a box:
var toolTipHover = false;
$('#chartTooltip').on('mouseover', function () {
toolTipHover = true;
}).on('mouseout', function () {
toolTipHover = false;
});
$('.box').on('mouseover', function () {
$('#chartTooltip').show();
}).on('mouseout', function () {
console.log(toolTipHover);
if (!toolTipHover) {
$('#chartTooltip').hide();
}
toolTipHover = false;
});
And if they are then it shows the #chartTooltip element. (The tooltip is positioned and populated via some other means.)
However if the user hovers the tooltip itself it causes the tooltip to disappear (because they are no longer hovering the box). So I'm trying to check if the tooltip is being hovered (i.e. the next element hovered). and if so then ignore the mouseout event.
But toolTipHover is always false. I presume due to a race exception where mouseout has completed before the mouseover for the #chartTooltip can return the variable value of true.
How can I get around this?
I'm going to assume #chartToolTip is outside of .box for this. Instead of a flag variable (toolTipHover), just check the mouseleave event toElement property. So for example:
$('.box').on('mouseleave', function(e){
if (!$(e.toElement).is('.tooltip')){
$('.tooltip').hide();
}
})
Here is an example: https://jsfiddle.net/qvqafyf2/
$('.tooltip').hide();
$('.box').on('mouseover', function(e){
$('.tooltip').show();
})
$('.box').on('mouseleave', function(e){
if (!$(e.toElement).is('.tooltip')){
$('.tooltip').hide();
}
})
$('.tooltip').on('mouseleave', function(e){
if (!$(e.toElement).is('.box')){
$(this).hide();
}
})
.box{
width: 200px;
height: 200px;
background: red;
}
.tooltip{
height: 50px;
width: 50px;
background: green;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
</div>
<div class="tooltip">
hi
</div>
You could add #chartTooltip with .box in your function like this:
$('.box , #chartTooltip').on('mouseover', function()
here is fiddle
I am Trying to use jQuery.one() to disable a button that shows an image of a tree after it is clicked. The showImage function works fine, but not .one.
Can I not use javascript inside of a jquery event handler?
html:
<div class="grove">
<button id="plant" onclick="showImage()">Plant Orange Tree</button>
</div>
<div id="orange-tree-template">
<div class="orange-tree">
<h2>Tree Name</h2>
<h3>etc...</h3>
css:
.display-tree-big{
background: url('../images/tree_big.jpg');
background-repeat: no-repeat;
height:1000px;
width:1000px;
border: solid black 2px;
}
#orange-tree-template { visibility: hidden; }
javascript
function showImage() {
var img = document.getElementById('orange-tree-template');
img.style.visibility = 'visible';
}
$(document).ready(function() {
$("#plant").one( "click", function() {
document.getElementById("#plant").disabled = true;
});
});
A couple of issues.
You have an inline onclick handler assigned to the button. This will not respect the jQuery.one method, so because of error 2 you could continue to click the button and showImage will be called.
The function assigned to the click event via jQuery.one() is being called, however the statement document.getElementById("#plant") should not contain #, thus the button was not disabled.
jQuery(function($) {
$("#plant").one("click", function() {
// yes of course you can use JavaScript
document.getElementById('orange-tree-template').style.visibility = 'visible';
this.disabled = true;
});
});
#orange-tree-template {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<button id="plant">Plant Orange Tree</button>
<div id="orange-tree-template">
TEST
</div>
Also the jQuery.one() method does not disable anything, it just executes a callback at most once per element per event type.