0

編集 (2012 年 12 月 26 日)

ページの URL の末尾にスラッシュがある場合 (example.com/page/ など) を除き、ページはスクロールしません。ページの URL が '.php' や '.html' などで終わっていれば問題なく動作します。次のスクリプトを URL の末尾のスラッシュで動作させる方法について何か考えはありますか?

jQuery('a[href*=#]').bind('click', function(e) {
    // Get the target
    var target = jQuery(this).attr("href"); 

    // prevent the "normal" behaviour which would be a "hard" jump
    e.preventDefault(); 

    // perform animated scrolling by getting top-position of target-
    // element and set it as scroll target
    jQuery('html, body').stop().animate({
        scrollTop: jQuery(target).offset().top 
    }, 500, function() {
        location.hash = target;  //attach the hash (#jumptarget) to the pageurl
    });

    return false;
});

ここ数年、スクリプトを使用して成功していますが、最近、いくつかの問題に遭遇しました。基本的に、スクリプトが行うことは、ページを特定のポイントまでスクロールすることです。これは、リンク アンカーで発生します。たとえば、1 つのリンクが次の場合:

<a href="#anchor">anchor link</a>

ページは、ページ上のそのアンカーまでスムーズにスクロールします。

<a name="anchor"></a>

または:

<a id="anchor"></a>

この問題は、リンクを次のようにフォーマットする必要があるページで他の JS が使用されている場合に発生します。

<a href="#">other link</a>

この「他のリンク」をクリックすると、ページはスムーズにスクロールしますが、アンカーがないページの上部または下部にスクロールします。

この「他のリンク」をクリックするとどうなりますか? 他の JS アクションは発生しますが (実際に発生します)、スムーズなページ スクロール スクリプトは発生しません。

このスクリプトを入手した場所からの実例を次に示します。

http://www.dezinerfolio.com/wp-content/uploads/smoothscrolldemo/df_smooth_scroll.html

完全なJSは次のとおりです。

Scroller = {
    // control the speed of the scroller.
    // dont change it here directly, please use Scroller.speed=50;
    speed: 10,

    // returns the Y position of the div
    gy: function (d) {
        gy = d.offsetTop
        if (d.offsetParent) while (d = d.offsetParent) gy += d.offsetTop
        return gy
    },

    // returns the current scroll position
    scrollTop: function (){
        body = document.body
        d = document.documentElement

        if (body && body.scrollTop) return body.scrollTop
        if (d && d.scrollTop) return d.scrollTop
        if (window.pageYOffset) return window.pageYOffset

        return 0
    },

    // attach an event for an element
    // (element, type, function)
    add: function(event, body, d) {
        if (event.addEventListener) return event.addEventListener(body, d,false)
        if (event.attachEvent) return event.attachEvent('on'+body, d)
    },

    // kill an event of an element
    end: function(e){
        if (window.event) {
            window.event.cancelBubble = true
            window.event.returnValue = false

            return;
        }

        if (e.preventDefault && e.stopPropagation) {
          e.preventDefault()
          e.stopPropagation()
        }
    },

    // move the scroll bar to the particular div.
    scroll: function(d){
        i = window.innerHeight || document.documentElement.clientHeight;
        h = document.body.scrollHeight;
        a = Scroller.scrollTop()

        if (d>a)
            if(h-d>i)
                a += Math.ceil((d-a)/Scroller.speed)
            else
                a += Math.ceil((d-a-(h-d))/Scroller.speed)
        else
            a = a + (d-a)/Scroller.speed;

        window.scrollTo(0,a)

        if (a==d || Scroller.offsetTop==a)
            clearInterval(Scroller.interval)

        Scroller.offsetTop = a
    },

    // initializer that adds the renderer to the onload function of the window
    init: function(){
        Scroller.add(window,'load', Scroller.render)
    },

    // this method extracts all the anchors and validates then as # and attaches the events.
    render: function(){
        a = document.getElementsByTagName('a');

        Scroller.end(this);

        window.onscroll

        for (i=0;i<a.length;i++) {
            l = a[i];

            if (l.href && l.href.indexOf('#') != -1 && ((l.pathname==location.pathname) || ('/'+l.pathname==location.pathname)) ){
                Scroller.add(l,'click',Scroller.end)

                l.onclick = function(){
                    Scroller.end(this);

                    l = this.hash.substr(1);
                    a = document.getElementsByTagName('a');

                    for (i=0;i<a.length;i++) {
                       if (a[i].name == l){
                            clearInterval(Scroller.interval);

                            Scroller.interval = setInterval('Scroller.scroll('+Scroller.gy(a[i])+')',10);
                        }
                    }
                }
            }
        }
    }
}

// invoke the initializer of the scroller
Scroller.init();

スクリプトを記述して、ハッシュの後にテキストがないhrefハッシュマークだけに等しい場合、スクローラーがトリガーされないようにする方法があると思います。#

誰もがより良いアイデアを持っていますか?

前もって感謝します!

4

2 に答える 2

0

jQuery 関数についてはお手伝いできませんが、元のスクリプトには 2 つの簡単な解決策があります。1 つ目は、アンカーの URL がハッシュ タグのみであるという特殊なケースを無視するようにスクリプトに指示するための小さな変更です。

render関数で、次の行を変更します。

if (l.href 
    && l.href.indexOf('#') != -1 
    && (l.pathname == location.pathname
        || '/' + l.pathname == location.pathname)
) {

に:

if (l.href
    && l.href != '#' // <<< Added this conditional >>>
    && l.href.indexOf('#') != -1
    && (l.pathname == location.pathname
        || '/' + l.pathname == location.pathname)
){

これにより、スクリプトは特殊なケースを無視するようになりますが、ブラウザがリンクに正常に反応することは妨げられないため、ブラウザは依然としてページの先頭にジャンプする可能性があります。あなたが言及した特別なケースは、ほとんどの場合、href属性を持つアンカータグを提供するために JavaScript の構築で使用されます。「#」は、リンクがページから離れないようにするために URL として使用されました。

「#」の代わりに、次のように空の JavaScript 呼び出しをリンクで使用できます。

<a href="javascript:;">other link</a>

これにより、スクローラーに関する問題が完全に回避されます。

于 2012-12-27T06:28:31.153 に答える
0

ジャレッド、助けてくれてありがとう!私がやりたいことだけを行うスクリプトに出くわしました。これが私が見つけたより良いスクリプトです:

jQuery('a[href*=#]').bind('click', function(e) {
    e.preventDefault(); //prevent the "normal" behaviour which would be a "hard" jump
    var target = jQuery(this).attr("href"); //Get the target
    // perform animated scrolling by getting top-position of target-element and set it as scroll target
    jQuery('html, body').stop().animate({ scrollTop: jQuery(target).offset().top }, 1000, function() {
        location.hash = target;  //attach the hash (#jumptarget) to the pageurl
    });
    return false;
});
于 2013-01-22T01:47:36.760 に答える