简体   繁体   中英

Use an anchor tag in url after load with knockout

I am working on a knockout page and I have a list of items. For each item I need them to have an anchor tag to scroll to. The problem I'm having is the anchor tag is being loaded from knockout bindings so, when you click on the url from an external page you would have a problem with it actually scrolling to the item. The page with the hash is a separate page. So in you can't scroll to the hash on page load simply because it doesn't exist until knockout loads the bindings.

For example...

My url = mysite.com/page1#thisItem

It should link to page1 with an anchor tag like...

<a name="thisItem"></a>

The problem is that the name gets added after the knockout bindings. I would prefer to do this without javascript checking if it has an id to link to and changing the window.location, however if that's my only choice then I will do it. Does anyone have a more elegant solution to this problem?

If you usecase is simple enough, you could simply check for the target onload, after your KO has initialized, and then just send the user there. Using something like scrollIntoView should work:

if (location.hash) {
    document.scrollIntoView(document.getElementByName(location.hash)[0]);
}

(not tested, adjust for syntax errors, etc!)

This example I put together works just fine:

https://jsfiddle.net/915jss01/1/

You need to use the attr data-binding to set the anchor target after loading:

<a data-bind="attr: {href: '#' + $data}, text: $data"></a>

and then similarly to set the target anchor name:

<a data-bind="attr: {name: $data}, text: $data"></a>

All you have to do is re-set window.location.hash after your page has been set up, and it will scroll there. You have to clear its value before re-assigning it, to get it to recognize the assignment as a change.

I put in a time delay, as the setup was quick enough that the initial setting of the hash "worked".

 window.location.hash = '#3'; // because I'm in a snippet var vm = { divs: ko.observableArray([{ id: '1', classname: 'green' }, { id: '2', classname: 'blue' }, { id: '3', classname: 'red' }]), hashchange: ko.observable(false) }; setTimeout(function() { ko.applyBindings(vm); var hash = window.location.hash; window.location.hash = ''; window.location.hash = hash; }, 100); 
 div { min-height: 500px; } .green { background-color: green; } .blue { background-color: blue; } .red { background-color: red; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div data-bind="foreach: divs"> <div data-bind="attr: {id: id}, css: classname, text: id"> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM