suchen
HeimWeb-FrontendHTML-TutorialDetaillierte Einführung in Front-End-Responsive-Programmierlösungen und deren Mängel (mit Code)

Dieser Artikel bietet Ihnen eine detaillierte Einführung in die Front-End-Responsive-Programmierung und ihre Mängel (mit Code). Ich hoffe, dass er für Sie hilfreich ist. helfen.

Viele Dinge in der realen Welt funktionieren responsiv. Wir werden beispielsweise Fragen von anderen entgegennehmen und dann antworten und entsprechende Antworten geben. Während des Entwicklungsprozesses habe ich auch viel Responsive Design angewendet und einige Erfahrungen gesammelt, in der Hoffnung, andere zu inspirieren.

Der Hauptunterschied zwischen reaktiver Programmierung und gewöhnlicher Programmierung besteht darin, dass die reaktive Programmierung im Push-Modus funktioniert, während die nicht-reaktive Programmierung im Pull-Modus funktioniert. Ereignisse sind zum Beispiel eine sehr häufige reaktive Programmierung:

button.on('click', () => {  
    // ...})

Auf nicht-reaktive Weise wird es so aussehen:

while (true) {  
    if (button.clicked) {        // ...
    }
}

Natürlich, egal ob in Bezug auf In Bezug auf Code-Eleganz und Ausführungseffizienz sind nicht-responsive Methoden nicht so gut wie responsive Designs.

Event Emitter

Event Emitter ist eine Event-Implementierung, mit der die meisten Menschen vertraut sind. Sie ist sehr einfach und praktisch. Wir können Event Emitter verwenden, um einfaches Responsivitätsdesign zu implementieren B. die folgende asynchrone Suche:

class Input extends Component {  
    state = {        value: ''
    }
    onChange = e => {        this.props.events.emit('onChange', e.target.value)
    }
    afterChange = value => {        this.setState({
            value
        })
    }
    componentDidMount() {        this.props.events.on('onChange', this.afterChange)
    }
    componentWillUnmount() {        this.props.events.off('onChange', this.afterChange)
    }
    render() {        
    const { value } = this.state        
    return (            <input value={value} onChange={this.onChange} />
        )
    }
}
class Search extends Component {  
    doSearch = (value) => {
        ajax(/* ... */).then(list => this.setState({
            list
        }))
    }
    componentDidMount() {
        this.props.events.on(&#39;onChange&#39;, this.doSearch)
    }
    componentWillUnmount() {
        this.props.events.off(&#39;onChange&#39;, this.doSearch)
    }
    render() {
        const { list } = this.state
        return (            <ul>
                {list.map(item => <li key={item.id}>{item.value}</li>)}            </ul>
        )
    }
}

Hier werden wir feststellen, dass die Implementierung von Event Emitter viele Mängel aufweist und wir Ressourcen in ComponentWillUnmount manuell freigeben müssen. Seine Ausdruckskraft reicht beispielsweise nicht aus, wenn wir bei der Suche mehrere Datenquellen aggregieren müssen:

class Search extends Component {  
    foo = &#39;&#39;
    bar = &#39;&#39;
    doSearch = () => {
        ajax({
            foo,
            bar
        }).then(list => this.setState({
            list
        }))
    }
    fooChange = value => {        this.foo = value        this.doSearch()
    }
    barChange = value => {        this.bar = value        this.doSearch()
    }
    componentDidMount() {        this.props.events.on(&#39;fooChange&#39;, this.fooChange)        this.props.events.on(&#39;barChange&#39;, this.barChange)
    }
    componentWillUnmount() {        this.props.events.off(&#39;fooChange&#39;, this.fooChange)        this.props.events.off(&#39;barChange&#39;, this.barChange)
    }
    render() {        // ...
    }
}

Offensichtlich ist die Entwicklungseffizienz sehr gering.

Redux

Redux verwendet einen Ereignisstrom, um Reaktivität zu implementieren. Da der Reduzierer eine reine Funktion sein muss, ist die einzige Möglichkeit, Reaktivität zu implementieren oder in Middleware.

Wenn Sie den Store abonnieren, kann Redux nur Dirty Checking verwenden, da es nicht genau ermitteln kann, welche Daten sich geändert haben. Zum Beispiel:

function createWatcher(mapState, callback) {  
    let previousValue = null
    return (store) => {
        store.subscribe(() => {            const value = mapState(store.getState())            if (value !== previousValue) {
                callback(value)
            }
            previousValue = value
        })
    }
}const watcher = createWatcher(state => {  
    // ...}, () => {    // ...})

watcher(store)

Diese Methode hat zwei Nachteile: Zum einen treten Effizienzprobleme auf, wenn die Daten komplex und die Datenmenge relativ groß ist ; Ja, es wäre schwierig, wenn die Funktion „mapState“ auf dem Kontext basieren würde. In React-Redux ist der zweite Parameter von MapStateToProps in der Connect-Funktion Props, die über die obere Komponente übergeben werden können, um den erforderlichen Kontext zu erhalten. Auf diese Weise wird der Listener jedoch zu einer React-Komponente und wird so gemountet, wie die Komponente Und das Entladen wird erstellt und zerstört. Wenn wir möchten, dass diese Reaktionsfähigkeit unabhängig von Komponenten ist, wird es ein Problem geben.

Eine andere Möglichkeit besteht darin, Datenänderungen in der Middleware zu überwachen. Dank des Redux-Designs können wir die entsprechenden Datenänderungen erhalten, indem wir bestimmte Ereignisse (Aktionen) abhören.

const search = () => (dispatch, getState) => {  
    // ...}const middleware = ({ dispatch }) => next => action => {  
    switch action.type {        case &#39;FOO_CHANGE&#39;:        case &#39;BAR_CHANGE&#39;: {            const nextState = next(action)            // 在本次dispatch完成以后再去进行新的dispatch
            setTimeout(() => dispatch(search()), 0)            return nextState
        }        default:            return next(action)
    }
}

Diese Methode kann die meisten Probleme lösen, aber in Redux abonnieren Middleware und Reduzierer tatsächlich implizit alle Ereignisse (Aktion), was offensichtlich unvernünftig ist, obwohl es keine Leistung gibt Unter der Prämisse der Frage ist es vollkommen akzeptabel .

Objektorientierte Reaktionsfähigkeit

ECMASCRIPT 5.1 führt Getter und Setter ein, und wir können eine Reaktionsfähigkeit durch Getter und Setter implementieren.

class Model {  
    _foo = &#39;&#39;
    get foo() {        return this._foo
    }
    set foo(value) {        this._foo = value        this.search()
    }
    search() {        // ...
    }
}// 当然如果没有getter和setter的话也可以通过这种方式实现class Model {  
    foo = &#39;&#39;
    getFoo() {        return this.foo
    }
    setFoo(value) {        this.foo = value        this.search()
    }
    search() {        // ...
    }
}

Mobx und Vue verwenden diese Methode, um Reaktionsfähigkeit zu implementieren. Natürlich können wir Proxy auch verwenden, wenn die Kompatibilität nicht berücksichtigt wird.

Wenn wir auf mehrere Werte reagieren und dann einen neuen Wert erhalten müssen, können wir dies in Mobx tun:

class Model {  
    @observable hour = &#39;00&#39;
    @observable minute = &#39;00&#39;
    @computed get time() {        return `${this.hour}:${this.minute}`
    }
}

Mobx sammelt zur Laufzeit die Werte, von denen die Zeit abhängt , und verwenden Sie diese Die Neuberechnung des Zeitwerts, wenn sich der Wert ändert (Auslösen des Setters), ist offensichtlich viel bequemer und effizienter als die EventEmitter-Methode und intuitiver als die Redux-Middleware.

Hier gibt es jedoch auch einen Nachteil. Das auf dem Getter basierende berechnete Attribut kann jedoch in vielen Fällen nur die Situation von y = f(x) beschreiben werde y = warte auf f( x), Getter kann diese Situation nicht beschreiben.

In dieser Situation können wir die von Mobx bereitgestellte Autorun-Funktion verwenden, um Folgendes zu erreichen:

class Model {  
    @observable keyword = &#39;&#39;
    @observable searchResult = []    constructor() {
        autorun(() => {            // ajax ...
        })
    }
}

Da der Erfassungsprozess von Laufzeitabhängigkeiten vollständig implizit ist, tritt hier häufig ein Problem bei der Erfassung unerwarteter Abhängigkeiten auf:

class Model {  
    @observable loading = false
    @observable keyword = &#39;&#39;
    @observable searchResult = []    constructor() {
        autorun(() => {            if (this.loading) {                return
            }            // ajax ...
        })
    }
}

Offensichtlich sollte das Laden hier nicht durch den gesuchten Autorun erfasst werden. Um dieses Problem zu lösen, wird etwas zusätzlicher Code hinzugefügt, und der zusätzliche Code birgt leicht die Möglichkeit für Fehler. Alternativ können wir die erforderlichen Felder auch manuell angeben, aber diese Methode erfordert einige zusätzliche Vorgänge:

class Model {  
    @observable loading = false
    @observable keyword = &#39;&#39;
    @observable searchResult = []
    disposers = []
    fetch = () => {        // ...
    }
    dispose() {        this.disposers.forEach(disposer => disposer())
    }    constructor() {        this.disposers.push(
            observe(this, &#39;loading&#39;, this.fetch),
            observe(this, &#39;keyword&#39;, this.fetch)
        )
    }
}class FooComponent extends Component {  
    this.mode = new Model()
    componentWillUnmount() {        this.state.model.dispose()
    }    // ...}

Und wenn wir die Zeitleiste beschreiben müssen, ist Mobx etwas unzureichend. Beispielsweise müssen Sie die Suche verzögern 5 Sekunden.

Verwandte Empfehlungen:

Puzzle-responsive Front-End-Framework-Version des responsiven Backends offiziell veröffentlicht_html/css_WEB-ITnose

Verwendung ein sehr einfaches responsives Front-End-Entwicklungsframework_html/css_WEB-ITnose


Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in Front-End-Responsive-Programmierlösungen und deren Mängel (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Sind die HTML -Tags und Elemente dasselbe?Sind die HTML -Tags und Elemente dasselbe?Apr 28, 2025 pm 05:44 PM

Der Artikel erklärt, dass HTML -Tags Syntaxmarker sind, die zum Definieren von Elementen verwendet werden, während Elemente vollständige Einheiten einschließlich Tags und Inhalt sind. Sie arbeiten zusammen, um Webseiten zu strukturieren.Character Count: 159

Welche Bedeutung hat der Kopf & gt; und & lt; Körper & gt; Tag in HTML?Welche Bedeutung hat der Kopf & gt; und & lt; Körper & gt; Tag in HTML?Apr 28, 2025 pm 05:43 PM

Der Artikel erörtert die Rollen von & lt; Head & gt; und & lt; Körper & gt; Tags in HTML, ihre Auswirkungen auf die Benutzererfahrung und die SEO -Auswirkungen. Die ordnungsgemäße Strukturierung verbessert die Funktionen der Website und die Suchmaschinenoptimierung.

Was ist der Unterschied zwischen & lt; stark & ​​gt;, & lt; b & gt; Tags und & lt; em & gt;, & lt; i & gt; Tags?Was ist der Unterschied zwischen & lt; stark & ​​gt;, & lt; b & gt; Tags und & lt; em & gt;, & lt; i & gt; Tags?Apr 28, 2025 pm 05:42 PM

Der Artikel erörtert die Unterschiede zwischen HTML -Tags, und sich auf ihre semantischen und präsentierenden Verwendungen und ihre Auswirkungen auf SEO und Barrierefreiheit konzentrieren.

Bitte erklären Sie, wie Sie den Zeichensatz angeben, der von einem Dokument in HTML verwendet wird.Bitte erklären Sie, wie Sie den Zeichensatz angeben, der von einem Dokument in HTML verwendet wird.Apr 28, 2025 pm 05:41 PM

In Artikel wird die Angabe der Charaktercodierung in HTML erläutert, die sich auf UTF-8 konzentriert. Hauptproblem: Sicherstellen, dass die korrekte Anzeige des Textes verstümmelt und die SEO und die Zugänglichkeit verbessert werden.

Was sind die verschiedenen Formatierungs -Tags in HTML?Was sind die verschiedenen Formatierungs -Tags in HTML?Apr 28, 2025 pm 05:39 PM

In dem Artikel werden verschiedene HTML -Formatierungs -Tags erörtert, die zur Strukturierung und Styling -Webinhalte verwendet werden, wodurch ihre Auswirkungen auf das Erscheinungsbild von Text und die Bedeutung semantischer Tags für Barrierefreiheit und SEO betont werden.

Was ist der Unterschied zwischen dem Attribut 'ID' und dem Attribut 'Klasse' von HTML -Elementen?Was ist der Unterschied zwischen dem Attribut 'ID' und dem Attribut 'Klasse' von HTML -Elementen?Apr 28, 2025 pm 05:39 PM

Der Artikel erörtert die Unterschiede zwischen den Attributen von HTMLs "ID" und "Klasse" und konzentriert sich auf ihre Einzigartigkeit, ihren Zweck, ihre CSS -Syntax und ihre Spezifität. Es erklärt, wie sich ihre Verwendung auf das Webseite und die Funktionalität des Webseite auswirkt, und bietet Best Practices für

Was ist das Attribut 'Klassen' in HTML?Was ist das Attribut 'Klassen' in HTML?Apr 28, 2025 pm 05:37 PM

Der Artikel erläutert die Rolle des HTML -Class -Attributs bei der Gruppierung von Elementen für Styling und JavaScript -Manipulation und kontrastiert sie mit dem eindeutigen 'ID' -attribut.

Was sind verschiedene Arten von Listen in HTML?Was sind verschiedene Arten von Listen in HTML?Apr 28, 2025 pm 05:36 PM

In Artikel werden HTML -Listen -Typen erörtert: bestellt (& lt; ol & gt;), ungeordnet (& lt; ul & gt;) und Beschreibung (& lt; dl & gt;). Konzentriert sich auf das Erstellen und Styling -Listen, um das Website -Design zu verbessern.

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

mPDF

mPDF

mPDF ist eine PHP-Bibliothek, die PDF-Dateien aus UTF-8-codiertem HTML generieren kann. Der ursprüngliche Autor, Ian Back, hat mPDF geschrieben, um PDF-Dateien „on the fly“ von seiner Website auszugeben und verschiedene Sprachen zu verarbeiten. Es ist langsamer und erzeugt bei der Verwendung von Unicode-Schriftarten größere Dateien als Originalskripte wie HTML2FPDF, unterstützt aber CSS-Stile usw. und verfügt über viele Verbesserungen. Unterstützt fast alle Sprachen, einschließlich RTL (Arabisch und Hebräisch) und CJK (Chinesisch, Japanisch und Koreanisch). Unterstützt verschachtelte Elemente auf Blockebene (wie P, DIV),

Sicherer Prüfungsbrowser

Sicherer Prüfungsbrowser

Safe Exam Browser ist eine sichere Browserumgebung für die sichere Teilnahme an Online-Prüfungen. Diese Software verwandelt jeden Computer in einen sicheren Arbeitsplatz. Es kontrolliert den Zugriff auf alle Dienstprogramme und verhindert, dass Schüler nicht autorisierte Ressourcen nutzen.

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

SecLists

SecLists

SecLists ist der ultimative Begleiter für Sicherheitstester. Dabei handelt es sich um eine Sammlung verschiedener Arten von Listen, die häufig bei Sicherheitsbewertungen verwendet werden, an einem Ort. SecLists trägt dazu bei, Sicherheitstests effizienter und produktiver zu gestalten, indem es bequem alle Listen bereitstellt, die ein Sicherheitstester benötigen könnte. Zu den Listentypen gehören Benutzernamen, Passwörter, URLs, Fuzzing-Payloads, Muster für vertrauliche Daten, Web-Shells und mehr. Der Tester kann dieses Repository einfach auf einen neuen Testcomputer übertragen und hat dann Zugriff auf alle Arten von Listen, die er benötigt.

SAP NetWeaver Server-Adapter für Eclipse

SAP NetWeaver Server-Adapter für Eclipse

Integrieren Sie Eclipse mit dem SAP NetWeaver-Anwendungsserver.