I have a Div which is as big as half of my page using CSS:
CLICK ON THIS TEXT
I am trying to wr
Since we cannot listen for events directly on the textNodes themselves, we have to take a more creative path to solving the problem. One thing we can do is look at the coordinates of the click event, and see if it overlaps with a textNode.
First, we'll need a small helper method to help us track whether a set of coordinates exists within a set of constraints. This will make it easier for us to arbitrarily determine if a set of x/y values are within the a set of dimensions:
function isInside ( x, y, rect ) {
return x >= rect.left && y >= rect.top
&& x <= rect.right && y <= rect.bottom;
}
This is fairly basic. The x
and y
values will be numbers, and the rect
reference will be an object with at least four properties holding the absolute pixel values representing four corners of a rectangle.
Next, we need a function for cycling through all childNodes that are textNodes, and determining whether a click event took place above one of them:
function textNodeFromPoint( element, x, y ) {
var node, nodes = element.childNodes, range = document.createRange();
for ( var i = 0; node = nodes[i], i < nodes.length; i++ ) {
if ( node.nodeType !== 3 ) continue;
range.selectNodeContents(node);
if ( isInside( x, y, range.getBoundingClientRect() ) ) {
return node;
}
}
return false;
}
With all of this in place, we can now quickly determine if a textNode was directly below the clicked region, and get the value of that node:
element.addEventListener( "click", function ( event ) {
if ( event.srcElement === this ) {
var clickedNode = textNodeFromPoint( this, event.clientX, event.clientY );
if ( clickedNode ) {
alert( "You clicked: " + clickedNode.nodeValue );
}
}
});
Note that the initial condition if ( event.srcElement ) === this
allows us to ignore click events originating from nested elements, such as an image or a span tag. Clicks that happen over textNodes will show the parent element as the srcElement
, and as such those are the only ones we're concerned with.
You can see the results here: http://jsfiddle.net/jonathansampson/ug3w2xLc/
Quick win would be to have
<div id="bigdiv">
<span id="text">TEXT HERE</span>
</div>
Script:
$('#text').on('click', function() {
.....
});
If you want to go straight through HTML, you can use
<div id="bigdiv" onclick="myFunction();">
and then simply apply the function afterwards in JS:
function myFunction(){
//...
}
EDIT: sorry, if you want the text to be affected, put in <p>
around the text or <span>
ie.
<div id="bigdiv">
<p onclick="myFuncion();"> TEXT </p>
</div>
Let's alter the content dinamically - I will make the clicking on lala available:
<div id="gig">
<div id="smthing">one</div>lala
<div id="else"></div>
</div>
Script:
var htmlText = $('#gig').text(); //the big divs text
var children = $('#gig').children(); //get dom elements so they can be ignored later
$.each(children, function (index, child) {
var txt = $(child).text().trim();
if (txt != '') { //if a child has text in him
htmlText = htmlText.replace(txt, 'xxx'); //replace it in the big text with xxx
}
});
htmlText = htmlText.split("xxx"); //split for xxx make it arrat
var counter = 0; //the part when the text is added
$.each(htmlText, function (i, el) {
htmlText[i] = el.trim();
if (htmlText[i] != "") { //if there is something here than it's my text
htmlText[i] = '<span id="text">' + htmlText[i] + '</span>'; //replace it with a HTML element personalized
counter++; //mark that you have replaced the text
} else { // if there is nothing at this point it means that I have a DOM element here
htmlText[i] = $(children[i - counter])[0].outerHTML; //add the DOM element
}
});
if (children.length >= htmlText.length) { //you might have the case when not all the HTML children were added back
for (var i = htmlText.length - 1; i < children.length; i++) {
htmlText[i + 1] = $(children[i])[0].outerHTML; //add them
}
}
htmlText = htmlText.join(""); //form a HTML markup from the altered stuff
$('#gig').html(htmlText); // replace the content of the big div
$('#text').on('click', function (data) { //add click support
alert('ok');
});
See a working example here: http://jsfiddle.net/atrifan/5qc27f9c/
P.S: sorry for the namings and stuff I am a little bit tired.
Are you able to do this, is this what you are looking for?
What the code does: It's making only the text inside the div although the div could have other divs as well, makes only the text that has no HTML container like a div a span a p an a or something like that and alters it adding it in a span and making it available for clicking.
EDIT - Solution without adding wrapping element
Doing this without a wrapping element is quite a hassle. I managed to get it to work, however this will only work for one liners that are centered vertically AND horizontally.
To see the HTML and CSS that goes along with this, see the jsFiddle: http://jsfiddle.net/v8jbsu3m/3/
jQuery('#bigDiv').click(function(e) {
// Get the x and y offest from the window
margin_top = jQuery(this).offset().top;
margin_left = jQuery(this).offset().left;
// Get the dimensions of the element.
height = jQuery(this).height();
width = jQuery(this).width();
// Retrieve the font_size and remove the px addition
font_size = parseInt(jQuery(this).css('font-size').replace('px', ''));
// Retrieve the position of the click
click_x = e.pageX;
click_y = e.pageY;
// These variables will be used to validate the end result
var in_text_y = false;
var in_text_x = false;
// Determine the click relative to the clicked element
relative_x = click_x - margin_left;
relative_y = click_y - margin_top;
// Determine whether the y-coordinate of the click was in the text
if (relative_y >= (parseFloat(height) / 2) - (parseFloat(font_size) / 2) &&
relative_y <= (parseFloat(height) / 2) + (parseFloat(font_size) / 2))
in_text_y = true;
// This piece of code copies the string and places it in a invisible div
// If this div has the same font styling and no paddings etc... it can
// be used to get the width of the text
text = jQuery(this).text();
text_width = jQuery('#widthTester').html(text).width();
// Determine whether the x-coordinate of the click was in the text
if (relative_x >= (parseFloat(width) / 2) - (parseFloat(text_width) / 2) &&
relative_x < (parseFloat(width) / 2) + (parseFloat(text_width) / 2))
in_text_x = true;
// If the x and y coordinates were both in the text then take action
if (in_text_x && in_text_y)
alert('You clicked the text!');
});
Also, this code can be optimized, since the same calculcation is done multiple times, but I thought that leaving the calculcations there better illustrated what was going on.
Solution by adding a wrapping element
If you put a span around the text, then you can add an onClick event handler to the span.
<div id="bigdiv">
<span>CLICK ON THIS TEXT</span>
</div>
jQuery code
jQuery('#bigdiv span').click(function() {
jquery(this).remove();
});