contentEditable is false only when clicked on the element - javascript

I have a div and it has some elements inside it. What I want to achieve is when a user double clicks an element inside the div, it sets itself as contentEditable. For example: if a user double clicks on a p tag, it becomes editable and as soon as he clicks anywhere outside that tag, it sets contentEditable to false
But what's happening is that when I double click the p tag, it does becomes editable but when I click anywhere outside that element, it doesn't set itself to false and it only sets itself to false when I click on the same p tag again. Which is very strange. What am I doing wrong here?
Here's my code:
<html>
<body>
<div id="zzz">
<h1>Welcome</h1>
<p>this is the text</p>
<button>click me</button>
<u>yo</u>
</div>
</body>
<script>
let arr = [];
let myiframe = document.getElementById("zzz");
myiframe.addEventListener("click", function (e) {
obj = e.target;
arr.push(obj);
console.log(arr);
if (arr.length > 2) {
arr.shift();
}
if (arr[0] == arr[1]) {
console.log("same");
} else {
console.log("different");
obj.contentEditable = "false";
}
if (event.detail === 2) {
obj.contentEditable = "true";
obj.focus();
}
});
</script>
</html>

I think you only need to store a single element in memory, which is the last editable element. I used .setAttribute and got it working
let arr = [];
let myiframe = document.getElementById("zzz");
let activeElement = null
myiframe.addEventListener("click", function(e) {
obj = e.target;
//console.log(activeElement)
if (activeElement && activeElement !== obj) {
activeElement.setAttribute('contenteditable', 'false');
}
if (event.detail === 2) {
obj.setAttribute('contenteditable', 'true');
activeElement = obj
obj.focus();
}
});
<div id="zzz">
<h1>Welcome</h1>
<p>this is the text</p>
<button>click me</button>
<u>yo</u>
</div>

If you change obj.contentEditable = "false"; to arr[0].contentEditable = "false" then upon a click it would check if the elements match and if they don't it would disable the elements property.

e.target is the element you clicked on, so when you click on an element and modify obj.contentEditable you’re only ever modifying that element’s contentEditable property.

Related

Attached event listener on mouseover

I'm very new to Javascript and is trying to attach an anonymous function to an event listener. What the function does is that when mouseover the first element, a message will be displayed in the second element depending on the length of the text within the first element.
However, when I hover my mouse over the first element, nothing happens. Because I'm new to JavaScript, I'm not sure what I did wrong.
function checkLength(event, minLength){
var el, elementTwo;
el = event.target;
elementTwo = el.nextSibling;
if(el.value.length < minLength){
elementTwo.innerHTML = "not enough";
} else {
elementTwo.innerHTML = "enough";
}
}
var elUserName = document.getElementById("one");
elUserName.addEventListener("mouseover", function(event){
checkLength(event, 5);
}, false);
<div>
<div id="one">Bob</div>
<div id="two"></div>
</div>
To access the text of the element you use textContent. value is for inputs.
Also, you need to select the next element sibling, not just the next sibling node.
function checkLength(event, minLength){
var el, elementTwo;
el = event.target;
elementTwo = el.nextElementSibling;
if(el.textContent.length < minLength){
elementTwo.innerHTML = "not enough";
} else {
elementTwo.innerHTML = "enough";
}
}
var elUserName = document.getElementById("one");
elUserName.addEventListener("mouseover", function(event){
checkLength(event, 5);
}, false);
<div>
<div id="one">Bob</div>
<div id="two"></div>
</div>

Using javascript conditions to hide elements

