Clicking <span> element > JavaScript output document.activeElement VS. event.target - javascript

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

Related

Is it possible to make a contenteditable paragraph focused with a button?

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>

How to get the target element for an 'selectionchange' dom event

I find myself in a situation where I want to get the target element that triggered the selectionChange dom event.
But judging by https://developer.mozilla.org/en-US/docs/Web/Events/selectionchange, it seems that the element in e.target is always the document object in the normal (non-input, non-textarea) case.
So does that mean I will have to manually call window.getSelection, and figure out the current cursor location and find the dom node that way?
Does anyone know of a short cut? or some working example would be nice.
If your element can become an active element, use document.activeElement to get the element we're selecting inside of. This will work with textareas, inputs, and on elements whose tabindex is set.
// NOTE: activeElement can only be found on selectable elements!
document.addEventListener('selectionchange',function(){
document.getElementById('currentTag').innerHTML = document.activeElement.tagName;
});
#currentTag{
font-weight:bold;
}
<textarea>This is sample text you can replace and move your cursor within. Whee!</textarea>
<br><input type="text" placeholder="Input">
<p tabindex="0">P tag text is the best tag text. <span color="blue">Unless you have a span.</span></p>
<ol tabindex="0">
<li tabindex="0">Item 1</li>
<li tabindex="0">Item 2</li>
</ol>
<p id="currentTag"></p>
You can use document.selection to get what is currently selected.
Example taken from http://help.dottoro.com/ljixpxji.php
<head>
<script type="text/javascript">
document.onselectionchange = OnChange;
function OnChange () {
var range = document.selection.createRange ();
if (range.text.length == 0) {
alert ("The current selection is empty");
}
else {
alert ("The contents of the current selection are\n" + range.text);
}
}
</script>
</head>
<body>
Select this text on this page!
</body>
--EDIT--
As pointed out by #user1017674 this code does not work in chrome, after a little bit of research I found document.selection should only be used in IE < 9. It seems that window.getSelection() is still going to be the best way to get it.
Ref. Does chrome supports document.selection?

How to select element relative to 'this' in javascript

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/

Get id of child div within contenteditable div

<div class="pad" id="test" contenteditable="true" spellcheck="false">
<div id="a0" class="fif" > text0</div>
<div id="a1" class="fif" >text1</div>
<div id="a2" class="fif" >text2</div>
</div>
As in above code there is a contenteditable div with some child divs inside it. I need a jQuery to return the id of the child div over which I am typing. e.g. if I am editing text1 it should give me (return) "a1".
It works as desired if I use
var clicked;
$('#test').click(function(event){
clicked = $(event.target);
alert(clicked.attr('id'));
});`
as shown here
http://jsfiddle.net/bernie1227/cK69Q/ (i.e. on clicking it returns id="a1") but it doesn't work in similar manner if I use
var clicked;
$('#test').keypress(function(event){
clicked = $(event.target);
alert(clicked.attr('id'));
});
as shown here http://jsfiddle.net/hari_OM/bLgkv/ i.e. on typing it returns "id=test" and not "id=a1"
I tried using event.target.id and $(this).attr("id") but they return id="test" and not id="a1" , but I need to get "a1". I also tried injecting onkeypress="funcname(this.id)" within child divs and retriving it from defined function, but it doesn't work.
I have written a solution which relies on tracking the target of the event, using event.target:
http://jsfiddle.net/bernie1227/cK69Q/
Ever looked into this? DOMCharacterDataModified
$(document).on('DOMCharacterDataModified', function( event ) {
if($(event.target).parent().attr('id') === 'parentid') {
console.log(
'target',$(event.target),"\r"
);
}
});

Use JQuery to listen for all clicks on the html body Except a specific div and its children

I am trying to use a jQuery listener to listen for a users clicks on the html body and perform a specific function if anywhere on the body has been clicked except for a specific div and the children within that div.
The idea is that the div is a popup type element and instead of having to have a close button that the user can click, they should just be able to click anywhere on the page besides that div and it will automatically close.
I have been using this listener:
var initialClick = false;
$('body').on('click.addPhoneListeners', function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
if(target.parentNode.id != clone.id && target.id != '') {
finish();
};
}
initialClick = true;
});
Which listens for all clicks on the body and unless the click comes from within the element I want the user to be able to interact with, it closes. Unfortunately this only works with a div that has only one level of children. As soon as I start getting multiple hierarchies such as this:
<div id="addressContainer">
<div id="address" class="hidden row">
<div class="row">
<div id="address.primary" class="hidden">P</div>
<div id="address.type"></div>
<div id="address.street"></div>
<div id="address.editButton" class="hidden"><a id="addressEditButton">Edit</a></div>
<div id="address.deleteButton" class="hidden"><a id="addressDeleteButton">Delete</a></div>
</div>
<div class="row">
<div id="address.city"></div>
<div id="address.state"></div>
<div id="address.zip"></div>
</div>
<input type="hidden" id="address.id"></input>
</div>
</div>
The target.parentNode.id gives me the objects parent element as opposed to the addressContainer id and thus does not work. Is use the top level parent from within nested elements? Other elements will be using this same code, so it has to work on both divs with just one level and div's with multiple.
UPDATE: Found a few excellent solutions, thanks guys. I do however have one other question. Refer to my code above where I set an initialClick boolean to false, then set it to true. I am doing this because for some reason if I don't, when I go to add the popup div, the initial click from the button used to set that popup fires the listener and closes the popup before I have a chance to do anything. This has been my solution around the problem, but is that the only way? Or am I just setting the listener slightly incorrect?
I usually do something like this:
$(document).click(function(e) {
// hide popup
});
$('#popup_div').click(function(e) {
e.stopPropagation();
});
That way the clicks from your popup never propagate to the document, so the close function never fires.
Replace
if(target.parentNode.id != clone.id)
with
if ($(target).closest("#" + clone.id).length === 0)
(I left the second clause alone since it didn't seem related to your question.)
This tries to find the closest ancestor with ID equal to clone.id. If none is found, an empty jQuery object is returned (i.e. one with length === 0), which is what we test for.
Incidentally: jQuery normalizes event.target, so you can just use that instead of whatever custom monstrosity EventUtility.getTarget(event) embodies.

Categories