javascript element body.onclick attatch event setTimeout - javascript

I want to make popup div that disappears when i click outside of it. I need pure js, not a jQuery or something.
So i do the following...
function that make div to dissapear:
function closePopUps(){
if(document.getElementById('contact-details-div'))
document.getElementById('contact-details-div').style.display = 'none';
//...same code further...
}
function closePopUpsBody(e){
//finding current target - http://www.quirksmode.org/js/events_properties.html#target
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
//is we inside div?
while (targ.parentNode) {
//filtering "Close" button inside div
if (targ.className && targ.className == 'closebtn')
break;
if (targ.className && targ.className == 'contact-profile-popup')
break;
targ = targ.parentNode;
}
//if it not a div, or close button, hide all divs and remove event handler
if ((targ.className && targ.className == 'closebtn')
|| !(targ.className && targ.className == 'contact-profile-popup')) {
if(document.getElementById('contact-details-div'))
document.getElementById('contact-details-div').style.display = 'none';
//...some more code here...
document.body.onclick = null;
}
}
maybe this code is ugly, but this not a main problem...
main problem is when i attach an event to body, it executes immediately! and div dissapears immediately, i even don't see it.
<tr onclick="
closePopUps();
document.getElementById('contact-details-div').style.display='block';
document.body.onclick = closePopUpsBody;
return false;">
i though if i don't use parentheses, it will not executes?
document.body.onclick = closePopUpsBody(); //this executes
document.body.onclick = function(){closePopUpsBody()}; //this is not
document.body.onclick = closePopUpsBody; //this is not
finally i finished with this decision
<tr onclick="
closePopUps();
document.getElementById('contact-details-div').style.display='block';
setTimeout('document.body.onclick = closePopUpsBody;', 500);
return false;">
but i think this is madness. so, what i am doing wrong?

You should stop event bubbling. Simple [demo]
var box = document.getElementById('box');
var close = document.getElementById('close');
// click on a box does nothing
box.onclick = function (e) {
e = e || window.event;
e.cancelBubble = true;
if (e.stopPropagation)
e.stopPropagation();
}
// click everywhere else closes the box
function close_box() {
if (box) box.style.display = "none";
}
close.onclick = document.onclick = close_box;