In this code, I have two elements; an input box with id 'alpha' and a paragraph with id 'bravo'. What I'm trying to do is make bravo invisible when there is nothing in the input box alpha.
Here is what I have so far:
<html>
<head>
<script>
var a = document.getElementById("alpha");
var b = document.getElementById("bravo");
window.onload = function hidebravo() {
if (a.value == nil) {b.style.visibility = "hidden";}
}
a.onchange = function hidebravo() {
if (a.value == nil) {b.style.visibility = "hidden";}
}
</script>
</head>
<body>
<input id="alpha"/>
<p id="bravo">Hello!</p>
</body>
</html>
For sake of clarity, I have set the variables 'a' and 'b' to correspond to the JS selectors for the input box and the paragraph, respectively.
Now, as soon as the window is loaded I call the function 'hidebravo()' which is the function that makes bravo invisible if input box alpha is empty. I call the same function whenever the user changes the value of alpha, in case alpha contains a value which the user then deletes and it becomes empty once again.
But, for whatever reason, this isn't working as it should and I can't figure out why.
Please help!
You should use null instead of nil in Javascript.
Here's the code that works, without window.onload function:
JS:
function reloadBravo() {
var bravoParagraph = document.getElementById('bravo');
var alphaTextBox = document.getElementById('alpha');
var alphaText = alphaTextBox.value;
if (alphaText.length > 0) {
bravoParagraph.innerHTML = alphaText;
bravoParagraph.style.visibility = 'visible';
} else {
bravoParagraph.innerHTML = '';
bravoParagraph.style.visibility = 'hidden';
}
}
HTML:
<html>
<head>
</head>
<body>
<input id="alpha" onkeyup="reloadBravo()"/>
<p id="bravo"></p>
</body>
</html>
This help you :
<html>
<head>
</head>
<body>
<input id="alpha"/>
<p id="bravo">Hello!</p>
<script>
var a = document.getElementById("alpha");
var b = document.getElementById("bravo");
window.onload = function hidebravo() {
if (a.value == "")
b.style.visibility = "hidden";
else
b.style.visibility = "visible";
}
a.oninput = function hidebravo() {
if (a.value == "")
b.style.visibility = "hidden";
else
b.style.visibility = "visible";
}
</script>
</body>
</html>
JavaScript doesn't have special nil value. There is null. But the .value property of the HTMLInputElement is a DOMString and can't be null. You need to check the .length property of the DOMString. length of 0 indicates that there is no set value.
if (a.value.length === 0) { ... }
Note that as an space and a tab is considered a character, you need to trim the value for checking whether user has typed any visible characters or not:
if (a.value.trim().length === 0) { ... }
But that's not the only problem. load event is fired once and your code doesn't check the current value of the inputs. You should add an event handler for keyup/input/change/paste/... events fired for the input elements.
a.addEventListener('keyup', hidebravo);
b.addEventListener('keyup', hidebravo);

Drag&Drop keep behavior of editable content

i'm experimenting with Drag&Drop in Javascript. So far it is working but my editable Content within the dragable objects aren't useable anymore (hence not the way they normally are)
this is an example of an dropable object:
<div id="ziel_2" draggable="true" trvdroptarget="true">
<div> some text<br>some text</div>
<div contenteditable="true">some text</div>
</div>
the whole object shouldn't be dragged if i try to use the contenteditable div, i want to click in the text and edit it or just select some text in it ang drag it just like normal
so the question: how can i cancel the drag-event if e.target.hasAttribute("contenteditable") in ondragstart?
EDIT: this is the Code behind the Scenes so far:
function lieferungen_draggable_add_dragstart(obj)
{
obj.addEventListener('dragstart', function (e) {
if(e.target.hasAttribute("contenteditable")) { /* make something stop this thing */ }
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('Text', this.getAttribute('id'));
return false;
});
return obj;
}
EDIT2:
contenteditableDiv.addEventListener('mousedown', function() { this.parentNode.setAttribute("draggable", false); });
contenteditableDiv.addEventListener('mouseup', function() { this.parentNode.setAttribute("draggable", true); });
this worked for me based on an idea from https://stackoverflow.com/a/9339176/4232410
thanks for your help!
Check for the contentEditable status of the element and any parent elements (see the docs for info about the attribute)
for (var el = e.target; el && el !== el.parentNode; el = el.parentNode) {
if (el.contentEditable === "true") {
return false;
}
}
// Continue processing here
Try this:
if(e.target.hasAttribute("contenteditable")) { return false; }
Basically, that's saying get out and don't do anything else if the target has attribute: contenteditable

Storing document.getElementById in a variable?

I have this script that is supposed to change the text of the button when the button is clicked.
<body>
<button onclick="toggleText(this);" id="id">Edit</button>
</body>
function toggleText(element){
var text = document.getElementById(element.id).textContent;
if (text == 'Edit') {
text = 'Done';
} else {
text = 'Edit';
}
}
But it doesn't work. It only works when you put document.getElementById(element.id).textContent directly into the if statements.
How do I get the variable to store properly?
Since you already get the element, you don't need to get it again. You can just use element.
But the reason why you can't change it is that you're only changing the variable that contains the text. It does not point to the element's properties. You need to use this:
function toggleText(element){
var text = element.textContent;
if (text == 'Edit') {
element.textContent = 'Done';
} else {
element.textContent = 'Edit';
}
}
When you access document.getElementById(element.id).textContent you get the value of it, not the reference. So changes to it won't affect the element.
But when you assign element to variable, it gets reference to it.
var element = document.getElementById(element.id);
if (element.textContent == 'Edit') {
element.textContent = 'Done';
} else {
element.textContent = 'Edit';
}
Just use:
index.js
var mainText = document.getElementById("mainText").value;
document.write(mainText);
index.html
<textarea id="mainText"></textarea>
As tymeJV commented, you can store by reference the element you get by id. Its property is stored by value. Instead store the element in a variable and access its property from the variable.
var text = document.getElementById(element.id);
if (text.textContent == 'Edit') {
text.textContent = 'Done';
} else {
text.textContent = 'Edit';
}
Is jquery an option ?
I used to do something like :
var a = $('#theid');
A.something

