1

I'm attempting to combine a JavaScript mechanism for auto placing the users cursor inside of an input box through the mouseover and mousemove listeners.

I have an almost perfect working example here: http://codepen.io/anon/pen/doxNLm?editors=101

  var current_element = document.getElementById("hover");
  current_element.onmousemove = function showCoords(evt) {

    var form = document.forms.form_coords;
    var parent_id = this.id;
    form.parentId.value = parent_id;
    form.pageXCoords.value = evt.pageX;
    form.pageYCoords.value = evt.pageY;
    form.layerXCoords.value = evt.layerX;
    form.layerYCoords.value = evt.layerY;

    function getTextWidth(text, font) {
      // re-use canvas object for better performance
      var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
      var context = canvas.getContext("2d");
      context.font = font;
      var metrics = context.measureText(text);
      return metrics.width;
    };

    var element_base_browser_styles = window.getDefaultComputedStyle(current_element);
    var total_text_pixal_length = getTextWidth(current_element.value, element_base_browser_styles.fontFamily + " " + element_base_browser_styles.fontSize);

    var add_char_pixal_lengths = 0;

    var myStringArray = current_element.value.split('');
    var arrayLength = myStringArray.length;
    for (var i = 0; i <= arrayLength; i++) {
      var get_char_value = getTextWidth(myStringArray[i], element_base_browser_styles.fontFamily + " " + element_base_browser_styles.fontSize);

      add_char_pixal_lengths = add_char_pixal_lengths + (get_char_value) + 1.311111111111; //every char value is added together. 
     // console.log("Total: " + x);

      if ((add_char_pixal_lengths)> (evt.layerX)) { 
        this.setSelectionRange(i, i);
        add_char_pixal_lengths = 0;
        break;
      }
    }
  }

  current_element.onmouseover = function() {
    this.focus()
  }

The problem I'm having is like Geosynchronous orbit; the cursor shifts out of place sometimes a few pixels (left or right). My calculation probably sucks, but I'm not sure canvas is really the best way to do the measurement? Is there a better way?

  1. mousemove listener to receive element cursor coordinates from e.pageX
  2. font style using window.getComputedStyles(input_element)
  3. arr.split('') from input_element.text string: x = ['a','b','c']
  4. 'for loop' the array, generate a canvas and measure each characters width
  5. add all char widths one by one until the value is greater than e.pageX
  6. set the 'for loop' iterate as the setSelectionRange(i, i)

Any help or suggestions on making this better would be appreciated. Thanks!

Null
  • 123
  • 7
  • Looks like it works to me. I move my cursor over the input, and it receives focus. Can you explain in more detail what you want to happen / what the bug is? – Lee Aug 24 '15 at 16:11
  • Sure, I'm looking for a more precise result. It works pretty good right now in the latest Firefox, but Chrome and others, not so much. so I'm just at a loss on how to optimize this any better. – Null Aug 24 '15 at 17:12
  • Oh, ok... I see what you're trying to do now. In chrome I get this error: `Uncaught TypeError: window.getDefaultComputedStyle is not a function` – Lee Aug 24 '15 at 19:25
  • Rather than a canvas, might be easier to just duplicate the element, set the styles, and render the element outside of the page somewhere (`top: -10000px`). – Lee Aug 24 '15 at 19:27
  • Ya, that's what i was originally going to try but got distracted with the canvas idea, btw getDefaultComputedStyle should be getComputedStyle for multi-browser support, not sure about I.E. but it works for Chrome. – Null Aug 25 '15 at 03:25

0 Answers0