Select HTML Elements Visually - javascript

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

Related

How to access sub-elements in current object within JavaScript/jQuery?

Above I have three banner elements that I want to mark as unread if they are clicked. I structured each banner so that they have a span element within a nested div as shown with the image below (the red dot comes from the span element):
My javascript for this function is the following code:
I am trying to add a class ".read-dot" to the ".dot" span element that will hide it. I would like to add this class to the ".dot" span element that is inside the div that the user would click on. Any help would be appreciated.
I tried accessing the this.$(".dot) to access the dot element of the current object that triggered the event, but I now see this syntax is incorrect. I am new to jQuery which is why I tried this; I also could not find the page most relevant to my question on the API doc.
First, you have to remove click accessibility for the child.
$('div.banner > *').css('pointer-events', 'none');
And then, you can use the jquery selector for the .unread class to remove the class and replace .dot with .read-dot
$('.unread').click((e) => {
let clickedElm = e.target;
clickedElm.classList.remove('unread');
clickedElm.querySelector('span').classList.remove('dot');
clickedElm.querySelector('span').classList.add('read-dot');
})

Focusing on nested contenteditable element

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())

How to disable Anchor(a ) tag on pageload or (by default disable) and enable it using jquery or Javascript?

How to disable Anchor(a ) tag on pageload or (by default disable) and enable it using jquery or Javascript??
You can change href attribute to data-href and add href attribute using:
$(function() {
$('[data-href]').each(function() {
var self = $(this);
self.attr('href', self.data('href'));
});
});
this will iterate over all elements that have data-href and add href attribute.
Since you need to disable the anchor tags by default, you can add a class to each tag and remove the calss using javascript.
.not-active {
pointer-events: none; // disables all the clicks
cursor: default; // shows the default cursor when you hover it instead of hand
}
Also you can change the font color and others so that the text does not appear like a link.
[EDIT]
<script>
var anchorElements=document.getElementsByTagName("a"); //Gives the list of all anchor tag elements in the page as an array.
for(i=0;i<anchorElements.length;i++) // Iterate over the array
anchorElements[i].classList.remove("not-active"); // for each element .classList returns the list of classes specified. remove() is an array function to remove an element in the array
</script>
If you are using jQuery you can use removeClass() jQuery function
$("a").removeClass("not-active");
To answer your comment ("How can I Remove calss using javascript ?? plz help") on removing class, there is a property called classList that contains its class attributes. This property provides methods that make it easy to add or remove a class. Something like:
var myItemClasses= document.getElementById("item").classList;
myItemClasses.remove("my-classname"); // to remove
myItemClasses.add("my-classname"); // to add
Hope this helps.

Hide an element without CSS

If CSS is disabled, but JavaScript is not, how can I hide an element (a file input field, in my case)? None of the following will work, although they all work when CSS is enabled:
element.style.display = 'none';
element.style.visibility = 'hidden';
element.hidden = 'hidden';
element.hidden = true;
element.setAttribute('hidden','hidden');
element.setAttribute('hidden',true);
The only thing that can hide when CSS is disabled, as far as I know, is a hidden input field. Maybe that could lead to a solution. Any help is appreciated, thanks!
Because it's an input element, you could change its type to hidden:
element.type = "hidden";
But be aware that this won't work in some IE versions. In that case, I think you'd need to create a new element, give it the hidden type, and swap them.
DEMO: http://jsfiddle.net/gLvRz/
You can just delete element from DOM:
element.parentNode.removeChild(element);
If you want to restore it later, you can store its HTML code (or a reference to element itself) in a variable. In case of form field, it may be required to store its value too and then restore the value after restoring element itself.
Also, consider using hidden HTML5-attribute, though its support by browsers may be not too wide yet (and the attribute itself may be removed from HTML standard).
I suppose you could abuse the AREA element to hide something inside it.
//hide element
var hiddenContainer = document.createElement("AREA");
element.parentNode.insertBefore(hiddenContainer, element);
hiddenContainer.appendChild(element);
//show element
hiddenContainer.parentNode.insertBefore(element, hiddenContainer);

Is there a way to detect if I'm hovering over text?

What I'm really after is to detect when the cursor changes to type "text", that is, when I'm hover over a piece of text. I have tried looking at the element types I am hovering over, but this isn't too accurate because I don't know what they actually contain.
I understand that detecting the CSS cursor attribute is only possible if it has previously been assigned by me.
Is this possible at all? How would you go about doing this?
EDIT:
I do not want to check If I am currently over a specific element, I want to know if I am hover over any text within that element. A div could be 100% width of the browser, but with a shorter piece of text at the far left. I don't want to detect when hovering over just any part of an element.
No need to try to detect if the cursor changed.
You can simply detect if the mouse is hovering your text by using this kind of construct :
document.getElementById('myTextId').onmouseover = function() {
// do something like for example change the class of a div to change its color :
document.getElementById('myDivId').className = 'otherColor';
};
If you don't have an id but a class or a tag, you can replace getElementById by getElementsByClassName or getElementByTagName (which will return arrays on which you'll iterate).
If you want to restore the color when leaving the element, I suggest you bind the event onmouseout in the same way.
For example, if you want to do something on any paragraph, you may do that :
var paras = document.getElementByClassName('p');
for (var i=0; i<paras.length; i++) {
paras[i].onmouseover = function() {
// do something like for example change the class of a div to change its color :
document.getElementById('myDivId').className = 'otherColor';
};
}
I you plan to do a lot of things like this, I suggest you look at jquery and its tutorial.
One possible way is to find all the text nodes in your DOM and wrap them in a span with a certain class. Then you could select that class and do whatever you want with it:
// Wrap all text nodes in span tags with the class textNode
(function findTextNodes(current, callback) {
for(var i = current.childNodes.length; i--;){
var child = current.childNodes[i];
if(3 === child.nodeType)
callback(child);
findTextNodes(child, callback);
}
})(document.body, function(textNode){ // This callback musn't change the number of child nodes that the parent has. This one is safe:
$(textNode).replaceWith('<span class="textNode">' + textNode.nodeValue + '</span>');
});
// Do something on hover on those span tags
$('.textNode').hover(function(){
// Do whatever you want here
$(this).css('color', '#F00');
},function(){
// And here
$(this).css('color', '#000');
});
JSFiddle Demo
Obviously this will fill your DOM with a lot of span tags, and you only want to do this once on page load, because if you run it again it will double the number of spans. This could also do weird things if you have custom css applied to spans already.
If you're using jQuery (which you should, because jQuery is awesome), do this:
$("#myDiv").mouseover(function() {
$("#myDiv").css("background-color", "#FF0000");
});

Categories