7

I was wondering if there is a way I could find the position of letters in HTML using Javascript or jQuery? I highly doubt this is possible, but it would make my life so much easier.

Alternatively, Is there a way to find the position of <br /> tags in HTML using JS?

Thanks in advance.

Flip
  • 6,233
  • 7
  • 46
  • 75
Roozbeh15
  • 4,047
  • 6
  • 27
  • 30
  • You're going to have to define what you mean by "position of letters in html". In relation to how they are displayed on the screen? Describe what you're trying to achieve, not how you think you have to achieve it. – Jared Farrish Feb 11 '12 at 09:57
  • What exactly do you mean by position? Index or what and in what context/parent? – Sarfraz Feb 11 '12 at 09:57
  • you can get your element with javascript or jquery, get them with tag. and with jquery you can find its position very easy. http://api.jquery.com/position/ – Ali U Feb 11 '12 at 10:00
  • 2
    http://stackoverflow.com/questions/5143534/get-the-position-of-text-within-an-element – Jakub Roztocil Feb 11 '12 at 10:00
  • I'm trying to get the position of letters on the screen just like you would get the position of a div element. – Roozbeh15 Feb 11 '12 at 10:00
  • See @jkbr's comment; that would be what you'd do. This is a duplicate of that question. – Jared Farrish Feb 11 '12 at 10:01
  • 1
    @Roozbeh15 http://jsfiddle.net/WKgWM/ – mgraph Feb 11 '12 at 10:15
  • @mgraph I want to do exactly that, except the highlighted character will constantly be changing. Much like what happens in a charayokee machine. I know how to take it from here, I think! Thanks a lot. – Roozbeh15 Feb 11 '12 at 20:13
  • @Roozbeh15 i will put as answer – mgraph Feb 11 '12 at 20:27

4 Answers4

12

As tdammers mentions, handling all of the details of putting together a process to handle what you're suggesting has many nuances that may have to be addressed, depending on what you're doing.

The basics of what you're trying to do is:

  1. Wrap an element around the text you want to find the position for, ie, in the case of text, probably a <span>.
  2. Get either the $.offset() or $.position() of the element or elements you added. Whichever you choose is relevant to what you're trying to do; the first is relevant to the document, the second to the containing element.

I created a simple demo of a script to "highlight" a term typed into a textbox in several paragraphs using divs with position: absolute and top/left offsets relative to the terms found in the paragraphs (located by the <span> surrounding them).

Note, this is only a demonstration (of $.offset()); it's not production-ready code. There's a link to the live fiddle demo below the code snippets.

First, I created a function to find and create a highlight <div> for each term found.

function highlightWordPositions(word) {
    var $paras = $('p'),
        $spans,
        _top = 0,
        _left = 0;

    $paras.each(function(){
        var $p = $(this),
            regex = new RegExp(word, 'g');

        $p.html($p.text().replace(regex, '<span>' + word + '</span>'));
        $spans = $p.find('span');

        $spans.each(function(){
            var $span = $(this),
                $offset = $span.offset(),
                $overlay = $('<div class="overlay"/>');

            $overlay
                .offset($offset)
                .css({
                    width: $span.innerWidth(),
                    height: $span.innerHeight()
                }).show();

            $(document.body).append($overlay);
        });
    });
}

Then, I attached a callback to the $.keyup() event:

$('#term').keyup(function(event){
    var term = this.value;

    if (term == '') {
        $('.overlay').remove();
        return false;
    } else if (term.indexOf(' ') != -1) {
        this.value = term.replace(' ', '');
        return false;
    }

    $('.overlay').remove();

    highlightWordPositions(term);
});

http://jsfiddle.net/JaN75/

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
  • Wow... this is pretty amazing! – Roozbeh15 Feb 11 '12 at 20:17
  • Is there any better solution to this? Considering that answer is more then a year old. – Cybrix Aug 07 '12 at 17:57
  • @Cybrix - That's actually not a year old (2012). I guess you need to define "better". You can wrap it with additional markup, like mgraph's example. – Jared Farrish Aug 07 '12 at 21:45
  • @JaredFarrish, Oops indeed it's not old at all. I don't know what I was reading. And what I had in mind is a way to avoid to wrap every words. Maybe using a monospaced font and do some calculation. But I doubt we can avoid to manually loop through the words to extract it's "sizes" and store it somewhere. This task is probably as much trouble (for the browser) with lot of words then wrapping them like your solution suggest. – Cybrix Aug 07 '12 at 22:47
  • this is old, now just use Range – caub Jan 20 '16 at 09:09
2

There is a simpler and more lightweight way (vs other answers that suggest overlays) to find the position of letters in DOM elements: use a range.

// returns { left, top, etc } in px
function getLetterPositions(myElementWithText, myTextElementIndex, myLetterPosition) {
    var range = document.createRange();
    range.setStart(myElementWithText.childNodes[myTextElementIndex], myLetterPosition);
    range.setEnd(myElementWithText.childNodes[myTextElementIndex], myLetterPosition+1);
    return range.getBoundingClientRect();
}
  • the element with the text holding the target letter is myElementWithText (e.g. a <div>)
  • the element child with the text (i.e. the textNode) is at index myTextElementIndex (in most cases, 0)
  • the position of the letter you are trying to find is myLetterPosition (e.g. if text is "abcd" and you want "c", this will be 2)
mwag
  • 3,557
  • 31
  • 38
2

Assuming that you mean the position where the character is displayed on screen, in pixels:

jQuery or the DOM do not model individual characters in their object models, so you can't read a character's position directly.

The best way I can think of is to insert a dummy element right before (or after) the character, e.g. a zero-width span with a special class, and then get its position. Alternatively, you can wrap the character in such a special element, and then get the wrapper's position, width, height, etc.

It's still not trivial, because you need to scan the HTML, and you don't want to break the HTML by inserting tags where they don't belong - for example, if you want to match the character 'd', you don't want to turn <div> into <<span class="magic">d</span>iv>, as that wouldn't be well-formed HTML.

Also, inserting those dummy elements may alter the layout slightly, depending on how the browser handles kerning.

jedierikb
  • 12,752
  • 22
  • 95
  • 166
tdammers
  • 20,353
  • 1
  • 39
  • 56
1

in action: http://jsfiddle.net/WKgWM/

html:

<p>Percussus ait in fuerat construeret cena reges undis effugere quod una.</p>​

js:

var selection = "dis";
var spn = '<span class="selected">'+selection+'</span>';
$("p").html($("p").html().replace(selection,spn));

css:

.selected{
  background-color:#FF00FF;
}​
mgraph
  • 15,238
  • 4
  • 41
  • 75