С помощью реагирующих веб-вкладок можно ли переключать вкладки и переходить к хешированному идентификатору с помощью щелчка? - PullRequest
0 голосов
/ 14 февраля 2019

Я создаю веб-сайт конференции, используя три из этих вкладок (#speaker, #talks, #schedule).Я думаю, что справедливо хотеть взаимодействия между вкладками, вот пара вариантов использования, которые я не могу решить.

  1. На вкладке #talks я нажимаю на био-хеш - #johnsmith.Этот идентификатор существует на странице, но поскольку я сначала не переключаю вкладку на #speakers, ничего не отображается.
  2. Если я хочу сослаться на конкретную беседу и отправить кому-то URL-адрес: https://website.com #speaker_name вкладки не будут открываться, и ничего, кроме вкладок, не будет отображаться.

Проблема усугубляется тем фактом, что, когда я нажимаю на тег привязки href, используя '#id',Я должен перезагрузить страницу, чтобы она открылась.

Мне кажется, что должен быть какой-то способ передачи параметра при смене вкладки или что-то ... Я в трудном положениипотому что я выкатываю код, но очень нуждаюсь в этой функциональности.

Вот реальное хранилище с открытым исходным кодом - https://github.com/kernelcon/website. Код, на который я ссылаюсь, можно найти в src / pages / Agenda/.

Вот пример кода.

Agenda.js

  <Tabs defaultTab={this.state.defaultTab}
    onChange={(tabId) => { this.changeTab(tabId) }}
    vertical={vert}>
    <TabList vertical>
      <Tab tabFor="speakers">Speakers</Tab>
      <Tab tabFor="talks">Talks</Tab>
    <span>
      <TabPanel tabId="speakers">
        <Speakers />
      </TabPanel>
      <TabPanel tabId="talks">
        <Talks />
      </TabPanel>
    </span>
  </Tabs>

Talks.js

changeTab(id) {
  window.location.reload(false); 
}

getTalks() {
  // Order Alphabetically
  const talksOrdered = speakerConfig.sort((a,b) => (a.title > b.title) ? 1 : ((b.title > a.title) ? -1 : 0));
  const talks = talksOrdered.map((ele, idx) => {
    const twitterUrl = ele.twitter.replace('@', '');

    return (
      <div id={ele.talk_id}
        key={idx}
        className='single-talk'>
        <div className='talk-title'>{ele.title}</div>
        <div className='talk-sub-title'>
          <div className='speaker-name'>
            <a onClick={() => {this.changeTab(ele.speaker_id)}}
              href={`#${ele.speaker_id}`}>{ele.speaker}</a>
          </div>
        ...

1 Ответ

0 голосов
/ 17 февраля 2019

Я закончил, отправив #tab_title/speaker_name, а затем добавил метод и функцию жизненного цикла componentWillMount в файл основной вкладки, как показано ниже.

componentWillMount() {
  const defaultTab = this.props.location.hash ? this.props.location.hash.split('#')[1] : 'schedule';
  this.setState({
    defaultTab: defaultTab
  });
  this.handleHashChange();
  window.addEventListener('hashchange', this.handleHashChange);
}
handleHashChange = () => {
  // given `#speakers/dave` now you have tabName='speakers', speakerHash='dave'
  const [tabName, speakerHash] = window.location.hash.replace('#', '').split('/');
  const tabNamesToWatchFor = [
    'schedule',
    'speakers'
  ];

  if (tabNamesToWatchFor.includes(tabName)) {
    this.setState({
      defaultTab: tabName,
      // pass this.state.speakerHash to <Speakers/> and use this for scrollIntoView in componentDidMount
      speakerHash: speakerHash
    });
  }
}

Далее я перешел на отдельную вкладку (в этом случае Speakers.js) и добавили метод componentDidMount и componentDidUpdate, чтобы помочь прокрутить сам динамик.

componentDidMount() {
  this.handleScrollToSpeaker(this.props.speakerHash);
}
componentDidUpdate(prevProps) {
  if (prevProps.speakerHash !== this.props.speakerHash) {
    this.handleScrollToSpeaker(this.props.speakerHash);
  }
}
handleScrollToSpeaker = hash => {
    window.setTimeout(() => {
      const ele = document.querySelector(`#${hash}`);
      if (ele) {
        ele.scrollIntoView({ block: 'start',  behavior: 'smooth' });
      }
    }, 500)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...