1

An input field #chatInput needs to be be focused when clicking on a container element #text EXCEPT if text inside that element was (highlighted via either double click or mouse selection)

// what I got so far which is incomplete
$('#text').on('click', function (e) {
  $('#chatInput').focus();
});

Fiddle: https://jsfiddle.net/xhykmtwy/4/

Dan P.
  • 1,707
  • 4
  • 29
  • 57

2 Answers2

0

A bit longer than I initially thought a solution could be but here's what I got:

var mouseDownStart = 0,
    lastKeyupTime = 0;

function processKeyDown() {
  if (!mouseDownStart) {
    mouseDownStart = Date.now();
  }
}

function processKeyUp() {
  var now = Date.now(),
      isDoubleClick = lastKeyupTime && now - lastKeyupTime < 500;
      isHighliting = now - mouseDownStart > 150

  lastKeyupTime = now;
  mouseDownStart = 0;

  return {
    isDoubleClick: isDoubleClick,
    isHighliting: isHighliting
  }
}

$('#text').on('mousedown', function (e) {
  processKeyDown();
});


$('#text').on('mouseup', function (e) {
  var data = processKeyUp();
  if (data.isDoubleClick || data.isHighliting) return;
  $('#chatInput').focus();
});

Updated fiddle: https://jsfiddle.net/xhykmtwy/1/

Dan P.
  • 1,707
  • 4
  • 29
  • 57
  • I see two problems when testing your jsfiddle: (1) If the text is selected quickly, the input box gets the focus; (2) If the mouse button is kept down for some time before being released, without selecting text, the input box does not get the focus. – ConnorsFan Sep 12 '16 at 00:57
  • Yeah - the number in ms could be adjusted to better reflect the dbl click but it seems to work for most cases where people legitimately highlight stuff and double click. I'll go with your solution however - if `getSelection` is not supported in the browser, it's no big deal - at least the solution is 100% robust for the browsers that support it, which is most browsers anyway. Thanks. – Dan P. Sep 12 '16 at 05:54
0

You may want to consider the solution below, which checks if some text is selected in the text element after the click event:

$('#text').click(function () {
    var container = this;
    setTimeout(function () {
        var selectedElement = null;
        var selectedText = null;
        if (window.getSelection) {
            // For modern browsers
            var selection = window.getSelection();
            if (selection) {
                selectedText = selection.toString();
                if (selection.anchorNode) {
                    selectedElement = selection.anchorNode.parentNode;
                }
            }
        }
        else if (document.selection && document.selection.type === "Text") {
            // For IE < 9
            var selection = document.selection;
            selectedText = selection.createRange().text;
        }
        if (!(selectedText && selectedText.length > 0) || (selectedElement !== container && !$(container).has(selectedElement))) {
            setTimeout(function () { $('#chatInput').focus(); }, 0);
        }
    }, 0);
});

According to my tests, it works in IE (including IE7), Firefox and Chrome. The only exception is the double-click in IE, which does not select the text. You can see the result in this jsfiddle.

The calls to setTimeout ensures that all the selection processing has been done, especially when clicking on the selected text to deselect it.

Credits:

  1. I used the method proposed by Eineki in How can I get the element in which highlighted text is in? to check if the text element contains the selected text.

  2. The code for processing the selection in IE < 9 was found in Tim Down's answer to the post Get the Highlighted/Selected text.

Community
  • 1
  • 1
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • If the browser doesn't support window.getSelection, what happens? – Dan P. Sep 12 '16 at 05:54
  • I updated my question also - the click can actually happen outside the text string. https://jsfiddle.net/xhykmtwy/4/ – Dan P. Sep 12 '16 at 06:04
  • I modified the answer and the jsfiddle to account for the changes in your question. I also included the code for old IE versions which do not support `getSelection`. Please see my remark about the double-click in IE. – ConnorsFan Sep 12 '16 at 15:19