2015-08-27 15 views
10

Bazı temel tuşa basma algılamalarını uygulamaya çalışıyorum ve hiç işe yaramayacağım.Anahtar aşağı olaya tepki vermeme tepkisi

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    } 

    handleKeyDown(event) { 
    console.log('handling a key press'); 
    } 

    render() { 
    return (
     <ChildComponent onKeyDown={this.handleKeyDown} /> 
    ); 
    } 
} 

React.render(<App />, document.getElementById('app')); 

cevap

4

sorun ChildComponent bir bileşen ama bir bileşenidir fabrika olmadığıdır. Bu fabrika ile oluşturulan elemanın oluşturulması sonucu değiştirilecektir.

ChildComponent'u bir div içine yerleştirin ve herhangi bir olay dinleyicisini, ChildComponent değil, div'e ekleyin. Satır içi ekrana ihtiyacınız varsa <div>'u <span> ile değiştirin.

let {Component} = React; 

class ChildComponent extends Component { 
    render() { 
    return (<child-component>click me</child-component>); 
    } 
} 

class App extends Component { 
    handleClick(event) { 
    console.log('handling a key press'); 
    } 

    render() { 
    return (<div onClick={this.handleClick}><ChildComponent /></div>); 
    } 
} 

React.render(<App />, document.getElementById('app')); 

DOM öğesi klavye olayı almak için odaklanmış olmak istiyor codepen

+0

Bunu da stilleri uygulamaya çalıştığını fark ettim. Bileşenin içindeki en üst düzey DOM öğesine başvurmak yerine, stiller sadece yere bırakılır. –

28

Sen elemanı (örneğin sarma elemanı) için tabIndex -attribute atamanız gerekir: Ben onKeyDown olay ama hiçbir şey üzerinde toplayıp gereken konsolda çıkış yapmış olur çıplak bileşeni var bunun için tuşa basmak. Sonra sahne ile kendisine keyDown işleyicisi geçmesi: takımım üzerinde çalışıyor Bir uygulama içinde

import React from 'react'; 
import { render } from 'react-dom'; 

class ChildComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    } 
    render() { 
    return (
     <div tabIndex="0" onKeyDown={this.props.handleKeyDown}>Fooo</div> 
    ); 
    } 
} 

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    } 

    handleKeyDown(event) { 
    console.log('handling a key press'); 
    } 

    render() { 
    return (
     <ChildComponent handleKeyDown={() => this.handleKeyDown()} /> 
    ); 
    } 
} 

render(<App />, document.getElementById('app')); 
+0

Bir sekme dizinine neden ihtiyaç duyulur? – user1095118

+1

@ user1095118 Linkler ve form öğelerinin yanında bulunan elemanların klavye odağı ve bu sayede tuş basışlarını alabilmelerinin tek yolu budur. Yerel sekme sırasını geçersiz kılmamak için sıfıra ayarlanır. Daha fazla bilgi için http://webaim.org/techniques/keyboard/tabindex adresine bakın. –

0

, biz react-hotkey kullanıyoruz. Ne yazık ki, React, ES6 sözdizimi ile karmaları desteklemiyor gibi görünüyor, ancak biraz bebekle havalıysanız, bunu deneyebilirsiniz.

let App = React.createClass({ 
    mixins: [hotkey.Mixin('handleKeyDown')], 

    componentDidMount() { 
    hotkey.activate(); 
    }, 

    componentWillUnmount() { 
    hotkey.disable(); 
    }, 

    handleKeyDown(event) { 
    console.log('handling a key press'); 
    }, 

    render() { 
    return (
     <ChildComponent /> 
    ); 
    } 
}); 

React.render(<App />, document.getElementById('app')); 
6

üzerine görün Yürüt. Öğeyi odaklamak için öğeyi tabIndex veya contentEditable ile kesmek istemiyorsanız, yerel DOM olay dinleyicilerini window'da kullanabilir ve klavye bileşenlerini işleyen her bileşende farklı bir işleyici tanımlayabilirsiniz.

Sadece bu bileşen bağını çözmek böylece tüm bileşenleri her zaman işlememesi olay dinleyicisi kaldırmak emin olun: Ayrıca

componentWillMount: function() { 
    window.addEventListener('keydown', this.handleKeyDown); 
    }, 

    componentWillUnmount: function() { 
    window.removeEventListener('keydown', this.handleKeyDown); 
    }, 

, o kolay olacaksa benzer işlevler sağlayan bir npm var gibi görünmektedir: https://www.npmjs.com/package/react-keydown

+0

'Bu' bileşeninin 'Bu' bileşeni olmasını istiyorsanız, olay işleyicinizi bağdaştırmayı unutmayın: 'this.handleKeyDown = this.handleKeyDown.bind (this)' – boxtrain

+0

her zaman değil. Yalnızca bu bileşenin de bu olayları ele alması gerekiyorsa, kendisine bağlamanız yeterlidir. Karmaşık kullanıcı arayüzü (web uygulamaları gibi) için, tüm kullanıcılara TÜM kullanıcı olaylarını yöneten ve yönlendiren 'InputHandler' sınıflarını kullanıyorum. her bir/tüm bileşenlerin kendi işleme işlevlerine sahip olmasından daha iyidir, çünkü eğer pencere üzerinde birden fazla tuş dinleyicileri eklenirse, 'handleKeydowns' bileşeninin tümü, olayı tüm olayları ele alan 1 'InputHandler 'ile ele geçirmeye çalışır. Ayrıca, taşıma işlevinde 'bu' ile hiçbir şey yapılmadığı bir durum söz konusudur - bu durumda bağlamanız da gerekmez. – Benny