Usually events are propagated to the parents. If you click on a <div>, then <body> also will have its onClick called.
The first thing is: debug the order of called functions: place window.dump("I am called!") kind of things in your handlers.
I suppose you need to call event.stopPropagation() somewhere in your code. (See https://developer.mozilla.org/en/DOM/event )
About the parentheses question:
document.body.onclick = closePopUpsBody;//this is not
document.body.onclick = closePopUpsBody();//this executes
This executes, because you are calling a function closePopUpsBody() to return a value which will be assigned to the onclick property. In JavaScript the function name represents the function object (as any other variable). If you place parentheses after a variable name, then you say: 'execute it for me, as a function`.

Here 's a full example of how you could accomplish that.
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
<style>
body { font-family: Tahoma; font-size: 1.1em; background: #666666; color: White; }
#layer01 { border: 1px solid black; width: 200px; height: 100px; position: absolute;
top: 100px; left: 100px; background: white; padding: 10px; color: Black;
display: block; }
</style>
</head>
<body>
Click anywhere outside the layer to hide it.
<div id="layer01"> Test Layer </div>
<script type="text/javascript">
isIE = (window.ActiveXObject) ? true : false;
document.onclick = function (e) {
var l = document.getElementById("layer01");
if (!isIE && e.originalTarget == l)
e.stopPropagation();
else if (isIE && event.srcElement == l)
event.cancelBubble = true;
else
l.style.display = "none";
}
</script>
</body>
</html>

Related

how to show the sub elements text based on div>a like the select>option structure in a drop-down box using original javascript

everyone. I got some problems when I wanna accomplish a drop-down box in a HTML website without using select and option elements, instead of using and elements.
The main function is made up by two parts, the first function is when clicked the first elements in the drop-down box, the hidden parts of list shows up and hide clicked again. The second function is when choose the elements in the hidden list, the text of the elements on the list will replace the first element on the drop-down box.
I have accomplished first function using below codes:
// javascript codes
var searchListBtn = document.getElementById("btn_List");
var a_searchListBtn = document.getElementById("btn_List").getElementsByTagName("a");
function show(event) {
let oevent = event || window.event;
if (document.all) {
oevent.cancelBubble = true;
}
else {
oevent.stopPropagation();
}
// click it to show it, click again to hide it and loop
if (searchListBtn.style.display === "none" || searchListBtn.style.display === "") {
searchListBtn.style.display = "block";
}
else {
searchListBtn.style.display = "none";
}
}
document.onclick = function() {
searchListBtn.style.display = "none";
}
searchListBtn.onclick = function (event) {
let oevent = event || window.event;
oevent.stopPropagation();
}
<!-- html codes -->
<html>
<body>
<div>
<div class="ui-search-selected" onclick="show();">A</div>
<div class="ui-search-selected-list" id="btn_List">
B
C
D
</div>
</div>
</body>
</html>
But when I did the second part, my idea was not clear enough to implement that, I searched if I use select>option elements I could use selectedIndex method to find the index of list, but this is a custom drop-down box formed by div>a structure elements.
I tried to console.log(a_searchListBtn) and show an array from the console, and I could use a_searchListBtn[0~3].text to get the value of B/C/D.
I tried to write codes like below:
a_searchListBtn.onclick = function() {
console.log("Clicked.")
}
But nothing in the console, so, is there anyone could apply some help, thx in advance.
Well you're fetching all the a elements using getElementsByTagName("a"). Now you just need to loop through the results and add a click event listener that will take the innerHTML of that a element and put it into the innerHTML of the ui-search-selected div.
You don't need an index. You can access the clicked element's innerHTML using event.target. See it working in this snippet below:
// javascript codes
var searchListBtn = document.getElementById("btn_List");
var uiSearchSelected = document.getElementById("ui-search-selected");
var a_searchListBtn = document.getElementById("btn_List").getElementsByTagName("a");
for (button of a_searchListBtn) {
button.addEventListener("click", replace);
}
function show(event) {
let oevent = event || window.event;
if (document.all) {
oevent.cancelBubble = true;
}
else {
oevent.stopPropagation();
}
// click it to show it, click again to hide it and loop
if (searchListBtn.style.display === "none" || searchListBtn.style.display === "") {
searchListBtn.style.display = "block";
}
else {
searchListBtn.style.display = "none";
}
}
document.onclick = function() {
searchListBtn.style.display = "none";
}
searchListBtn.onclick = function (event) {
let oevent = event || window.event;
oevent.stopPropagation();
}
function replace(event) {
if (!event) return;
uiSearchSelected.innerHTML = event.target.innerHTML
}
<!-- html codes -->
<html>
<body>
<div>
<div id="ui-search-selected" onclick="show();">A</div>
<div class="ui-search-selected-list" id="btn_List">
B
C
D
</div>
</div>
</body>
</html>
I have tried to use this codes to implement this funtion, it works.
// javascript
var par_searchListBtn = document.getElementById("btn_list_parent");
var searchListBtn = document.getElementById("btn_List");
var a_searchListBtn = document.getElementById("btn_List").getElementsByTagName("a");
// console.log(a_searchListBtn.length);
// console.log(a_searchListBtn);
function show(event) {
let oevent = event || window.event;
if (document.all) {
oevent.cancelBubble = true;
}
else {
oevent.stopPropagation();
}
if (searchListBtn.style.display === "none" || searchListBtn.style.display === "") {
searchListBtn.style.display = "block";
}
else {
searchListBtn.style.display = "none";
}
}
document.onclick = function() {
searchListBtn.style.display = "none";
}
searchListBtn.onclick = function (event) {
let oevent = event || window.event;
oevent.stopPropagation();
}
for(var i = 0; i < a_searchListBtn.length; i++){
a_searchListBtn[i].onclick = function () {
par_searchListBtn.innerHTML = this.innerText;
//searchListBtn.style.display = "none";
}
}
<!-- html codes -->
<html>
<body>
<div>
<div class="ui-search-selected" id="btn_list_parent" onclick="show();">A</div>
<div class="ui-search-selected-list" id="btn_List">
B
C
D
</div>
</div>
</body>
</html>

How to remove all children of contenteditable element?

I need to delete all children of a div after clicking enter.
There is a div and event listener below.
<div id = "area" contenteditable="true"></div>
document.onreadystatechange = function(){
if(document.readyState == 'complete'){
document.getElementById("area").addEventListener("keypress" , public_mode);
}
function public_mode(){
var key = window.event.keyCode;
if (key == 13) {
sendMessage();
}
}
function sendMessage(){
var area = document.getElementById("area");
while (area.firstChild) {
area.removeChild(area.firstChild);
}
}
As you can see the contenteditable elements is added an element in according with clicking enter - it depends on browser what element will be added.In my case I use chrome and here are inserted div.
So, the result after clicking enter on the area but without removing
<div id = "area" contenteditable = "true">
Sckoriy
<div></div>
</div>
and , with removing
<div id = "area" contenteditable = "true">
<div></div>
<div></div>
</div>
But , the needed result is
<div id = "area" contenteditable = "true">
//Empty
</div>
The code mostly works, however there were two main issues.
keyCode is deprecated. you should be using key which turns the syntax of searching for a key into looking for a string. This means instead of 13 you just check to see if key is Enter.
Secondly you need to pass the event to your public_mode function so that you can read the key that has been pressed when the event occurs. You also need to use preventDefault to prevent it from adding a new line after removing everything from the original contentEditable area when it does detect Enter
document.onreadystatechange = function() {
if (document.readyState == 'complete') {
document.getElementById("area").addEventListener("keypress", public_mode);
}
function public_mode(event) {
var key = event.key;
if (key === "Enter") {
event.preventDefault();
sendMessage();
}
}
function sendMessage() {
var area = document.getElementById("area");
while (area.firstChild) area.removeChild(area.firstChild);
}
}
#area {
min-width: 100vw;
border: 1px solid black;
}
<div id="area" contenteditable="true"></div>
You could just set the innerHTML proprety to an empty string;
area.innerHTML = '';
target the dom by id
var s = document.getElementById("area");
save the number of childrens
var num = s.children.length;
and remove the num of childs of element
for(var i=0;i<num;i++){
s.children[0].remove()
}
and inner for some thext
s.innerHTML = "";
Pass the key event as an argument to your function.
Also, if you do not want the newline entered in your div, you can prevent the event from continuing with event.preventDefault().
document.onreadystatechange = function() {
if (document.readyState == 'complete') {
const area = document.getElementById('area')
area.addEventListener('keypress', public_mode);
area.focus();
}
}
function public_mode(event) {
if (window.event.keyCode == 13) {
sendMessage();
event.preventDefault();
}
}
function sendMessage() {
const area = document.getElementById('area');
while (area.firstChild) {
area.removeChild(area.firstChild);
}
}
<div id="area" contenteditable="true">Press Enter to erase me!</div>

Javascript -- how to click anywhere on page to hide opened div

I have a javascript that opens up a hidden div:
<script>
function dropdown()
{ document.getElementById("login_dropdown").style.display="block"; }
</script>
The html is:
<div onclick="dropdown()">
<div id="login_dropdown">STUFF</div>
</div>
The CSS is:
<style>
#login_dropdown {
width: 150px;
display:none;
}</style>
Using javascript alone, how can I hide this div when I click anywhere else on the page, excluding the opened DIV itself.
Something like this with vanilljs
document.addEventListener('click', function(event){
const yourContainer = document.querySelector('....');
if(!yourContainer.contains(event.target)) {
//hide things classes.. yourContainer.classList.add('hidden');
}
});
You could do this
var elem = document.getElementById("login_dropdown");
(document.body || document.documentElement).addEventListener('click', function (event) {
// If the element on which the click event occurs is not the dropdown, then hide it
if (event.target !== elem)
elem.style.display="none";
}, false);
function closest(e, t){
return !e? false : e === t ? true : closest(e.parentNode, t);
}
container = document.getElementById("popup");
open = document.getElementById("open");
open.addEventListener("click", function(e) {
container.style.display = "block";
open.disabled = true;
e.stopPropagation();
});
document.body.addEventListener("click", function(e) {
if (!closest(e.target, container)) {
container.style.display = "none";
open.disabled = false;
}
});
#popup {
border: 1px solid #ccc;
padding: 5px;
display: none;
width: 200px;
}
<div id="container">
<button id="open">open</button>
<div id="popup">PopUp</div>
</div>
Something like this:
$("document").mouseup(function(e)
{
var subject = $("#login_dropdown");
if(e.target.id != subject.attr('id'))
{
subject.css('display', 'none');
}
});
works like this. When you click anywhere on the page, the handler fires and compares the ID of the open tab vs the id of the document (which there is none) - so it closes the tab. However, if you click the tab, the handler fires, checks the ID, sees the target is the same and fails the test (thus not closing the tab).

