nhảy neo bằng cách sử dụng javascript


129

Tôi có một câu hỏi sẽ được tìm thấy rất thường xuyên. Vấn đề là không nơi nào có thể tìm thấy một giải pháp rõ ràng.

Tôi có hai vấn đề liên quan đến neo.

Mục tiêu chính là để có được một url sạch đẹp mà không có bất kỳ băm nào trong đó trong khi sử dụng các ký tự liên kết để nhảy trên một trang.

Vì vậy, cấu trúc của các neo là:

<ul>
    <li><a href="#one">One</a></li>
    <li><a href="#two">Two</a></li>
    <li><a href="#three">Three</a></li>
</ul>

<div class="wrap">
    <a name="one">text 1</a>
    <a name="two">text 2</a>
    <a name="three" class="box">text 3</a>
</div>

Được rồi, nếu bạn nhấp vào một trong các liên kết, url sẽ tự động thay đổi thành

www.domain.com/page#1

Cuối cùng, điều này chỉ là:

www.domain.com/page

Càng xa càng tốt. Bây giờ điều thứ hai là, khi bạn tìm kiếm trên internet cho vấn đề đó, bạn sẽ tìm thấy javascriptnhư một giải pháp.

Tôi đã tìm thấy chức năng này:

function jumpto(anchor){
    window.location.href = "#"+anchor;
}

và gọi hàm đó với:

<a onclick="jumpto('one');">One</a>

những gì sẽ giống như trước đây. Nó sẽ thêm băm vào url. Tôi cũng đã thêm

<a onclick="jumpto('one'); return false;">

không thành công. Vì vậy, nếu có ai đó có thể cho tôi biết cách giải quyết điều này tôi thực sự sẽ đánh giá cao.

Cảm ơn rất nhiều.


Không chắc chắn về điều này, nhưng bạn có thể thử viết thủ công vào thuộc tính băm sau khi nhảy. Ví dụ: đặt thời gian chờ trong trình xử lý onclick sẽ đặt window.location.hash=''.
Jeff

Bạn có nghĩa là bạn không muốn có # hiển thị trong URL khi chuyển đến phần khác trong cùng một trang web?
Roger Ng

2
Trong trường hợp đó, bạn sẽ phải điều khiển scrollTop của cửa sổ, thông thường bằng window.scrollTohoặc trình trợ giúp jQuery tương ứng: stackoverflow.com/questions/6677035/jquery-scroll-to-element hoặc stackoverflow.com/questions/500336/ tựa
Frank van Puffelen

@Jeff - Nếu bạn làm location.hash='', phần #còn lại ở đó.
Derek 朕 會

Đừng làm như thế làm ơn. Băm là tốt khi lưu trang trong dấu trang của bạn.
Marco Sulla

Câu trả lời:


204

Bạn có thể lấy tọa độ của phần tử đích và đặt vị trí cuộn cho nó. Nhưng điều này quá phức tạp.

Đây là một cách lười biếng hơn để làm điều đó:

function jump(h){
    var url = location.href;               //Save down the URL without hash.
    location.href = "#"+h;                 //Go to the target element.
    history.replaceState(null,null,url);   //Don't like hashes. Changing it back.
}

Điều này sử dụng replaceStateđể thao tác url. Nếu bạn cũng muốn hỗ trợ cho IE , thì bạn sẽ phải thực hiện theo cách phức tạp :

function jump(h){
    var top = document.getElementById(h).offsetTop; //Getting Y of target element
    window.scrollTo(0, top);                        //Go there directly or some transition
}​

Bản trình diễn: http://jsfiddle.net/DerekL/rEpPA/
Một bản chuyển đổi khác: http://jsfiddle.net/DerekL/x3edvp4t/

Bạn cũng có thể sử dụng .scrollIntoView:

document.getElementById(h).scrollIntoView();   //Even IE6 supports this

(Vâng, tôi đã nói dối. Nó không phức tạp chút nào.)


