Как обработать «намерение открыть ссылку на новой странице» в приложении SPA? - PullRequest
7 голосов
/ 04 июля 2019

Ну, в моем (реагирующем) одностраничном приложении у меня много "внутренних ссылок". Эти ссылки работают путем изменения URL-адреса с помощью хранилища маршрутизатора. (Mobx + реагируют).

Поскольку html-стандарты предостерегают от использования href без фактического href, и если используется событие on_click, следует использовать стиль кнопки, похожий на ссылку.

Это прекрасно работает. За исключением того, что теперь я хочу улучшить использование, я хочу позволить потребителям нажимать Ctrl + щелчок, среднюю мышь или любую другую комбинацию клавиш эзотерического браузера, который использует пользователь, чтобы «открыть ссылку в новой вкладке».

Есть ли способ получить «намерение» клика браузером? - чтобы увидеть, было ли намерение пользователя открыть ссылку (кнопку) в новой вкладке?

Не позволяя пользователю перезагрузить страницу при обычном нажатии на ссылку?

Или с другой стороны: как я могу предотвратить перезагрузку полной страницы при нажатии на ссылку, которая является относительным URL и открывается в том же окне?

Ответы [ 3 ]

0 голосов
/ 09 июля 2019
function Anchor(props) {
    const {href, children} = props;
    function handleClick(e) {
        if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey) return; // let the browser handle
        e.preventDefault(); // take over
        try {
            window.history.pushState(null, null, href);
        } catch {
            window.location.assign(href);
        }
    }
    return <a {...props} onClick={handleClick}>{children}</a>
}

Использование, как тег <a>:

<Anchor href="/other-page">Go to Other Page</Anchor>
0 голосов
/ 15 июля 2019

Итак. React-router-dom имеет компонент под названием «Link».Который отлично справляется с этим вариантом использования ..

Вот фрагмент кода из компонента Link, скопированного из response-routerrepo.

function isModifiedEvent(event) {
  return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
}

function LinkAnchor({ innerRef, navigate, onClick, ...rest }) {
  const { target } = rest;

  return (
    <a
      {...rest}
      ref={innerRef} // TODO: Use forwardRef instead
      onClick={event => {
        try {
          if (onClick) onClick(event);
        } catch (ex) {
          event.preventDefault();
          throw ex;
        }

        if (
          !event.defaultPrevented && // onClick prevented default
          event.button === 0 && // ignore everything but left clicks
          (!target || target === "_self") && // let browser handle "target=_blank" etc.
          !isModifiedEvent(event) // ignore clicks with modifier keys
        ) {
          event.preventDefault();
          navigate();
        }
      }}
    />
  );
}

Вы можете просто немного изменить этот компонент в соответствии с вашим вариантом использования,Попробуйте сделать это HOC или, возможно, используйте шаблон renderProps для рендеринга вашего контента внутри этой якорной ссылки

Надеюсь, это поможет ..

0 голосов
/ 09 июля 2019

Попробуйте использовать Link, он работает в обоих направлениях:

import {Link} from 'mobx-router';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...