Javascript to trigger one function only if two events are both true

Say I want to activate myFunction only if the user has pressed the paragraph with a key and clicks on it. In the case below, the function will get triggered if any of the events is true.
<p id="p1" onClick="myFunction()" onKeyDown="myFunction()">
Text awaiting to be colored in red</p>
<script>
function myFunction(){
document.getElementById("p1").style.color = "red";
}
</script>
You need one extra variable isKeyDown, and isKeyDown should be set to true on keydown, and set to false on keyup.
And than in click callback check is isKeyDown true, call myFunction.
An example of how you could do it. This works with Enter and normally clicking it. Really you don't need to make p focus but I thought it was neat, even though you can still handle the key events from the document and since the click only registers on p there's nothing to worry about.
var p = document.getElementById('p1');
p.addEventListener('mousedown', function(e) {
p.clicked = true;
checkEvents(p);
});
p.addEventListener('mouseup', function(e) {
p.clicked = false;
});
p.addEventListener('keydown', function(e) {
if (e.keyCode === 13) {
p.enterDown = true;
}
});
p.addEventListener('keyup', function(e) {
checkEvents(p);
if (e.keyCode === 13) {
p.enterDown = false;
}
});
function checkEvents(el){
if(el.enterDown && el.clicked){
el.style.backgroundColor = 'red';
}
}
p:focus {
outline: none;
}
<p id="p1" tabindex='0'>
Text awaiting to be colored in red</p>
You'll need to breakdown into two methods. First is keystrokes->click and then click->keystrokes. I'm not sure if this is achievable on pure/vanilla javascaript. But on jquery it goes something like:
$('#p1' ).keydown(function() {
if($('#p1').click()) {
document.getElementById("p1").style.color = "red";
}
});
$('#p1')click(function () {
if($('#p1').keydown()) {
document.getElementById("p1").style.color = "red";
}
});

