So synchronisieren Sie das Scrollen zwischen 2 Containern, während Sie das Panel auf der Schwebeplatte anzeigenHTML

HTML-Programmierer
Guest
 So synchronisieren Sie das Scrollen zwischen 2 Containern, während Sie das Panel auf der Schwebeplatte anzeigen

Post by Guest »

In meiner Svelte -Komponente zeige ich Zeilennummern für jede Zeile im Textbereich. Ich habe die Bildlaufnummer deaktiviert. Und manuell synchronisieren Zeilennummernbehälter, wenn ich auf den Textbereich scrolle. Überlauf-y: Hidden; auf #Zeilenzahlen Spielen Sie in diesem Fall eine entscheidende Rolle. Dies funktioniert gut, wenn ich Überlauf hinzufüge: sichtbar; zu #Zeilenzahlen , aber dann ist das Scrollen nicht synchron Beschreibung hier "src =" https://i.static.net/gsx7m3bq.png "/>
Hier ist der Code von Sveltle Komponente < /p>

Code: Select all

import { getSelectedLines } from './selection.js';
import { handleEditing } from './text-editor.js';
import { onMount, afterUpdate } from 'svelte';
import './TextArea.css';

// Props
export let text = ''; // The text content of the textarea
export let placeholder = ''; // Optional placeholder text
export let disabled = false; // Whether the textarea is disabled
export let stepsExecutionTimes = []; // Execution time data
export let mode = "editor"; // editor, monitor

// Events
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();

let previousText = ''; // Track previous text for change detection
let lineNumbers = []; // Array to hold line numbers
let highlightedLines = []; // Array to hold highlighted lines
let collapsedLines = new Set(); // Set to hold collapsed lines
let lineNumbersContainer; // Reference to the line numbers container
let textarea; // Reference to the textarea element
let highlightedTextContainer; // Reference to the highlighted text container

// Emit text change events
function emitTextChange(newText) {
dispatch('textChange', { text: newText });
}

// Emit line selection events
function emitLineSelection(selectedLines) {
dispatch('lineSelection', { selectedLines });
}

// Handle key down events for text editing and highlighting
function handleKeyDown(event) {
//..
}

// Highlight the current step node based on the selected lines
function highlightCurrentStepNode(event) {
const selectedLines = getSelectedLines(event.target, event.key, event.shiftKey);
emitLineSelection(selectedLines); // Emit selected lines
highlightedLines = selectedLines.nodeIds;
}

// Handle key up events to detect text changes
function handleKeyUp(event) {
//..
}

// Handle click events to highlight the current step
function handleClick(event) {
//..
}

// Update line numbers based on the text content
function updateLineNumbers() {
const lines = text.split('\n');
let lineCount = 0;
lineNumbers = lines.map((line, index) => {
const trimmedLine = line.trim();
//TODO: exclude header lines
if (trimmedLine.startsWith("FLOW:")) {
lineCount = -1; // Reset line count for new FLOW
return null; // No line number for FLOW line
} else if (trimmedLine.length === 0) {
return null; // No line number for empty lines
} else {
lineCount++;
let className = "";
const exeTime = $stepsExecutionTimes.find(et => et.id === lineCount);

//..
return { lineNumber: lineCount, className, exeTime };
}
});
}

function handleToggleDebug() {
dispatch('toggleDebug');
}

// Handle logs button click
function handleShowLogs() {
dispatch('showLogs');
}

// Sync scrolling between textarea and line numbers
function syncScroll(event) {
const {scrollTop,scrollLeft} = event.target;
lineNumbersContainer.scrollTop = scrollTop;
highlightedTextContainer.scrollTop = scrollTop;
highlightedTextContainer.scrollLeft = scrollLeft;
if(highlightedTextContainer.scrollTop !== scrollTop){
event.target.scrollTop = highlightedTextContainer.scrollTop;
lineNumbersContainer.scrollTop = highlightedTextContainer.scrollTop;
}
// event.preventDefault();
}

// Prevent scrolling on line numbers
function preventLineNumberScroll(event) {
if (lineNumbersContainer) {
lineNumbersContainer.scrollTop = event.target.scrollTop;
}
}