Javascript Detect click event outside of div [duplicate]

This question already has answers here:
How do I detect a click outside an element?
(91 answers)
Closed 1 year ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
I have a div with id="content-area", when a user clicks outside of this div, I would like to alert them to the fact that they clicked outside of it. How would I use JavaScript to solve this issue?
<div id = "outer-container">
<div id = "content-area">
Display Conents
</div>
</div>
In pure Javascript
Check out this fiddle and see if that's what you're after!
document.getElementById('outer-container').onclick = function(e) {
if(e.target != document.getElementById('content-area')) {
document.getElementById('content-area').innerHTML = 'You clicked outside.';
} else {
document.getElementById('content-area').innerHTML = 'Display Contents';
}
}
http://jsfiddle.net/DUhP6/2/
The Node.contains() method returns a Boolean value indicating whether a node is a descendant of a given node or not
You can catch events using
document.addEventListener("click", clickOutside, false);
function clickOutside(e) {
const inside = document.getElementById('content-area').contains(e.target);
}
Remember to remove the event listened in the right place
document.removeEventListener("click", clickOutside, false)
Bind the onClick-Event to an element that is outside your content area, e.g. the body. Then, inside the event, check whether the target is the content area or a direct or indirect child of the content area. If not, then alert.
I made a function that checks whether it's a child or not. It returns true if the parent of a node is the searched parent. If not, then it checks whether it actually has a parent. If not, then it returns false. If it has a parent, but it's not the searched one, that it checks whether the parent's parent is the searched parent.
function isChildOf(child, parent) {
if (child.parentNode === parent) {
return true;
} else if (child.parentNode === null) {
return false;
} else {
return isChildOf(child.parentNode, parent);
}
}
Also check out the Live Example (content-area = gray)!
I made a simple and small js library to do this for you:
It hijacks the native addEventListener, to create a outclick event and also has a setter on the prototype for .onoutclick
Basic Usage
Using outclick you can register event listeners on DOM elements to detect whether another element that was that element or another element inside it was clicked. The most common use of this is in menus.
var menu = document.getElementById('menu')
menu.onoutclick = function () {
hide(menu)
}
this can also be done using the addEventListener method
var menu = document.getElementById('menu')
menu.addEventListener('outclick', function (e) {
hide(menu)
})
Alternatively, you can also use the html attribute outclick to trigger an event. This does not handle dynamic HTML, and we have no plans to add that, yet
<div outclick="someFunc()"></div>
Have fun!
Use document.activeElement to see which of your html elements is active.
Here is a reference:
document.activeElement in MDN
$('#outer-container').on('click', function (e) {
if (e.target === this) {
alert('clicked outside');
}
});
This is for the case that you click inside the outer-container but outside of the content-area.
Here is the fiddle : http://jsfiddle.net/uQAMm/1/
$('#outercontainer:not(#contentarea)').on('click', function(event){df(event)} );
function df(evenement)
{
var xstart = $('#contentarea').offset().left;
var xend = $('#contentarea').offset().left + $('#contentarea').width();
var ystart = $('#contentarea').offset().top;
var yend = $('#contentarea').offset().top + $('#contentarea').height();
var xx = evenement.clientX;
var yy = evenement.clientY;
if ( !( ( xx >= xstart && xx <= xend ) && ( yy >= ystart && yy <= yend )) )
{
alert('out');
}
}
use jquery as its best for DOM access
$(document).click(function(e){
if($(e.target).is("#content-area") || $(e.target).closest("#content-area").length)
alert("inside content area");
else alert("you clicked out side content area");
});
Put this into your document:
<script>
document.onclick = function(e) {
if(e.target.id != 'content-area') alert('you clicked outside of content area');
}
</script>
Here is a simple eventListener that checks all parent elements if any contain the id of the element. Otherwise, the click was outside the element
html
<div id="element-id"></div>
js
const handleMouseDown = (ev) => {
let clickOutside = true
let el = ev.target
while (el.parentElement) {
if (el.id === "element-id") clickOutside = false
el = el.parentElement
}
if (clickOutside) {
// do whatever you wanna do if clicking outside
}
}
document.addEventListener("mousedown", handleMouseDown)

Categories

Resources