Replies: 1 comment
-
I make a version of your code that does:
// The idea is based on https://github.com/squidfunk/mkdocs-material/discussions/4370
// Immediately Invoked Function Expression (IIFE) to encapsulate the code and avoid polluting the global scope
(function () {
document.querySelectorAll('div.language-cpp.highlight>pre>code').forEach(function (code) {
let scrollPosition = 0; // we are dragging the code far from this original point
let pressTimer = null; // upon the mouse down, we will start the timer
const duration = 500; // the duration that triggers between code dragging instead of text selecting
let longPress = false; // if the timer surpasses the duration, then longPress is true and trigger
let isDragging = false; // we will still priority text selecting if any is selected when we both drag and select
const trigger_dragging = function (e) {
// Ignore non-left mouse button clicks
if (e.button !== 0) {
return;
}
// Check if the code element has scrollability
if (code.scrollWidth <= code.clientWidth) {
return;
}
// Reset flags and initial scroll position
longPress = false;
isDragging = false;
scrollPosition = e.clientX;
// Start the timer to differentiate between a click and a long press
if (pressTimer === null) {
pressTimer = setTimeout(function () {
// if we hold long enough to start code dragging
longPress = true;
isDragging = true;
// Change the cursor to indicate dragging is possible
code.style.cursor = 'grab';
setTimeout(function () {
code.offsetHeight;
}, 0);
}, duration);
}
};
const cancel_dragging = function (e) {
// If the mouse leaves the code element, cancel dragging
if (!code.contains(e.relatedTarget)) {
if (pressTimer !== null) {
clearTimeout(pressTimer);
pressTimer = null;
}
// Reset cursor and flags
code.style.cursor = '';
longPress = false;
isDragging = false;
}
};
const dragging = function (e) {
// Check if any text is selected, we prioritize text selecting to code dragging
const selection = window.getSelection();
if (selection.toString().length > 0) {
isDragging = false;
code.style.cursor = '';
return;
}
// If a long press has been detected and dragging is allowed, perform the dragging
if (longPress && isDragging) {
code.scrollLeft -= (e.clientX - scrollPosition);
scrollPosition = e.clientX;
e.preventDefault();
// Clear any text selection during this process, so the bug of both drag and select is not possible
window.getSelection().removeAllRanges();
}
};
const prevent_text_selecting = function (e) {
// prevent text selecting happens during dragging
if (isDragging) {
e.preventDefault();
}
}
// These 6 event listeners are used only in the code and not the whole document to avoid misuse
code.addEventListener("mousedown", trigger_dragging);
code.addEventListener("mousemove", dragging);
code.addEventListener("mouseup", cancel_dragging);
code.addEventListener("mouseout", cancel_dragging);
code.addEventListener("mouseleave", cancel_dragging);
code.addEventListener("click", prevent_text_selecting);
});
})(); |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hold the left mouse in empty area to drag
Code text is still selectable
extra.js
. ( set the highlight optionline_spans
to non-empty string for a better experience)Beta Was this translation helpful? Give feedback.
All reactions