前端工程展示页
项目介绍
源代码 + 效果图
See the Pen
Challenges [06] by MaverickNone (@MaverickNone)
on CodePen.
如果客官您觉得不够大,看着不太爽!请点击这里或者这边~
源代码解构
HTML
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test [06]</title> <link rel="stylesheet" href="style.css"> <script src="https://kit.fontawesome.com/83ef1fc2b2.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> <script src="script.js"></script> </head>
|
- jQuery的添加源可以从cdnjs里面找,大部分添加源都可以找到,非常方便
- 因为涉及对HTML元素的控制,jQuery的UI组件包也要添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <body> <div id="wrapper"> <div id="quote-box"> <div class="quote-text"> <i class="fas fa-angle-double-left"></i> <span id="text"></span> <i class="fas fa-angle-double-right"></i> </div> <div class="quote-author"> - <span id="author"></span> </div> <div class="buttons"> <a class="button" id="tweet-quote" title="Tweet this quote!" target="_blank"><i class="fab fa-twitter"></i></a> <a class="button" id="tumblr-quote" title="Post this quote on tumblr!" target="_blank"><i class="fab fa-tumblr"></i></a> <button class="button" id="new-quote">New quote</button> </div> </div> <div class="footer"> By <a href="https://mavericknone.github.io">MaverickNone</a> </div> </div> </body>
|
- 稍微可以讲的也就两点
-
<i>
标签原本是作为斜体文本的标记,现在常常被用于标记图标
-
<span>
标签没有固定的格式表现,其中的文本与其他文本不会任何视觉上的差异。但是可以用于孤立文本方便CSS和JavaScript对于单独控制
| <script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script> </html>
|
-
src
里面的内容是freeCodeCamp对项目的质量评测系统,如果在</body>
前添加,那么就会报错Uncaught TypeError: Cannot read property 'appendChild' of null
,因为HTML加载的时候是从上往下加载,也就是说,当评测系统开始评测已经加载完毕开始评测的时候,需要评测的内容尚未加载完毕,所以肯定报错
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| @import url(https://fonts.googleapis.com/css?family=Raleway:400,500); :root { --black: #333; --white: #fff; } * { margin: 0; padding: 0; list-style: none; }
body { background-color: var(--black); color: var(--black); font-family: "Raleway", sans-serif; font-weight: 400; display: flex; justify-content: center; align-items: center; height: 100vh; } .footer { width: 450px; text-align: center; display: block; margin: 15px auto 0 auto; font-size: 0.8em; color: var(--white); a { font-weight: 500; text-decoration: none; color: var(--white); } } #quote-box { border-radius: 20px; width: 450px; padding: 40px 50px; display: table; background-color: var(--white); .quote-text { i { margin-left: 0.4em; margin-right: 0.4em; } text-align: center; width: 450px; font-weight: 500; font-size: 1.75em; } .quote-author { width: 450px; padding-top: 20px; text-align: right; } .buttons { width: 450px; margin: auto; display: block; .button { height: 38px; border: none; border-radius: 8px; color: var(--white); background-color: var(--black); outline: none; font-size: 0.85em; padding: 8px 18px 6px 18px; margin-top: 30px; opacity: 1; cursor: pointer; &:hover { animation: toWhite 0.5s; animation-fill-mode: forwards; } @keyframes toWhite { 100% {opacity: 0.8} } &#tweet-quote, &#tumblr-quote { float: left; padding: 8px 0 0; text-align: center; font-size: 1.2em; margin-right: 5px; height: 30px; width: 40px; } &#new-quote { float: right; } } } }
|
-
<body> { height: 100vh; }
这里直接将页面高度设置为整个可视页面
- 对于
<i>
标签,控制其包含的图标大小是通过调控font-size
来实现的
- 在
Scss
中,&
字符用于选择父级选择器
-
outline: none;
用于消除聚焦于按钮时出现的很难看的默认边框
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| let quotesData, currentQuote = "", currentAuthor = "";
let colors = [ "#16a085", "#27ae60", "#2c3e50", "#f39c12", "#e74c3c", "#9b59b6", "#FB6964", "#342224", "#472E32", "#BDBB99", "#77B1A9", "#73A857" ];
function inIframe() { try { return window.self !== window.top; } catch (err) { return true; } } function openURL(url) { window.open(url); }
function getQuotes() { return $.ajax({ url: "https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json", success: function(jsonQuotes) { quotesData = JSON.parse(jsonQuotes); console.log("Successfully received and processed json object!!!"); } }); }
|
-
inIframe()
这个函数的作用是检查当前元素是否在窗口的最顶层(是否能被看到),如果没有该函数,Twitter
和Tumblr
的图标就会在加载完后立马被刷下去
- 本来
<a>
元素本身自带打开窗口的功能,但是使用inIframe()
后,图标的Link失效,需要用openURL
来自己写个类似的功能来手动重新实现
-
getQuotes()
里面是jQuery
自带的Ajax
异步数据接收函数,本来实现类似的功能需要写一堆代码,非常繁琐,现在简化了
- 接收的
JSON
字符串数据需要用JSON.parse()
来转化成JavaScript
能够处理的Object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| function getRandomQuote() { let randomIndex = Math.floor(Math.random() * quotesData.quotes.length); return quotesData.quotes[randomIndex]; } function getQuote() { let randomQuote = getRandomQuote(); currentQuote = randomQuote.quote; currentAuthor = randomQuote.author; console.log(currentQuote); console.log('By '+currentAuthor);
if (inIframe()) { $("#tweet-quote").attr( "href", "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=" + encodeURIComponent('"' + currentQuote + '" ' + currentAuthor) ); $("#tumblr-quote").attr( "href", "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=" + encodeURIComponent(currentAuthor) + "&content=" + encodeURIComponent(currentQuote) + "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button" ); }
$(".quote-text").animate({ opacity: 0 }, 500, function() { $(this).animate({ opacity: 1 }, 500); $("#text").text(randomQuote.quote); }); $(".quote-author").animate({ opacity: 0 }, 500, function() { $(this).animate({ opacity: 1 }, 500); $("#author").html(randomQuote.author); });
let randomIndex = Math.floor(Math.random() * colors.length); console.log(colors[randomIndex]);
$("html body").animate({ backgroundColor: colors[randomIndex], color: colors[randomIndex] }, 1000); $(".button").animate({ backgroundColor: colors[randomIndex] }, 1000); }
|
- 记住生成固定范围的随机数的方法
- 如果分享按钮在顶层界面,就只动态替换分享的链接
-
encodeURIComponent()
函数可把字符串作为 URI 进行编码,实现动态分享当前quote
- 现在我们来仔细分析一下动画的过程发生了什么
- 前0.5秒:
- 文字消失,从不透明到全透明,从颜色A变成透明
-
<body>
元素和3个按钮从颜色A转到过渡颜色(AB之间的颜色)
- 后0.5秒:
- 文字出现,从全透明到不透明,从透明变成颜色B
-
<body>
元素和3个按钮从过渡颜色转到颜色B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| $(document).ready(function() { getQuotes().then(() => { getQuote(); });
$("#new-quote").on("click", getQuote);
$("#tweet-quote").on("click", function() { if (!inIframe()) { openURL( "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=" + encodeURIComponent('"' + currentQuote + '" ' + currentAuthor) ); } }); $("#tumblr-quote").on("click", function() { if (!inIframe()) { openURL( "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=" + encodeURIComponent(currentAuthor) + "&content=" + encodeURIComponent(currentQuote) + "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button" ); } }); });
|
-
then()
方法保证getQuotes()
先得到并处理数据,然后再通过getQuote()
呈现数据
-
on()
分别绑定了3次事件,一点new quote按钮,就呈现数据(新的quote,并随机变化颜色),一点Twitter
或者Tumblr
按钮就分别打开各自的动态分享页面
- 如果分享按钮不在顶层界面,就手动打开新界面。如果在,就啥都不做,反正原来的点击就自带打开链接的功能
项目总结
- 对于jQuery的很多使用细节仍然还是一知半解,仍然需要找专业的书籍来进阶提升
- 对于CSS的单一特效已经有了基本认知,但是对于父元素与子元素之间的特效的组合不甚了解,也需要找专业的书籍来打好基础
- 这次也花了很长时间才弄懂怎么添加外源,不过这次算是一次性全部弄懂了
- 这个项目也启发了在GitHub上的Gist板块保存只读JSON的想法,用Ajax技术来传输访问