'Prevent link dragging, but still allow text highlighting

I have some data in a table where clicking it will navigate you elsewhere, but people are requesting the ability to highlight the text to be able to copy/paste it elsewhere. Since they are links, the default behavior in HTML is to drag the link... I don't know why or how that is useful, but I want to disable that on certain links.

TL;DR: I want to be able to highlight the text of a link and not drag it.

The gif below should help explain my issue.

Example

The following methods are NOT what I want:

I have seen examples that prevent both highlighting & dragging using something like this

<a draggable="false" href="#">

or this

.no-drag {
  user-drag: none;
}

Or this

myElement.ondragstart = function () {
    return false;
};

But obviously that is not what I need here.Is what I want possible to do?



Solution 1:[1]

@Julien Grégoire's answer above put me on the right track for this, but the below code is the basics of what I ended up using.

var clickedEl = document.getElementById("test");
var limit = 5;
var mouseMoved = false;

function resetEvents() {
    clickedEl.onmousemove = null;
    clickedEl.ondragstart = null;
    clickedEl.onmouseleave = null;
    mouseMoved = false;
}

clickedEl.onmousedown = function (downEvent) {
    if (clickedEl.attributes.href) {
        clickedEl.onclick = function (clickEvent) {
            if (mouseMoved) {
                clickEvent.preventDefault();
            }
            resetEvents();
        };
    }
    
    clickedEl.onmouseleave = function () {
        resetEvents();
    };

    clickedEl.onmousemove = function (moveEvent) {
        // This prevents the text selection being dragged
        clickedEl.ondragstart = function (dragEvent) {
            dragEvent.preventDefault();
        };

        if (Math.abs(moveEvent.x - downEvent.x) >= limit || Math.abs(moveEvent.y - downEvent.y) >= limit) {
            // If user clicks then moves the mouse within a certain limit, select the text inside
            window.getSelection().selectAllChildren(clickedEl);
            mouseMoved = true;
        }
    };

};
<a id="test" href="http://stackoverflow.com">Click or select</a>

Solution 2:[2]

In Google Chrome this works

user-select: none;
-webkit-user-drag: none;

Solution 3:[3]

You could detect if user moves the mouse after the click and if so manage selection using window.getSelection. Something like this for example:

var linkEl = document.getElementById('test')

linkEl.onmousedown = function(downEvent) {

  var clickedEl = downEvent.target;
  var mouseMoved = false;

  clickedEl.onmousemove = function() {

    // If user clicks then moves, select the whole link
    window.getSelection().selectAllChildren(clickedEl);

    // Set a flag to prevent opening the link
    mouseMoved = true;

    // Reset mousemove, else it'll run constantly
    clickedEl.onmousemove = null;

    // This is only to prevent having the text selection being dragged
    clickedEl.ondragstart = function(dragEvent) {
      dragEvent.preventDefault();
    }
  }

  if (mouseMoved) {
    // If mouse has moved, prevent default
    downEvent.preventDefault();
  }
}
<a draggable="false" id="test" href="http://stackoverflow.com">Click or select</a>

Solution 4:[4]

This is the simplest solution that worked for me. You can change '*' to 'a'.

*, *::after, *::before {
    -webkit-user-select: none;
    -webkit-user-drag: none;
    -webkit-app-region: no-drag;    
}

Solution 5:[5]

I'm super late to answer but I'm just gonna leave it here:

Just put draggable="false" inside <a> tag,

<a draggable="false" href="./"></a>

then in CSS you put:

body {
        -webkit-user-drag: none;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 alejandrodotor8
Solution 3 FiniteLooper
Solution 4 FiniteLooper
Solution 5 ozakiharumi