無縫滾動

1 概述

無縫滾動效果在網頁里特別常見,一般它用來顯示一定數量的圖片或者與輪播圖進行結合,在說無縫滾動實例之前,我們得說說偏移量中的offsetLeft、offsetWidth 、offsetTop和offsetHeight。

  1. 偏移量共包括offsetTop、offsetLeft、offsetWidth、offsetHeight

元素:內容大小(width、height)、內邊距(padding)、邊框(border)、外邊距(margin)、滾動條(scroll)

【1】offsetWidth:元素在水平方向上占據的大小,無單位
offsetWidth = border + 元素內容寬度 + padding
= border-left-width + padding-left- width + width + padding-right-width + border-right-width

【2】offsetHeight:元素在垂直方向上占據的大小,無單位
offsetHeight = border + 元素內容高度 + padding
= border-left-height+ padding-left- height+ height+ padding-height-width + border-right-height

注:1. 如果存在垂直滾動條,offsetWidth也包括垂直滾動條的寬度;
2. 如果存在水平滾動條,offsetHeight也包括水平滾動條的高度

【3】offsetTop: 表示元素的上外邊框至offsetParent元素的上內邊框之間的像素距離
【4】offsetLeft:表示元素的左外邊框至offsetParent元素的左內邊框之間的像素距離

理解了偏移量,我們就可以開始動手寫無縫滾動功能頁面。

2 原理


2.1 HTML和CSS布局方面

重點注意的地方:

  • 1 一定要給運動物體的父元素設置相對定位
#div1 {
/* 運動的父元素設置相對定位 */
position: relative;
overflow: hidden;
width: 712px;
height: 108px;
background-color: blue;
margin: 20px auto;
}
  • 2 運動的本體要設置絕對定位
#div1 ul {
/* 運動的物體設置絕對定位 */
position: absolute;
top: 0;
left: 0;
}

2.2 JS部分

要先從布局上理解無縫滾動的原理,在運動的ul元素內本身就有8個li
,但是只顯示4個,每次運動時就顯示往后的li,但同時隨著ui的運動對應的li也會被隱藏,在運動到一個特定位置時(總ul寬度的一半),將li的位置拉回初始位置,使其產生一個可以不斷運動的“假象”、這就是無縫滾動的大致原理(我自己理解的),廢話少說,上代碼吧。

首先,用innerHTML輸出一個新的ul,然后計算出ul實際的寬度。

oUl.innerHTML += oUl.innerHTML; //創建2個ul 也就是8個li
oUl.style.width = (aLi[0].offsetWidth) * aLi.length + 'px'; //計算出ul實際寬度

然后,就是重點部分,定義無縫滾動的功能函數,這個自己看代碼理解(╥╯^╰╥)

//運動函數(重點)
var speed = -2; //運動方向默認向左
function move() {
  if(oUl.offsetLeft < -oUl.offsetWidth / 2) {
    oUl.style.left = 0;
  }
  if(oUl.offsetLeft > 0) {
    oUl.style.left = -oUl.offsetWidth / 2 + 'px';
  }
  oUl.style.left = oUl.offsetLeft + speed + 'px';
};
var timer = setInterval(move, 30);

接著是移入時暫停方便閱覽和移出時繼續運動的小功能實現

//移入就暫停
oDiv.onmouseover = function() {
  clearInterval(timer);
};
//移出就運動
oDiv.onmouseout = function() {
  timer = setInterval(move, 30);
};

3 完整代碼


<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <title>無縫滾動練習</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            #index-select {
                width: 400px;
                height: 50px;
                margin: 10px auto;
            }
            
            #index-select select {
                float: left;
                display: block;
                margin: 0px 50px;
            }
            
            #div1 {
                /* 運動的父元素設置相對定位 */
                position: relative;
                overflow: hidden;
                width: 712px;
                height: 108px;
                background-color: blue;
                margin: 20px auto;
            }
            
            #div1 ul {
                /* 運動的物體設置絕對定位 */
                position: absolute;
                top: 0;
                left: 0;
            }
            
            #div1 ul li {
                float: left;
                widows: 178px;
                height: 108px;
                list-style: none;
            }
        </style>
        <script>
            window.onload = function() {
                var oDiv = document.getElementById('div1');
                var oUl = oDiv.getElementsByTagName('ul')[0];
                var aLi = oDiv.getElementsByTagName('li');
                var se1 = document.getElementById('se1');
                var se2 = document.getElementById('se2');

                oUl.innerHTML += oUl.innerHTML; //創建2個ul 也就是8個li
                oUl.style.width = (aLi[0].offsetWidth) * aLi.length + 'px'; //計算出ul實際寬度
                //運動函數(重點)
                var speed = -2; //運動方向默認向左
                function move() {
                    if(oUl.offsetLeft < -oUl.offsetWidth / 2) {
                        oUl.style.left = 0;
                    }
                    if(oUl.offsetLeft > 0) {
                        oUl.style.left = -oUl.offsetWidth / 2 + 'px';
                    }
                    oUl.style.left = oUl.offsetLeft + speed + 'px';
                };
                var timer = setInterval(move, 30);

                //移入就暫停
                oDiv.onmouseover = function() {
                    clearInterval(timer);
                };
                //移出就運動
                oDiv.onmouseout = function() {
                    timer = setInterval(move, 30);
                };

                //控制方向和速度
                se2.onchange = se1.onchange = function() {
                    if(se1['value'] == "向左") {
                        switch(se2['value']) {
                            case "慢速":
                                speed = -2;
                                break;
                            case "中速":
                                speed = -4;
                                break;
                            case "快速":
                                speed = -8;
                                break;
                            default:
                                console.log("彈吉他的左手是和弦");
                        }
                    }

                    if(se1['value'] == "向右") {
                        switch(se2['value']) {
                            case "慢速":
                                speed = 2;
                                break;
                            case "中速":
                                speed = 4;
                                break;
                            case "快速":
                                speed = 8;
                                break;
                            default:
                                console.log("彈吉他的右手是節奏");
                        }
                    }
                };
            };
        </script>
    </head>
    <body>
        <div id="index-select">
            <select id="se1">
                <option value="向左">向左</option>
                <option value="向右">向右</option>
            </select>
            <select id="se2">
                <option value="慢速">慢速</option>
                <option value="中速">中速</option>
                <option value="快速">快速</option>
            </select>
        </div>

        <div id="div1">
            <ul>
                <li><img src="img/p1.jpg" </li>
                <li><img src="img/p2.jpg" </li>
                <li><img src="img/p3.jpg" </li>
                <li><img src="img/p4.jpg" </li>
            </ul>
        </div>
    </body>
</html>

OK,無縫滾動就是這樣,經檢驗沒有bug,可以放心食用(~ ̄▽ ̄)~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374