Algum de vocês sabe como lidar bem com links de hash de âncora no AngularJS ?
Eu tenho a seguinte marcação para uma página de FAQ simples
<a href="#faq-1">Question 1</a>
<a href="#faq-2">Question 2</a>
<a href="#faq-3">Question 3</a>
<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="fa1-3">Question 3</h3>
Ao clicar em qualquer um dos links acima, o AngularJS intercepta e direciona-me para uma página completamente diferente (no meu caso, uma página 404, pois não há rotas correspondentes aos links).
Meu primeiro pensamento foi criar uma rota correspondente a " / faq /: chapter " e, no controlador correspondente, verificar $routeParams.chapter
após um elemento correspondente e, em seguida, usar o jQuery para rolar para baixo.
Mas então o AngularJS caga em mim novamente e apenas rola para o topo da página de qualquer maneira.
Então, alguém aqui fez algo semelhante no passado e conhece uma boa solução para isso?
Edit: Mudar para html5Mode deve resolver meus problemas, mas meio que precisamos oferecer suporte ao IE8 + de qualquer maneira, por isso, temo que não seja uma solução aceita: /
fonte
ng-href=""
lugar.Respostas:
Você está procurando
$anchorScroll()
.Aqui está a documentação (de baixa qualidade).
E aqui está a fonte.
Basicamente, você apenas injeta e chama no seu controlador, e ele irá rolar para qualquer elemento com o ID encontrado em
$location.hash()
Aqui está um desentupidor para demonstrar
EDIT: para usar isso com roteamento
Configure seu roteamento angular como de costume e adicione o código a seguir.
e seu link ficaria assim:
Aqui está um Plunker demonstrando rolagem com roteamento e $ anchorScroll
E ainda mais simples:
e seu link ficaria assim:
fonte
<a href="#foo">foo</a>
. Meu exemplo de código foi mostrar a rolagem para um ID na mudança de rota.$location.search('scrollTo', null)
No meu caso, notei que a lógica de roteamento estava ativando se eu modificasse o
$location.hash()
. O seguinte truque funcionou ..fonte
$location.hash(my_id); $anchorScroll; $location.hash(null)
. Isso impede a recarga e não preciso gerenciar aold
variável.Não há necessidade de alterar nenhum roteamento ou qualquer outra coisa, basta usar
target="_self"
ao criar os linksExemplo:
E use o
id
atributo em seus elementos html como este:Não há necessidade de usar ## como apontado / mencionado nos comentários ;-)
fonte
fonte
Se você sempre conhece a rota, pode simplesmente acrescentar a âncora assim:
onde
route
é a rota angular atual eanchorID
corresponde a<a id="anchorID">
algum lugar da páginafonte
reloadOnSearch: false
para essa rota na configuração de suas rotas, angular não acionará uma alteração de rota e apenas rolará para o ID. Em combinação com a rota completa especificada naa
tag, eu diria que esta é a solução mais simples e direta.$anchorScroll
funciona para isso, mas há uma maneira muito melhor de usá-lo nas versões mais recentes do Angular.Agora,
$anchorScroll
aceita o hash como um argumento opcional, para que você não precise alterar$location.hash
nada. ( documentação )Esta é a melhor solução porque não afeta a rota. Não consegui que nenhuma das outras soluções funcionasse porque estou usando o ngRoute e a rota seria recarregada assim que eu definia
$location.hash(id)
, antes que$anchorScroll
pudesse fazer sua mágica.Aqui está como usá-lo ... primeiro, na diretiva ou controlador:
e depois na visualização:
Além disso, se você precisar contabilizar uma barra de navegação fixa (ou outra interface do usuário), poderá definir o deslocamento para $ anchorScroll assim (na função de execução do módulo principal):
fonte
id
nessa visualização.ngRoute
e a versão mais recente do Angular.Esta foi a minha solução usando uma diretiva que parece mais angular porque estamos lidando com o DOM:
Plnkr aqui
github
CÓDIGO
HTML
Eu usei o serviço $ anchorScroll. Para neutralizar a atualização de página que acompanha a alteração de hash, fui adiante e cancelei o evento locationChangeStart. Isso funcionou para mim porque eu tinha uma página de ajuda conectada a um comutador de ng e as atualizações quebrariam essencialmente o aplicativo.
fonte
Tente definir um prefixo de hash para rotas angulares
$locationProvider.hashPrefix('!')
Exemplo completo:
fonte
Eu contornei isso na lógica de rota do meu aplicativo.
fonte
Este é um post antigo, mas passei muito tempo pesquisando várias soluções, então queria compartilhar mais um. Apenas adicionando
target="_self"
ao<a>
tag corrigiu isso para mim. O link funciona e me leva ao local apropriado na página.No entanto, o Angular ainda injeta alguma estranheza com o # no URL, para que você possa ter problemas ao usar o botão Voltar para navegação e outros itens depois de usar esse método.
fonte
Esse pode ser um novo atributo para o ngView, mas eu consegui obter links de hash âncora para trabalhar
angular-route
usando ongView autoscroll
atributo e 'double-hashes'.ngView (consulte rolagem automática)
(O código a seguir foi usado com fita angular)
fonte
Eu poderia fazer assim:
fonte
Aqui está uma solução alternativa suja, criando uma diretiva personalizada que rolará para o elemento especificado (com "faq" codificado)
http://plnkr.co/edit/Po37JFeP5IsNoz5ZycFs?p=preview
fonte
$anchorScroll
, veja minha resposta.fonte
Se você não gosta de usar,
ng-click
aqui está uma solução alternativa. Ele usa afilter
para gerar a URL correta com base no estado atual. Meu exemplo usa ui.router .O benefício é que o usuário verá onde o link fica pairando.
O filtro:
fonte
Minha solução com ng-route foi esta diretiva simples:
O html é parecido com:
fonte
scroll-to="yourid"
e nomeie a directivascrollTo
(e acesso ao atributo comoattrs["scrollTo"]
? Além disso, sem a inclusão jQuery explicite o manipulador tem de ser preso comelement.on('click', function (e) {..})
.Você pode tentar usar o anchorScroll .
Exemplo
Portanto, o controlador seria:
E a vista:
... e nenhum segredo para o ID da âncora:
fonte
Eu estava tentando fazer meu aplicativo Angular rolar para um carregamento de âncora e ver as regras de reescrita de URL de $ routeProvider.
Após longa experimentação, decidi sobre isso:
fonte
Não tenho 100% de certeza se isso funciona o tempo todo, mas no meu aplicativo isso me dá o comportamento esperado.
Digamos que você esteja na página SOBRE e tenha a seguinte rota:
Agora, no seu HTML
Em conclusão
Incluir o nome da página antes da âncora fez o truque para mim. Deixe-me saber sobre seus pensamentos.
Desvantagem
Isso renderizará novamente a página e depois role para a âncora.
ATUALIZAR
Uma maneira melhor é adicionar o seguinte:
fonte
Obtenha seu recurso de rolagem facilmente. Ele também suporta rolagem Animated / Smooth como um recurso adicional. Detalhes para a biblioteca de rolagem angular :
Github - https://github.com/oblador/angular-scroll
Bower :
bower install --save angular-scroll
npm :
npm install --save angular-scroll
Versão Minfied - apenas 9kb
Rolagem suave (rolagem animada) - sim
Scroll Spy - sim
Documentação - excelente
Demonstração - http://oblador.github.io/angular-scroll/
Espero que isto ajude.
fonte
Baseado em @Stoyan, eu vim com a seguinte solução:
fonte
Na mudança de rota, ele rolará para o topo da página.
coloque esse código no seu controlador.
fonte
Na minha opinião, o @slugslog tinha, mas eu mudaria uma coisa. Eu usaria substituir, para que você não precise configurá-lo novamente.
Documentos Pesquisa por "Substituir método"
fonte
Nenhuma das soluções acima funciona para mim, mas tentei isso e funcionou,
Então percebi que precisava notificar a página para começar com a página de índice e depois usar a âncora tradicional.
fonte
Em algum momento, a navegação por hash do aplicativo angularjs não funciona e as bibliotecas jquery javascript de bootstrap fazem uso extensivo desse tipo de navegação, para que ele funcione e seja adicionado
target="_self"
à tag anchor. por exemplo<a data-toggle="tab" href="#id_of_div_to_navigate" target="_self">
fonte
Consulte https://code.angularjs.org/1.4.10/docs/api/ngRoute/provider/ $ routeProvider
Definir isso como falso fez o truque sem todas as opções acima para mim.
fonte
Estou usando o AngularJS 1.3.15 e parece que não preciso fazer nada de especial.
https://code.angularjs.org/1.3.15/docs/api/ng/provider/ $ anchorScrollProvider
Então, o seguinte funciona para mim no meu html:
Não precisei fazer nenhuma alteração no meu controlador ou JavaScript.
fonte