// Highlight keywords, comments, and FLOW lines
function highlightKeywords(text) {
const lines = text.split('\n');
const highlightedLines = lines.map((line) =>  {
if (line.trim().startsWith('#')) {
// Highlight comment lines
return `${line}`;
} else if (line.trim().startsWith('FLOW:')) {
// Highlight FLOW lines
return `${line}`;
} else {
// Highlight other keywords
const keywords = {
branch: ["IF", "ELSE_IF", "ELSE", "LOOP"],
leaving: ["GOTO", "SKIP", "STOP", "END"],
normal: ["AND", "THEN", "BUT", "FOLLOW", "ERR"],
other: ["FLOW", "FOLLOW"]
};

let highlightedLine = line;
Object.entries(keywords).forEach(([category, words]) => {
words.forEach(word => {
const regex = new RegExp(`\\b${word}\\b`, 'g');
highlightedLine = highlightedLine.replace(regex, `${word}`);
});
});

return `${highlightedLine}`;
}
});
return highlightedLines.join('\n');
}

// Update the highlighted text container
function updateHighlightedText() {
if (highlightedTextContainer) {
highlightedTextContainer.innerHTML = highlightKeywords(text);
}
}

$: {
//Text is not being displayed on load without this code until user click on text area
if (text !== previousText) {
updateLineNumbers();
updateHighlightedText();
}
}

// Initialize line numbers on mount
onMount(() => {
updateLineNumbers();
updateHighlightedText();
});

// Update line numbers after the component updates (e.g., when switching flows)
afterUpdate(() => {
updateLineNumbers();
updateHighlightedText();
});



{#each lineNumbers as line, index}
{#if line !== null}

{line.lineNumber}


Min: {line.exeTime?.minExeTime || 0} ms
Avg: {line.exeTime?.avgExeTime || 0} ms
Max: {line.exeTime?.maxExeTime || 0} ms

🔧
📄



{:else}
&nbsp;
{/if}
{/each}




< /code>
Hier ist die CSS -Datei < /p>
#text-area-container {
display: flex;
width: 100%;
height: calc(100vh - 180px);
font-family: monospace;
background-color: #f9f9f9;
overflow: hidden; /* Prevent double scrollbars */
position: relative;
}

#highlighted-text, #text-area, #line-numbers {
font-family: monospace;
font-size: 14px; /* Ensure consistent font size */
line-height: 1.5; /* Ensure consistent line height */
}

#line-numbers {
position: relative;
width: 40px;
padding: 10px 5px;
text-align: right;
border-right: 1px solid #ccc;
background-color: #f0f0f0;
user-select: none;
overflow-y: hidden; /* Disable scrolling */
height: 100%; /* Match height of textarea */
z-index: 3;
overflow: visible;
}

#highlighted-text {
color: inherit;
position: absolute;
top: 0;
left: 40px;
right: 0;
bottom: 0;
padding: 10px;
box-sizing: border-box;
height: 100%;
pointer-events: none;  /* Allow clicks to pass through to the textarea */
white-space: pre-wrap;
font-family: monospace;
overflow: hidden;
z-index: 2; /* Ensure highlighted text is above the textarea */
}

#text-area {
flex: 1;
border: 0;
padding: 10px;
box-sizing: border-box;
resize: none;
height: 100%;
background-color: transparent;
overflow-y: auto; /* Enable scrolling */
height: 100%; /* Match height of line numbers */
position: relative;
z-index: 1; /* Ensure textarea is below the highlighted text */
color: transparent; /* Make textarea text transparent */
caret-color: black; /* Ensure the caret (cursor) is visible */
}

#text-area:disabled {
background-color: #eee;
cursor: not-allowed;
}

#line-numbers > div {
position: relative; /* Ensure panels are positioned relative to the line number */
padding-right: 10px; /* Add space for the panel */
}

/* Panel */
.panel {
position: absolute;
top: 0;
left: 100%; /* Position to the right of the line number */
background-color: white;
border: 1px solid #ccc;
padding: 10px;
border-radius: 4px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
z-index: 3; /* Ensure panel is above other elements */
pointer-events: none; /* Allow interactions with the panel */
opacity: 0; /* Hidden by default */
transition: opacity 0.2s ease-in-out;
min-width: 80px;
white-space: nowrap; /* Prevent line breaks */
}

/* Show panel on hover */
#line-numbers > div:hover .panel {
opacity: 1; /* Visible when hovered */
pointer-events: auto;
}

/* Panel icons */
.panel-icons {
display: flex;
gap: 10px;
margin-top: 10px;
}

.panel-icons button {
background: none;
border: 1px solid #ccc;
cursor: pointer;
font-size: 14px;
padding: 5px 10px;
border-radius: 4px;
}

.panel-icons button:hover {
background-color: #f0f0f0;
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post