How do I change the size of a jQuery element?

Tilpas elementstørrelser dynamisk med jQuery

19/06/2023

Rating: 4.77 (16684 votes)
Indholdsfortegnelse

Dynamisk størrelsesjustering af HTML-elementer med jQuery

I moderne webudvikling, især når man designer applikationer til mobile enheder, er det ofte nødvendigt at have elementer, der kan tilpasse sig deres indhold. Dette gælder især for tekstinputfelter som input og textarea. Mens standard HTML og CSS ikke tilbyder en simpel løsning til at få disse elementer til automatisk at ændre størrelse baseret på det skrevne indhold, findes der effektive metoder ved hjælp af JavaScript, og specifikt jQuery, til at opnå denne funktionalitet. Denne artikel vil udforske forskellige teknikker til at håndtere dynamisk størrelsesjustering af HTML-elementer.

Udfordringen med Input- og Textarea-elementer

Som standard vil input- og textarea-elementer ikke ændre deres størrelse automatisk, når brugeren skriver tekst i dem. Dette kan være frustrerende, da det ofte er et ønskeligt træk at lade inputfelter udvide sig for at rumme længere tekststykker uden at kræve manuel scroll eller begrænse brugerens input. Mens andre HTML-elementer, som f.eks. span eller div, naturligt udvider sig (både horisontalt og vertikalt for block-level elementer) baseret på deres indhold, mangler inputfelter denne indbyggede adfærd.

Alternativer til Standard Inputfelter

En interessant tilgang til at opnå automatisk størrelsesjustering er at anvende attributten contenteditable på ikke-input elementer. Ved at gøre et element som en span eller div redigerbart, kan det udvide sig naturligt for at matche dets indhold. For eksempel:

<span class="input" role="textbox" contenteditable> 99 </span>

Et sådant span-element vil automatisk udvide sig horisontalt for at rumme indholdet. Hvis det var et block-level element, ville det også udvide sig vertikalt. Selvom denne metode giver den ønskede visuelle adfærd, rejser den spørgsmål om tilgængelighed og semantik. Brugen af role="textbox" er et forsøg på at signalere elementets funktion til skærmlæsere, men det er ikke en garanteret løsning. Desuden kan der være ulemper i forhold til, hvordan formularer indsendes, hvordan data serialiseres, og hvordan elementet opfattes af hjælpeteknologier sammenlignet med et standard input-felt.

Teknikker til Resizing af Faktiske Inputelementer med jQuery

Når vi ønsker at bevare funktionaliteten og tilgængeligheden af standard input- og textarea-elementer, er der flere metoder, der involverer jQuery:

1. Wrapper og Skjult Span-metoden

En populær teknik er at wrappe inputfeltet i en inline-block container (f.eks. en span eller div med display: inline-block;) og derefter absolut positionere det originale inputfelt indeni. En skjult span placeres også inde i wrapperen. jQuery bruges til at synkronisere inputfeltets værdi med den skjulte span. Når brugeren skriver, opdateres den skjulte span, og dens bredde bestemmer wrapperens bredde, hvilket igen skubber inputfeltet bredere efter behov.

Her er et eksempel på konceptet:

$(".resizable-input").on('input', function() { var $self = $(this); var $hiddenSpan = $self.siblings('.hidden-span'); if ($hiddenSpan.length === 0) { $hiddenSpan = $("").insertAfter($self); } $hiddenSpan.text($self.val() || $self.attr('placeholder') || ''); // Kopier vigtige CSS-egenskaber for at sikre korrekt breddeberegning var computedStyle = window.getComputedStyle($self[0]); $hiddenSpan.css({ 'font-family': computedStyle.fontFamily, 'font-size': computedStyle.fontSize, 'font-weight': computedStyle.fontWeight, 'letter-spacing': computedStyle.letterSpacing, 'padding-left': computedStyle.paddingLeft, 'padding-right': computedStyle.paddingRight, 'border-left-width': computedStyle.borderLeftWidth, 'border-right-width': computedStyle.borderRightWidth, 'box-sizing': 'content-box' // Vigtigt for korrekt breddeberegning }); $self.width($hiddenSpan.width() + 'px'); }).trigger('input'); // Udløs ved initialisering for at sætte korrekt bredde 

CSS ville se nogenlunde sådan ud:

.input-wrapper { position: relative; display: inline-block; } .resizable-input { position: absolute; top: 0; left: 0; width: 100%; /* Start med en bredde, som så justeres */ box-sizing: border-box; border: none; /* Eller specificer din egen border */ padding: 5px; /* Eller specificer din egen padding */ background: transparent; } .hidden-span { display: inline-block; visibility: hidden; white-space: nowrap; padding: 5px; /* Match input padding */ border: 1px solid transparent; /* Match input border */ font-size: inherit; /* Arv font-size */ } 

Denne metode sikrer, at inputfeltet visuelt matcher den beregnede bredde af dets indhold, inklusive pladsholdertekst, når feltet er tomt. Det er vigtigt at kopiere relevante skrifttypeegenskaber (font-family, font-size, font-weight osv.) fra inputfeltet til den skjulte span for at sikre en præcis breddeberegning.

2. Teknikker til Textarea

For textarea-elementer, der skal ændre højde baseret på indholdet, er en klassisk teknik at tælle antallet af linjeskift og bruge dette til at sætte elementets højde. Højden kan beregnes som (antal linjer * linjehøjde) + top/bund padding + top/bund border. Denne metode fungerer bedst for indhold, der er præformateret eller hvor linjeskift er meningsfulde (f.eks. kodevisning). For længere, uformaterede tekstblokke, hvor browseren automatisk ombryder tekst, er det mere komplekst.

En mere robust løsning for textarea involverer at måle den faktiske højde af indholdet. Dette kan gøres ved midlertidigt at kopiere indholdet til et skjult element med samme CSS-egenskaber og derefter bruge dets `scrollHeight` til at sætte textarea'ens højde. jQuery kan bruges til at implementere dette:

$("textarea.auto-resizable").on('input', function() { var $self = $(this); // Midlertidigt sæt højde til 'auto' for at få den faktiske scrollHeight $self.css('height', 'auto'); var scrollHeight = $self.prop('scrollHeight'); $self.css('height', scrollHeight + 'px'); }).trigger('input'); // Udløs ved initialisering 

Det er vigtigt at sikre, at CSS-egenskaber som `box-sizing`, `padding`, `border`, `font-family`, `font-size` og `line-height` er korrekt sat på textarea'en, da disse påvirker den beregnede højde.

3. Shaw's CSS Grid og Data-attribut Metode

En meget elegant løsning, der udnytter moderne CSS-funktioner, er den, som Shaw beskriver. Denne metode bruger en CSS Grid-layout og en data-*-attribut. jQuery bruges til at sætte værdien af inputfeltet som en data-*-attribut på selve inputelementet. Et pseudo-element (f.eks. ::before eller ::after) på en wrapper eller selve inputtet konfigureres til at bruge denne data-*-attribut som sit indhold. Da pseudo-elementet er en del af grid-layoutet, vil dets indhold (som er inputtets værdi) strække grid-containeren til den korrekte bredde.

Et konceptuelt eksempel:

HTML:

<div class="grid-wrapper"> <input type="text" class="resizable-grid-input" data-value="Initial" style="--input-value: 'Initial';" value="Initial"> </div>

CSS:

.grid-wrapper { display: inline-grid; } .resizable-grid-input { /* Foruddefinerede styles til input */ padding: 8px; border: 1px solid #ccc; font-family: sans-serif; font-size: 16px; } .grid-wrapper::before { content: attr(data-value); /* Eller brug CSS variabel --input-value */ display: inline-block; /* Kopier input font-styles her */ font-family: inherit; font-size: inherit; font-weight: inherit; letter-spacing: inherit; padding: 8px; border: 1px solid #ccc; box-sizing: border-box; visibility: hidden; white-space: nowrap; } /* Juster grid-layoutet baseret på pseudo-elementet */ .grid-wrapper { grid-template-columns: max-content; } 

jQuery til at opdatere data-value:

$("input.resizable-grid-input").on('input', function() { var $self = $(this); var value = $self.val(); $self.attr('data-value', value); // Opdater også CSS-variabel hvis brugt $self.css('--input-value', JSON.stringify(value)); }); 

Denne metode er effektiv, da den overlader en del af arbejdet til browserens layout-motor, men den kræver en god forståelse af CSS Grid og pseudo-elementer.

Implementeringseksempel: En Universel jQuery-funktion

Vi kan skabe en generel jQuery-funktion, der kan anvendes på ethvert inputfelt for at opnå dynamisk breddejustering. Denne funktion skal beregne den nødvendige bredde baseret på inputtets indhold, inklusive pladsholderen, og tage højde for alle relevante CSS-egenskaber.

Her er en funktion, der gør netop dette:

$.fn.autoAdjustWidth = function() { return this.each(function() { var $input = $(this); var $hiddenSpan; // Find eller opret den skjulte span $hiddenSpan = $input.siblings('.auto-adjust-span'); if ($hiddenSpan.length === 0) { $hiddenSpan = $("").css({ 'position': 'absolute', 'float': 'left', 'white-space': 'nowrap', 'visibility': 'hidden', 'display': 'inline-block' }).insertAfter($input); } // Funktion til at opdatere bredden var updateWidth = function() { var inputText = $input.val() || $input.attr('placeholder') || ''; $hiddenSpan.text(inputText); // Kopier vigtige CSS-egenskaber var computedStyle = window.getComputedStyle($input[0]); $hiddenSpan.css({ 'font-family': computedStyle.fontFamily, 'font-size': computedStyle.fontSize, 'font-weight': computedStyle.fontWeight, 'letter-spacing': computedStyle.letterSpacing, 'word-spacing': computedStyle.wordSpacing, 'text-transform': computedStyle.textTransform, 'text-rendering': computedStyle.textRendering, 'padding-left': computedStyle.paddingLeft, 'padding-right': computedStyle.paddingRight, 'padding-top': computedStyle.paddingTop, 'padding-bottom': computedStyle.paddingBottom, 'border-left-width': computedStyle.borderLeftWidth, 'border-right-width': computedStyle.borderRightWidth, 'border-top-width': computedStyle.borderTopWidth, 'border-bottom-width': computedStyle.borderBottomWidth, 'box-sizing': computedStyle.boxSizing, // Vigtigt! 'width': 'auto', // Nulstil for korrekt beregning 'height': 'auto' }); // Sæt inputfeltets bredde var spanWidth = $hiddenSpan.outerWidth(); // Håndter minimumsbredde (f.eks. baseret på padding/border) var minWidth = parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight) + parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth) || 0; // Hvis inputtet er skjult eller har display: none, brug offsetWidth if ($input.css('display') === 'none') { spanWidth = $input.prop('offsetWidth'); } // Sikr at bredden ikke er mindre end minimum var finalWidth = Math.max(spanWidth, minWidth); $input.css('width', finalWidth + 'px'); }; // Opdater ved input $input.on('input.autoAdjust', updateWidth); // Opdater ved ændring af placeholder eller CSS // Dette kan være mere komplekst og kræve MutationObserver eller specifikke events // Initial opdatering updateWidth(); }); }; // Anvend funktionen $(function() { $('input[type="text"]').autoAdjustWidth(); // Eller specifikke klasser: // $('.auto-resizing-input').autoAdjustWidth(); }); 

Denne funktion kopierer alle relevante CSS-egenskaber fra inputfeltet til den skjulte span for at sikre, at breddeberegningen er så præcis som muligt. Den håndterer også tilfælde, hvor inputfeltet måske er skjult, ved at bruge `offsetWidth`. Endelig sikrer den, at inputfeltet altid har en vis minimumsbredde, der svarer til dets padding og border.

Opsummering og Bedste Praksis

  • Overvej altid tilgængelighed. Mens contenteditable kan virke, er standard inputfelter generelt mere tilgængelige.
  • Brug jQuery til at implementere dynamisk størrelsesjustering for input og textarea.
  • Kopier relevante skrifttypeegenskaber og boks-dimensioner (padding, border) fra originalelementet til det skjulte element, der bruges til breddeberegning.
  • Husk at inkludere pladsholderteksten i beregningen, når inputfeltet er tomt.
  • For textarea, overvej at bruge `scrollHeight` for at bestemme den korrekte højde.
  • Test grundigt på tværs af forskellige browsere og enheder for at sikre ensartet adfærd.

Ved at følge disse teknikker kan du skabe mere responsive og bruger venlige webapplikationer, hvor dine inputfelter elegant tilpasser sig brugerens input.

Ofte Stillede Spørgsmål (FAQ)

Kan jeg ændre størrelsen på et jQuery-element direkte med et 'size'-attribut?
Nej, size-attributten på HTML-elementer, især inputfelter, påvirker typisk kun den oprindelige visning eller et begrænset antal tegn, og den reagerer ikke dynamisk på indholdet. For at ændre størrelsen dynamisk skal du bruge CSS og JavaScript (f.eks. jQuery) til at manipulere `width` eller `height` egenskaberne.
Hvordan sikrer jeg, at den beregnede bredde er korrekt?
Det er afgørende at kopiere alle relevante CSS-egenskaber, der påvirker tekstbredden (som font-family, font-size, font-weight, letter-spacing, padding og border), fra det originale inputfelt til det element, der bruges til at beregne bredden (f.eks. en skjult span). Korrekt håndtering af box-sizing er også vigtigt.
Hvad hvis jeg vil have inputfeltet til at skalere både bredde og højde?
For at skalere både bredde og højde (som en textarea), skal du anvende lignende principper. Bredden kan beregnes som beskrevet, og højden kan bestemmes ved at måle den nødvendige `scrollHeight` af indholdet, eventuelt ved hjælp af en skjult kopi af elementet med det aktuelle indhold.
Er der performance-overvejelser ved hyppig størrelsesjustering?
Ja, hvis størrelsesjustering sker meget hyppigt (f.eks. ved hver tastetryk), kan det potentielt påvirke performance. Det er en god idé at debounce eller throttle input-eventet, hvis du oplever problemer. Dog er moderne browsere generelt ret gode til at håndtere disse beregninger effektivt.
Hvad er forskellen mellem at bruge `width()` og `innerWidth()` / `outerWidth()` i jQuery?
width() returnerer kun bredden af indholdet. innerWidth() inkluderer padding, men ikke border. outerWidth() inkluderer både padding og border. Når du beregner den nødvendige bredde for et inputfelt, er det ofte mest præcist at bruge den metode, der bedst matcher, hvordan elementets bredde beregnes i CSS, typisk ved at tage højde for padding og border, især hvis `box-sizing` er sat til `border-box`.

Hvis du vil læse andre artikler, der ligner Tilpas elementstørrelser dynamisk med jQuery, kan du besøge kategorien Teknologi.

Go up