Is it possible to make a contenteditable paragraph focused with a button.
I've tried making the paragraph focused (like you would with an input), but it doesn't work. Like this:
document.getElementById("example").focus();
This is an example of what it should look like (I used input for this example):
https://jsfiddle.net/7rwft2c3/
The element you would like to focus must be editable first. According to the spec, you can only .focus() on a focusable area.
The spec says:
The term focusable area is used to refer to regions of the interface
that can become the target of keyboard input.
Here: https://html.spec.whatwg.org/multipage/interaction.html#focusable-area
So add the contentEditable attribute first, and then .focus() the element.
Per the comment below, .blur() is not necessary because once the contentediable attribute is removed, the element can no longer be focused.
Note here I changed the <input> to a <div>:
const el = document.getElementById("myText");
function getFocus() {
el.setAttribute('contenteditable', 'true');
el.focus();
}
function loseFocus() {
el.removeAttribute('contenteditable');
}
<div id="myText">A Div</div>
<button type="button" onclick="getFocus()">Get focus</button>
<button type="button" onclick="loseFocus()">Lose focus</button>
Related
So, I have two contenteditable divs nested inside of another:
<div class="top" contenteditable="true">
<div class="nested" contenteditable="true">This</div>
</div>
Here is Fiddle.
When it is focused, nested should be focused but using console.log(document.activeElement); it shows that the top is focused and it doesn't recognize the nested div.
In a case where content is being edited, I need to recognize nested div element instead of the top element.
How would I achieve this? Any help will be much appreciated.
The way [contenteditable] elements are handled by browser made any nested [contenteditable] not handling any event, the editing host is the former editable parent. See spec:
If an element is editable and its parent element is not, or if an
element is editable and it has no parent element, then the element is
an editing host. Editable elements can be nested. User agents must
make editing hosts focusable (which typically means they enter the tab
order). An editing host can contain non-editable sections, these are
handled as described below. An editing host can contain non-editable sections that contain further editing hosts.
Now as a workaround, you could make focused nested editable element the hosting host by setting any of its editable parent temporaly not editable. See e.g:
$('div.top [contenteditable]').on('focusin focusout', function(e) {
$(this).parents('[contenteditable]').prop('contenteditable', e.type === "focusout");
});
-updated jsFiddle-
Give tabindex=-1 to the nested div, than can be focused:
.nested {
display: inline;
background-color: #eef;
}
<div class="top" contenteditable="true">
Editable div <div class="nested" tabindex=-1>Nested div</div>
</div>
Notes:
contenteditable is inherited, so there is no need to specify it again.
it only works with mouse focus. Moving the caret (cursor left/right) over the nested div, will not focus the nested div. Similarily, leaving a focused nested div with the caret, will not does not give the focus back to the parent div. Handling might need work arounds with keydown listener, range and selection.
For nested contentEditable elements, focus shall be only triggered in the top ancestor.
You could use selection to get the closest element where the caret is right in:
function getCEOfCaret(){
const selection = window.getSelection()
const range = selection.getRangeAt(0)
const start = range.startContainer;
let startElement;
if(start.nodeType === 1) startElement = start;
else startElement = start.parentElement;
return startElement.closest('[contenteditable="true"]')
}
console.log(getCEOfCaret())
I’m newbie in JavaScript. Here’s my code below.
Upon clicking a button, I understand why event.target returns span object (because that’s the innermost element I click. correct?).
My doubt is, going by same logic why document.activeElement returns button object and not span object? Isn't it the span element that should be active when I click the button or not?!
Thanks in advance for your clarifications :=)
<!DOCTYPE html>
<head>
<script type="text/javascript">
function GetActive () {
if (document.activeElement) {
var output = document.getElementById ("output");
output.innerHTML = document.activeElement + ’-’ + event.target
}
}
</script>
</head>
<body onclick="GetActive ();">
Click anywhere on the page to get the active element <input id="myInput" value="input field" />
<button> <span>Sample button</span> </button>
<div id="output"></div>
</body>
This happens because document.activeElement reports the element which is currently focused (or will receive keystrokes).
Returns the currently focused element, that is, the element that will get keystroke events if the user types any. This attribute is read only.
Since elements like span and div can't receive keystrokes or be focused on (by tabbing to them) ordinarily, they won't ever be the activeElement. Those tags will be the activeElement only when they can receive keystrokes or be "active", such as when you've made them contenteditable or given them a tabindex.
Demo
Is it possible to select all the text an an element (e.g., a paragraph <p>) with JavaScript? A lot of people think jQuery .select() would do this, but it does not. It merely triggers an event. Note that DOM objects for <input> elements have a native select() method, but most other elements (such as <output> and <p>) do not.
(Do I need to use content-editable to get this to work?)
If you need to support later browsers, i.e., IE9+, you can use the following
document.querySelector('button').addEventListener('click', function(){
var range = document.createRange();
var selection = window.getSelection();
range.selectNodeContents(document.querySelector('p'));
selection.removeAllRanges();
selection.addRange(range);
});
Hello <p>Select me</p> World
<button id ='btn'>Select text</button>
Related links:
The spec: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level2-Range-method-selectNodeContents
http://help.dottoro.com/ljcpcpnt.php
https://developer.mozilla.org/en-US/docs/Web/API/range.selectNodeContents
https://developer.mozilla.org/en-US/docs/Web/API/Selection.addRange
For support across all browsers, see https://github.com/timdown/rangy from https://stackoverflow.com/users/96100/tim-down
select() Will only work on <input> and <textarea> elements...
Also yes, you will have to use:
contenteditable="true"
And use .focus() to select all the text.
Try this:
<p id="editable" contenteditable="true"
onfocus="document.execCommand('selectAll',false,null);">Your Text Here</p>
<button onclick="document.getElementById('editable').focus();" >Click me</button>
JSFiddle Demo
I have the following:
<div class="tab-pane" id="message">
<textarea rows="4" cols="50" id="send_message" placeholder="Enter text ..."> </textarea>
OK
Cancel
I want to bind the click method to the 'div' element , and when one of the child 'a' elements is clicked do separate things. I am trying to distinguish between them using the button text, but the following is not working:
$(function(){
$('#message').click(function(){
if($(this + ">a").is(":contains(OK)")) {
console.log("OK!!");
How can I fix this?
Okay there are two ways of doing this:
.find(selector)
if(this).find("a").is(":contains(OK)")) {
console.log("OK!!");
OR
$(selector,context)
if("a",this).is(":contains(OK)")) {
console.log("OK!!");
In javascript, this is essentially the context of the current function. In jQuery event callbacks, this is set to be the source element of the event - not the selector string, which is what you are treating it as.
Instead, you want to do a test like: if($("a", this).is(":contains(OK)")) {
This works because the second parameter to the jQuery selector is the context to search in, so you are only searching for the a tags under the source element of the click.
Binding the click element to the Div, then checking the text string of the A tags will make both events happen on every click. You want to bind 2 separate click events on each A tag. Add an ID to each A tag, then try this code
$('#okLinkID').click(function(){
console.log("OK!!");
});
$('#cancelLinkID').click(function(){
console.log("Cancel!!");
});
//Attaches only one listener to the #message div and listens for any 'a' element within it to be clicked.
$('a','#message').on('click',function(){
var $this = $(this),
btnText = $this.text();
console.log(btnText);
});
http://jsfiddle.net/YA7Ds/
An HTML webpage is rendered in div. How can I allow the user to click and select any HTML tag? Similar to how Firebug and Chrome does it. I need the selected tag returned as is.
Add an event listener on your div and check for the event's target property (srcElement for IE).
document.getElementById("page").onclick = function(e) {
var target = e.target || e.srcElement;
alert(e.target.tagName);
};
http://jsfiddle.net/Xeon06/e67qW/1/
In jQuery:
$.click( function(){
var clicked = $(this);
});
you can add a onclick attribute to each html element which returns itself.
Chrome and Firefox also have a hover which outlines the element tough. To make that in a easy (and ugly) way you could add a hover css pseudo class for the html elements which adds a border of 1px to the html element.
*:hover{
border: 1px solid;
}
A better way would be to create a new element with javascript with the same measurements and position and to give it a z-index so it floats above the existing element