I have many contenteditable div.
When I select a text by hightlighting inside a contenteditable div, I want to retrieve the contenteditable div element.
For exemple :
<div contenteditable="true">
Hello World,
<i>this is <b>a dog</b> in the garden</i>
Thank you very much
</div>
So when I select the text "dog" by highlighting, I want to retrieve the contenteditable div element in order to know which contenteditable div I have used.
An idea ?
Edit :
I made this code, but it's not perfect :
var selection = window.getSelection();
var node = selection.anchorNode;
for(var i = 0; i < 50; i++)
{
node = node.parentNode;
if(node.getAttribute("contenteditable") == "true")
{
console.log("found");
break;
}
}
I think previous answers are over-complicating matters.
This is the same whether you select text or just click on an element.
You need to be able to identify the current element that you have clicked on or pressed a key on (otherwise I don't see how you can make contenteditable work sensibly).
Assuming you can do this, all you need to do is go back from CurrentElm to the parent that has the contenteditable attribute with a while loop -
while (Elm.contenteditable != true) {Elm=Elm.parent}
I confess to not providing full programming details, but I can if you need them.
The first issue is to be able to identify the CurrentElm on mouseclick or keypress.
If you can't do this, then get back to me and I'll explain - the rest then becomes easy.
You need an event to fire after the text is highlighted. Unfortunatley, there isn't a onhighlight event so you must use something like onmouseup.
Next, you need a way to add event listeners to all your contenteditable divs. One way to use this is document.querySelectorAll(). But you may find it easer to add one event listener to the "parent" of these divs and continue on with the directions below.
The event listener for mouseup will provide an event object. See https://developer.mozilla.org/en-US/docs/Web/Events/mouseup. This object has the value currentTarget which will give you the element where the mouseup event occured, which in turn is the element where the highlighting took place.
This question seems to have already been asked:
javascript to get paragraph of selected text in web page
Here is another example:
http://www.codetoad.com/javascript_get_selected_text.html
Related
I am dynamically (but not async) building html elements with js and encounter an error upon setting the "value" attribute.
Simplified code:
let tag = document.createElement("div");
tag.innerHTML = `${item}`;
tag.setAttribute("value", `${item}`);
tag.classList.add("newtags", "lot of css classes")
tagslist.appendChild(tag)
newtags = Array.from(document.querySelectorAll('.newtags'))
newtags.forEach(item => {
item.addEventListener("click", e =>{
console.log(e.target.value)
})
})
Upon clicking on the created tags I get "undefined" yet if I do console.log(e.target) without adding value I can see it is working and the value is there. Am I setting something that isn't really the value of the element?
Thanks
Div elements don't have value attributes. Only form controls (like input and button elements) do.
You could use a data attribute for this but div elements aren't designed to be interactive.
You are adding a click event handler but screen readers won't tell the user they can click on them, and people navigating with a keyboard will skip right past them since you haven't done anything to allow them to be focused.
Use a button instead of a div. Apply CSS as desired.
div element doesn't have value property. only few elements such as input, textarea have value
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
I think you want to add attribute data-value to the div as div element doesn't have a value attribute.
tag.setAttribute("data-value", `${item}`);
Then when you try to get the div data value.
console.log(e.target.dataset.value)
The following function can focus on an element with an id declaration:
function setFocus() {
document.getElementById("focus").focus();
}
But how can one focus on an element with a classname declaration. Use case would be previously in the code where the element we want to focus on is already stored from the dom (i.e., const element = document.querySelectorAll('.a-class-name')[0]) type of scenario?
Does the element have a tab index? You cannot focus a non input element unless it has a tab index. Use tabindex="-1" for elements like divs and spans. Then call the .focus() method on the element. -1 will allow you to focus with the focus method but wont get focus when move the focus around with the keyboard and pressing tab.
document.getElementById('btn').addEventListener('click', function() {
document.querySelectorAll('.focus_me')[0].focus();
});
<span class="focus_me" tabindex="-1">Focus me</span><br>
<button id="btn">Click to focus</button>
element.scrollIntoView(true) will do what you are needing.
document.getElementsByClassName('className') would always return multiple elements because conceptually Classes are meant to be applied to multiple elements. If you want only the first element in the DOM with that class, you can select the first element out of the array returned, as you did.
var elements = document.getElementsByClassName('className');
var requiredElement = elements[0];
OR
var requiredElement = document.querySelector('.className');
Then as #j08691 mentioned in the comments use
function setFocus() {
requiredElement.focus();
}
If the one with getElementById works, then there is no reason for this to not.
Happy coding. :)
I was wanting to have a javascript (jQuery) function that removed everything that didn't have the safe class.
The problem is, if the parent element is hidden, it cannot show the 'safe' part of it.
Is there a simple way to get around this? I'd rather not go in and span all of the elements that need removed.
trimmer = function(element){
x = $(element+' *:not(.safe)');
x.hide();
}
trimmer('section');
Fiddle
var element = 'section';
//finds all non `.safe` elements in `section`s and hides them
$(':not(.safe)', element).hide();
//finds all `.safe` elements in `section`s and shows the `section`s
$('.safe', element).parents(element).show();
Horen was right, it is indeed impossible to show parts of a hidden element.
To make only parts of the text disappear, the non-safe content must be labeled for removal.
$(element).contents().each(function() {
if (this.nodeType == 3)
$(this).wrap('<span class="disappear" />');
});
You can read more about this answer here:
How to add spans to all areas of a node that isn't restricted
I have a requirement of changing focus of elements in a div by using tab key. focus should not be moved away from the elements in the div. How can this be done. I am trying this approach:
1) get all the elements inside div to an array
2) bind a keypress event to each element in the array and passing the nxt element to it
3) handling keypress by a function that will shift the focus to next element.
sample code:
var elements = jQuery('xxx');
elements.each(function (index, element) {
element.bind("keypress", { nxt:elements[index+1] }, function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.data.nxt[0].focus();
}
});
});
My doubt is,
1)how to get all the elements from the div that can be focused on tab key press.
2)Is there anything in jQuery that can get different type of elements in one go.(something like, to get input+select+a+textarea in one statement)
3)If this approach is not worth, please suggest one.
Check out this fiddle. It may help you
HTML code
<div id="container">
<input type="text" id="first"/>
<input type="text" id="second"/>
<input type="text" id="third"/>
</div>
JavaScript Code:
var elems = $('div#container input');
elems.each(function(index,element) {
console.log(element);
$(element).keydown(function(e) {
var code = e.keyCode || e.which;
console.log(code);
if(code === 9) {
$(this).next().focus();
e.preventDefault();
}
})
})
http://jsfiddle.net/tmFFk/1/
you don't need jquery for this. you can use tabIndex attribute to switch over. tabIndex.
<div tabIndex="1">asdasd</div>
<div tabIndex="2">asdasd 2</div>
<div tabIndex="3">asdasd 3</div>
demo : tabIndex
I had similar problem and created tiny jQueryUI plugin that limits fields that TAB affects. you use it simply:
$(".someGroup").tabGuard();
and that will make tab iterate over fields inside of .someGroup wrapper. This way you can group various forms on a page and the one in focus will keep iterating on TAB or Shift+TAB if that makes sense. Find it here:
http://tomaszegiert.seowebsolutions.com.au/tabguard/index.htm
It uses :tabbable to get all the elements that TAB can focus on and feel free to check source to see how its done. I hope you will find it useful.
If I'm reading it right, you need to switch in between DIVs with Tab press.
As per the Specification, Tabindex is not supported on Div's. It's only supported on A, AREA, BUTTON, INPUT, OBJECT, SELECT, and TEXTAREA.
As for the question, it's quite an unusual requirement but a very interesting one. I've never tried this out, but I can give my suggestions logically for each of your queries:
You can use .children() to get all child elements within that div.
You can use all selectors in one go by separating them with commas, or you can give them classes.
Let me know if it works out.
I would like to replace the text on pages when I click on the text or even just replace the single word clicked on. I have tried a top down approach selecting all elements in the DOM, filtering out the textNodes, wrapping each with tags and adding a click event handler to each tag. But this is far too slow and inefficient particularly on very large and dynamic sites.
I only need to replace the text that was clicked. Is there a bottom up way of doing this starting from the event.target? How do I find the closest textNode to the event.target, for example?
In the example you gave, you can just do the following; for more info see How do I select text nodes with jQuery?
$(document).click(function(event) {
textNodes = $(event.target).contents().filter(function() {
return this.nodeType == 3;
});
textNodes.each( function() {
$(this).replaceWith("New Text");
});
})
Have you tried Jquery's .closest() ?
Description: For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.