1
Chuột !! Liên kết bị hỏng :-( Tôi nghĩ rằng JS Fiddles ở đó mãi mãi
Mawg nói rằng phục hồi Monica

1
@Mawg Rõ ràng họ đã loại bỏ khả năng sử dụng add /showở cuối url.
Derek 朕 會

11
"Ngay cả IE6 cũng hỗ trợ điều này" là bình luận tốt nhất tôi từng thấy.
Josh

3
@Black Không có thứ nào như là một phần tử jQuery jQuery. Nếu bạn muốn lấy phần tử đầu tiên ra khỏi truy vấn của mình, hãy làm $(mySelector)[0].scrollIntoView().
Derek 朕 會

4
1+ cho scrollIntoView. 1- để đề cập đến nó cuối cùng.
Yay295

12

Tôi nghĩ đó là giải pháp đơn giản hơn nhiều:

window.location = (""+window.location).replace(/#[A-Za-z0-9_]*$/,'')+"#myAnchor"

Phương pháp này không tải lại trang web và đặt trọng tâm vào các neo cần thiết cho trình đọc màn hình.


Và những gì hiếm khi hoạt động trên IE, điều này hoạt động trên tất cả IE;)
Adam111p

5
Tôi đã kết thúc vớiwindow.location = window.location.origin + window.location.pathname + '#hash';
Alex

Điều này tải lại trang cho tôi. Câu trả lời được chấp nhận đã kết thúc, tuy nhiên, tôi ước nó ngắn hơn.
Hold OfferHunger

3

Không đủ đại diện cho một bình luận.

Phương thức dựa trên getEuityById () trong câu trả lời được chọn sẽ không hoạt động nếu neo có namenhưng không idđược đặt (không được khuyến nghị, nhưng xảy ra trong tự nhiên).

Cần lưu ý điều gì đó nếu bạn không có quyền kiểm soát đánh dấu tài liệu (ví dụ: webextension).

Các locationphương pháp có trụ sở tại câu trả lời được lựa chọn cũng có thể được đơn giản hóa với location.replace:

function jump(hash) { location.replace("#" + hash) }

1

Bởi vì khi bạn làm

window.location.href = "#"+anchor;

Bạn tải một trang mới, bạn có thể làm:

<a href="#" onclick="jumpTo('one');">One</a>
<a href="#" id="one"></a>

<script>

    function getPosition(element){
        var e = document.getElementById(element);
        var left = 0;
        var top = 0;

        do{
            left += e.offsetLeft;
            top += e.offsetTop;
        }while(e = e.offsetParent);

        return [left, top];
    }

    function jumpTo(id){    
        window.scrollTo(getPosition(id));
    }

</script>

3
Tôi không nghĩ việc thêm băm làm cho nó trở thành một trang mới.
Derek 朕 會

5
Nó không tải lại trang.
Derek 朕 會

Bạn đúng nó không tải lại trang. Tôi thử trong giao diện điều khiển với chrome và favicon được tải lại.
Jonathan Vukovich-Tribouharet

Trong Firefox mới nhất, các thay đổi băm dường như buộc tải lại cho iFrames (trong thuộc tính src). Tôi coi đây là một lỗi trình duyệt, nhưng cần phải biết.
Beejor

1

Tôi có một nút cho lời nhắc rằng khi nhấp vào nó sẽ mở hộp thoại hiển thị và sau đó tôi có thể viết những gì tôi muốn tìm kiếm và nó đi đến vị trí đó trên trang. Nó sử dụng javascript để trả lời tiêu đề.

Trên tệp .html tôi có:

<button onclick="myFunction()">Load Prompt</button>
<span id="test100"><h4>Hello</h4></span>

Trên tệp .js tôi có

function myFunction() {
    var input = prompt("list or new or quit");

    while(input !== "quit") {
        if(input ==="test100") {
            window.location.hash = 'test100';
            return;
// else if(input.indexOf("test100") >= 0) {
//   window.location.hash = 'test100';
//   return;
// }
        }
    }
}

Khi tôi viết test100 vào dấu nhắc, nó sẽ đi đến nơi tôi đã đặt span id = "test100" trong tệp html.

Tôi sử dụng Google Chrome.

Lưu ý: Ý tưởng này xuất phát từ việc liên kết trên cùng một trang bằng cách sử dụng

<a href="#test100">Test link</a>

mà nhấp chuột sẽ gửi đến neo. Để nó hoạt động nhiều lần, từ kinh nghiệm cần phải tải lại trang.

Tín dụng cho mọi người tại stackoverflow (và có thể cả stackexchange nữa) không thể nhớ cách tôi tập hợp tất cả các bit và miếng. ☺

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.