When Listening to Ctrl + B event, Bookmark tab shows up

I am trying to implement Ctrl+B for a contenteditable div which should make the text bold.
The only problem I'm getting is that when Ctrl+B is pressed, browser's bookmark tab appears.
(fiddle)
$(document).ready(function() {
$('#editable').designMode = 'on';
$('#editable').on('keyup', function(e) {
console.log(e.which);
if(e.which == 66 && e.ctrlKey) {
e.preventDefault();
console.log('bold');
document.execCommand ('bold', false, null);
return false;
}
});
});
#editable {
width:200px;
height:100px;
border:1px solid #999;
border-radius: 3px;
padding: 10px;
box-sizing:border-box;
}
#editable:focus {
outline: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div contenteditable="true" id="editable"></div>
Please help me find a way to disable that bookmark when I'm focussed inside that editable div.
check this solution
jsFiddle
var g_state = 0;
$(document).ready(function() {
$('body').keydown( function ( eve ) {
if (eve.which === 17) {
eve.preventDefault();
g_state = 1;
}
return true;
});
$('body').keyup( function ( eve ){
if (eve.which === 17) {
eve.preventDefault();
g_state = 0;
}
return true;
});
$('body').keypress( function ( eve ) {
eve.preventDefault();
if (eve.ctrlKey && (eve.which === 78)) {
alert("(eve.ctrl + 'n')");
}
else {
if (g_state && (eve.which === 78)) {
alert("(ctrl tracking by key up/down + 'n', resetting)");
g_state = 0;
}
else {
if (eve.shiftKey && (eve.which === 78)) {
alert("(eve.shift + 'n')");
}
else {
alert("pass");
}
}
}
});
});
Hi Dangling Cruze,
Here there is no any rocket science , What we are doing here is to Prevent the event bubing. And stopping event to reach at web browser.
The preventDefault() method cancels the event if it is cancel-able, meaning that the default action that belongs to the event will not occur.
In single term
For example, this can be useful when:
Clicking on a "Submit" button, prevent it from submitting a form
Clicking on a link, prevent the link from following the URL
At the document level we are binding all main three event
keydown
keyup
keypress
and identifying key combination as well to prevent some key combination that is being used by browser as well.
let me know if you require any further help

Categories