iT邦幫忙

2

#問 滑動網頁卷軸形狀變化

  • 分享至 

  • xImage

請問要怎麼在滾動視窗看到works字樣時,中間那行白色線能以中心點往外展開10%寬度?

(js碼是參考外面網站混出來的,大部分都看不太懂,麻煩大家了qq)

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>

	<script type="text/javascript">
		 $( window ).scroll( function () {
 
        if ( $( window ).scrollTop() > $( '.workbox' ).offset().top - 10 ) {
       
       		$('.workline').animate({'width=10%'})

        }  })
	</script>
	
	<style type="text/css">
		*{margin:0 auto}

		.workbox{background-color:#B37B4C;padding:1%;text-align:center;color:#ffff;}
		.workbox h2{font-size:40px;padding-top:1%;}
		.workbox h6{font-size:20px;padding-top:1%;}
		.workline{background-color:#ffff;padding:1px;width:2%;}

	</style>

</head>
<body>
	<br><br><br><br><br><br><br><br><br><br><br><br>
	<br><br><br><br><br><br><br><br><br><br><br><br>
	<br><br><br><br><br><br><br><br><br><br><br><br>
	<br><br><br><br><br><br><br><br><br><br><br><br>

	<div class="workbox">
			<h2>W O R K S</h2>
			<div class="workline"></div>
			<h6>作品</h6>
	</div>
    
	<script src="jquery-3.4.1.min.js"></script>

</body>
</html>

所以???你的問題點是啥??
小魚 iT邦大師 1 級 ‧ 2019-09-09 15:51:20 檢舉
問題點是請你幫他解決問題.
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

3
ccutmis
iT邦高手 2 級 ‧ 2019-09-10 09:06:02
最佳解答

參考看看...有加上展開變型後回復初始狀態的判斷式。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>滑動網頁卷軸形狀變化</title>
<!-- jquery庫通常會放在這地方載入 -->
<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>
<script type="text/javascript">
let lastAnimateId='';
$( window ).scroll( function () {
		const senseHeight=200;
		let winScrollTop=$( window ).scrollTop();
		if ( Math.abs(winScrollTop-$( '#works' ).offset().top)< senseHeight ) {
			$('#works .workline').animate({width:"15%"});
			lastAnimateId='#works';
		}else if( Math.abs(winScrollTop-$( '#contactus' ).offset().top)< senseHeight ){
			$('#contactus .workline').animate({width:"30%"});
			lastAnimateId='#contactus';
		}else{
			if( lastAnimateId!='' ){
				$(lastAnimateId+' .workline').animate({width:"2%"});
				lastAnimateId='';
			}
		} 
});
</script>
<style type="text/css">
*{margin:0 auto}

.workbox{background-color:#B37B4C;padding:1%;text-align:center;color:#FFF;}
.workbox h2{font-size:40px;padding-top:1%;}
.workbox h6{font-size:20px;padding-top:1%;}
.workline{background-color:#FFF;padding:1px;width:2%;}
</style>

</head>
<body>
<div style="height:1000px;"></div>
<div class="workbox" id="works">
	<h2>W O R K S</h2>
	<div class="workline"></div>
	<h6>作品</h6>
</div>
<div style="height:1000px;"></div>
<div class="workbox" id="contactus">
	<h2>C O N T A C T ✪ U S</h2>
	<div class="workline"></div>
	<h6>聯絡我們</h6>
</div>
<div style="height:1000px;"></div>

</body>
</html>

然後你可能會覺得每多一個id就要重覆一次if(...){}的作法很笨,若有這想法的話可以試試下列的範例:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>滑動網頁卷軸形狀變化</title>
<!-- jquery庫通常會放在這地方載入 -->
<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>
<script type="text/javascript">
const scroll_id_array=['#aboutus','#technology','#works','#contactus'];
let lastAnimateId='';
$( window ).scroll( function () {
		const senseHeight=500;
		let winScrollTop=$( window ).scrollTop();
		let scroll_detect_result=$.map(scroll_id_array, function(index) {
			if ( Math.abs(winScrollTop-$(index).offset().top)< senseHeight ) {
				$(index+' .workline').animate({width:"15%"});
				lastAnimateId=index;
				return index;
			}
		});
		if(scroll_detect_result==''){
			$(lastAnimateId+' .workline').animate({width:"2%"});
			lastAnimateId='';
		}
});
</script>
<style type="text/css">
*{margin:0 auto}
div{background:#ffffdd;}
.workbox{background-color:#B37B4C;padding:1%;text-align:center;color:#FFF;}
.workbox h2{font-size:40px;padding-top:1%;}
.workbox h6{font-size:20px;padding-top:1%;}
.workline{background-color:#FFF;padding:1px;width:2%;}
</style>

</head>
<body>
<div style="height:1000px;"></div>
<div class="workbox" id="aboutus">
	<h2>A B O U T ✪ U S</h2>
	<div class="workline"></div>
	<h6>公司簡介</h6>
</div>
<div style="height:1000px;"></div>
<div class="workbox" id="technology">
	<h2>T E C H N O L O G Y</h2>
	<div class="workline"></div>
	<h6>核心技術</h6>
</div>
<div style="height:1000px;"></div>
<div class="workbox" id="works">
	<h2>W O R K S</h2>
	<div class="workline"></div>
	<h6>作品</h6>
</div>
<div style="height:1000px;"></div>
<div class="workbox" id="contactus">
	<h2>C O N T A C T ✪ U S</h2>
	<div class="workline"></div>
	<h6>聯絡我們</h6>
</div>
<div style="height:1000px;"></div>

</body>
</html>

補上純JS版的範例,如果改天樓主不想用jQuery的時候可以參考,
這個demo的執行效率比上面的jQuery版本好。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>滑動網頁卷軸形狀變化(純JS版)</title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded",function(){
	console.log('PageLoaded!');
	const senseHeight=400;
	const scroll_id_array=['#aboutus','#technology','#works','#contactus'];
	let scroll_id_top=[];
	scroll_id_array.forEach(function(element) {
		scroll_id_top.push(document.querySelector(element).offsetTop);
	});

	window.addEventListener('scroll', function(e) {
		let last_known_scroll_position = window.scrollY;
		scroll_id_top.forEach(function(element) {
			let scroll_gap=Math.abs(last_known_scroll_position-element);
			let currentAnimateId=scroll_id_array[scroll_id_top.findIndex(scroll_index => scroll_index === element)];
			let current_target=document.querySelector(currentAnimateId+' .workline');
			if(scroll_gap<senseHeight){
				current_target.classList.add('workline_anim');
				current_target.classList.remove('workline_anim2');
			}else{
				current_target.classList.add('workline_anim2');
				current_target.classList.remove('workline_anim');
			}
		});
	});
});
</script>
<style type="text/css">
*{margin:0 auto}
div{background:#ffffdd;}
.workbox{background-color:#B37B4C;padding:1%;text-align:center;color:#FFF;}
.workbox h2{font-size:40px;padding-top:1%;}
.workbox h6{font-size:20px;padding-top:1%;}
.workline{background-color:#FFF;padding:1px;width:2%;}
.workbox .workline_anim{ animation-fill-mode: forwards; transition: all 1s ease-in-out;transform: scaleX(8); }
.workbox .workline_anim2{ animation-fill-mode: forwards; transition: all 1s ease-in-out;transform: scaleX(1); }
</style>

</head>
<body>
<div style="height:1000px;"></div>
<div class="workbox" id="aboutus">
	<h2>A B O U T ✪ U S</h2>
	<div class="workline"></div>
	<h6>公司簡介</h6>
</div>
<div style="height:1000px;"></div>
<div class="workbox" id="technology">
	<h2>T E C H N O L O G Y</h2>
	<div class="workline"></div>
	<h6>核心技術</h6>
</div>
<div style="height:1000px;"></div>
<div class="workbox" id="works">
	<h2>W O R K S</h2>
	<div class="workline"></div>
	<h6>作品</h6>
</div>
<div style="height:1000px;"></div>
<div class="workbox" id="contactus">
	<h2>C O N T A C T ✪ U S</h2>
	<div class="workline"></div>
	<h6>聯絡我們</h6>
</div>
<div style="height:1000px;"></div>

</body>
</html>
看更多先前的回應...收起先前的回應...

耶對我是要這樣的效果~ 謝謝你><
不過想問一下~

1.const跟let的意思跟var一樣嗎?
2.這些都是用jquery還是混著js打出來的?
3.中間的map,Math,ads是代表什麼~
4.為什麼第二段縮寫的可以把eles省略~
5.最上面integrity和crossorigin是載入的意思嗎? 後面載的又是什麼

不好意思問題有點多,有空在回答我就好,謝謝><

ccutmis iT邦高手 2 級 ‧ 2019-09-10 11:38:46 檢舉

A1:這個鐵人賽的主題很適合你看,看完你就懂了
https://ithelp.ithome.com.tw/articles/10213188

A2:大部份用到jquery,條件判斷跟變數給值那些是js

A3: $.map()那個是jquery的東西,範例可參考下列文章
https://ithelp.ithome.com.tw/articles/10090418
Math.abs()這個是javascript裡的數學類函式啊,用意:取絕對值。
而Math.abs(...)那段整行的意思就是去把$( window ).scrollTop()減$(某ID).offset().top的結果取絕對值(因為相減結果有可能是負的)然後去判斷這個值是否小於200,是的話表示現在某ID滾動到頁面上方位置。這種類似的判斷寫法很多種,重點是你的程式邏輯。

A4: 第二段是用到$.map()把scroll_id_array陣列的內容取出來跑一遍,這個就跟第一段那個if(...)else if(...)....是同樣原理的,只是寫法不同。第一段的else{...}是用來把變寬的杠縮回去,在第二段則改用scroll_detect_result來判斷是否把變寬的杠縮回。(scroll_detect_result是$.map...那段的傳回值,如果傳回值是某ID代表目前要把某ID的杠變寬,如果是空的,就把lastAnimateId的杠縮回),原理大概是這樣子,多寫就懂了,另外要會用Chrome瀏覽器的F12,不懂請上網google 'Google Chrome F12大法'

啊啊 還有~
我把第二種直接貼到新檔案裡在開網頁,發現有點難處發動態,而且當框框在視窗中央時並不會維持長度15%,只有一直上下滑動才會偶爾觸發,這樣是正常的嗎~

感謝大大解說><

ccutmis iT邦高手 2 級 ‧ 2019-09-10 11:56:34 檢舉


const senseHeight=200;
改成
const senseHeight=500;
試試看
我原本是把觸發位置設定在框框要在頁面上方
如果你要它在頁面中央也能維持段長度15%的話 那就加大感應高度嘍
try it!


另外一個可能造成的原因就是,目前這個寫法還不夠好,有些地方可能會造成系統資源負擔,例如滑鼠每滾動一次就會去跑一次$.map(....); 如果你在短時間內上下滾動,它會頻繁的計算,有時就會讓動畫看起來卡卡的,或是會延後一會兒才變寬。

有了有了~謝謝+.+

ccutmis iT邦高手 2 級 ‧ 2019-09-11 17:00:16 檢舉

兔子兔子
我剛才補充了一個純JS寫的版本 有空可以參考看看

啊啊抱歉這麼晚才看到>< 真的謝謝你了+.+
是說純js跑的是不是會比jquery好啊?
初學者先學哪個比較好?
我之前看js初學影片看得霧煞煞 想問為什麼js教學影片剛開始都是教跳出視窗類的特效? 但做網頁的時候都沒用到alert
p.s.我是都看yt上的影片教學
一樣有空再回復我就好~ 謝謝你幫我這麼多

ccutmis iT邦高手 2 級 ‧ 2019-09-18 01:13:00 檢舉

初學者先學哪個比較好?

目前的話我會建議先學JS吧,畢竟打好基礎後你大概懂jQuery怎麼運作的了。我自己學習的話是爬網路文章比較多,最近it邦又有鐵人賽,你可以找一些JS相關的主題訂閱學習,多看多想多寫才會進步,以下是我有訂閱的你可以參考看看:

[JavaScript 初心者筆記] 純JS
https://ithelp.ithome.com.tw/users/20120114/ironman/2307?page=1

[網頁排版個人學習筆記] 有介紹jQuery相關
https://ithelp.ithome.com.tw/users/20119743/ironman/2531

[透過 ESLint 練習 JavaScript ES6] 這個比較進階一些
https://ithelp.ithome.com.tw/users/20119924/ironman/2235

更多與鐵人賽有關的主題您可以自己去挖堀喔!


我之前看js初學影片看得霧煞煞 想問為什麼js教學影片剛開始都是教跳出視窗類的特效? 但做網頁的時候都沒用到alert

這是個好問題,以前我剛開始學作網頁的時候,網頁瀏覽器還沒有像現在這麼方便,例如Google Chrome按F12有開發者工具(這個工具你一定要會用),如果我想知道某個變數的值是多少,我只需要在適當的地方寫

let myVar='Hello World';
console.log('變數:'+myVar);
/* 會在開發者工具console主控台看到 
印出 變數: Hello World */

但是在早期沒有這麼方便的工具,想知道變數是什麼最簡單的方式就是alert出來,例如

alert('變數:'+myVar);
/*會跳出小視窗寫 '變數: Hello World' */

當然用console.log(...)是比較好的debug工具,自然直接用javascript: alert()的人就愈來愈少了,如果是要在網頁上秀出類似alert的小框框,很多框架都有提供類似alert框的效果,例如 Google搜 'Bootstrap alert框' 就能找到demo,甚至自己純手工刻也可以,所以為何現在很少見alert(...) 你懂的...

另外用alert();有時不小心會把整個網頁卡住,例如下面這段你把它放在網頁的body區裡面,再用網頁打開,它就會卡住不能動

<script>
for(;;) alert('HaHa Browser is not working!');
</script>

for(;;) alert(....)
這個就是無限廻圈會一直呼叫小視窗,除非你把瀏覽器直接關掉,不然它就卡在那邊了,用alert(...)不小心時可能會遇到,而用console.log(...)比較不會遇到這種情況。

謝謝大大!!><超級無敵感謝~

ccutmis iT邦高手 2 級 ‧ 2019-09-18 13:22:52 檢舉

/images/emoticon/emoticon82.gif

1
俊緯
iT邦新手 5 級 ‧ 2019-09-10 09:05:32

這段 $('.workline').animate({'width=10%'}) 寫錯了,
animate 裡的 style 是物件,所以要改成 animate({width: '+=10%'})
看看是不是你需要的結果。

Codepen

謝謝大大+.+

我要發表回答

立即登入回答