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
-
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