為第一次使用網頁顯示「新手提示」之懶人工具
source link: https://blog.darkthread.net/blog/simple-novice-guide/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
為第一次使用網頁顯示「新手提示」之懶人工具
2021-04-01 10:25 PM 1 1,574寫網頁的人總夢想著自己寫的介面夠簡單夠直覺,不需說明文件,使用者模索兩下就能上手。但事與願違,網頁上一些自以為夠明顯一定會被使用者發現的得意設計,上線半年還乏人問津,常令設計者一陣鼻酸。
手機 App 有一種不錯的設計概念可供借鏡,做法是第一次開啟 App 時先跳出一段動畫展示,簡要提示新功能或操作技巧,使用者必須看完才能開啟使用,而它只有在首次使用時顯示,之後便不再出現。
我想把這種「新手提示」的概念應用在網頁上 - 第一次開啟網頁時先放一層遮罩擋住 UI 不讓使用者操作,以動畫方式提示操作訣竅,展示結束後在 localStorage 留下已讀註記,下回再開啟時檢查到已讀註記便不再顯示。
為每個網頁大費周章客製專屬新手提示動畫有點辛苦,於是我想到用 jQuery Selector 找在特定元素在旁邊附上一小段文字說明的點子,這樣子用 { "selector1": "說明文字1", "selector2": "說明文字2" ... } 定義出標註的元素及文字,呼呼共用函式播放,如此只需簡單設定就能為網頁加上新手提示了。 這種新手指示的效果當然比不上請視覺設計人製作的精美動畫相比,但比起靜態說明文件或任由使用者自己摸索,已是了不起的大躍進,可以大幅提供企業內部應用系統的操作體驗。
最後我把這個概念寫成共用函式,還加入自訂說明文字位置、自動捲動至元素位置、顯示前後自訂事件... 等功能,並小心翼翼保持 IE 相容,理論上可滿足大部分應用情境。而為了實地展示,我 Fork 了一個網頁欄位驗證 Github 專案當成示範對象,在網頁加入以下程式碼:
<script src="afet.novice-guide.js"></script>
<script>
afet.ShowNoviceGuide('readFlagName', false, {
'h1': {
offsetLeft: 0, offsetTop: -20,
text: '<div style="padding:12px;width:500px;text-align:center;font-size:2em;color:yellow">\
簡易式「新手提示」展示</div>'
},
'[name=name]': '請在這裡填入您的姓名\n例如:黑鮪魚之夢',
'[type=checkbox]:eq(1)~span': {
offsetLeft: -50, offsetTop: 20,
before: function (el) { el.closest('label').css('border', '1px solid red'); },
after: function (el) { el.closest('label').css('border', "none"); },
text: '點選文字也可打勾哦'
},
'[type=submit]': {
offsetLeft: 0, offsetTop: -50,
text: '按這裡送出表單'
},
'.email': {
offsetLeft: 40, offsetTop: 20,
before: function (el) { validator.checkField(el[0]); },
after: function (el) { validator.reset(); },
text: '檢核失敗將出現紅色警語'
},
'.reshow': '新手提示只會顯示一次\n重看請按這裡清localStorage旗標\n並重新整理頁面'
});
</script>
呈現效果如下,想實地動手的朋友可玩玩線上版:
函式庫不大,不到 120 行打發,單一 js 搞定,有 jQuery 就能動。完整程式碼如下:
var afet;
(function (afet) {
/**
* 簡易新手提示產生器 Ver 1.0.0 by Jeffrey https://blog.darkthread.net
* @param {any} guideCode 指示代碼,首次顯示後在localStorage下註記以免重複出現
* @param {boolean} force 無視 localStorage 已讀註記,一律顯示
* @param {any} instructions Key/Value 形式,Key為 Selector,Value 為說明物件
* @param {any} instrucStyles 說明區塊自訂樣式
* 說明物件格式為 { offsetTop: y, offsetLeft: x, text: '...', before: function(el) {...}, after: function(el) {...} }
* 說明物件也可以字串取代,則說明會寫示在選取元素下方,說明文字以可為 HTML 或純文字,若為純文字支援換行顯示
*/
function showNoviceGuide(guideCode, force, instructions, instrucStyles) {
var zIdx = 9990, bgColor = '#2196f3', key = "$NG_" + guideCode;
if (localStorage.getItem(key) && !force) return;
var docW = $(document).width() + 'px', docH = $(document).height() + 'px';
var mask = $('<div></div>').css({
position: 'absolute', top: 0, left: 0, width: docW, height: docH, 'z-index': zIdx,
opacity: 0.2, 'background-color': '#444', cursor: 'pointer'
});
mask.appendTo('body');
function getNumber(s) { return parseInt(s.replace('px', '')); }
var queue = Object.keys(instructions);
var lastTip;
var svg = $('<svg version="1.1"></svg>').css({ position: 'absolute', top: 0, left: 0, zIndex: zIdx + 1, width: docW, height: docH, opacity: 0.5, cursor: 'pointer' });
svg.appendTo('body');
//http://chubao4ever.github.io/tech/2015/07/16/jquerys-append-not-working-with-svg-element.html
function SVG(tag) {
return document.createElementNS('http://www.w3.org/2000/svg', tag);
}
function drawLine(x1, y1, x2, y2, color) {
$(SVG('line'))
.attr('x1', x1).attr('y1', y1).attr('x2', x2).attr('y2', y2)
.attr('stroke', color).attr('stroke-width', '2px')
.appendTo(svg);
}
function drawCircle(x, y, r, color) {
$(SVG('circle')).attr('cx', x).attr('cy', y).attr('r', r).attr('fill', color)
.appendTo(svg);
}
svg.click(function () {
if (lastTip) {
lastTip.trigger('next').remove();
lastTip = null;
}
svg.empty();
if (!queue.length) {
mask.remove();
svg.remove();
window.scrollTo(0, 0);
localStorage.setItem(key, "Y");
return;
}
var sel = queue.shift();
var focusElem = $(sel);
var instruction = instructions[sel];
if (typeof instruction === "string") {
instruction = {
offsetTop: focusElem.height() + 20,
offsetLeft: 0,
text: instruction
};
}
if (focusElem.length && focusElem.is(":visible")) {
$.isFunction(instruction.before) && instruction.before(focusElem);
var pos = focusElem.offset();
var tip = $('<div></div>');
tip.css({
position: 'absolute',
top: (pos.top + instruction.offsetTop) + 'px',
left: (pos.left + instruction.offsetLeft) + 'px',
"z-index": zIdx + 2,
opacity: 1,
backgroundColor: bgColor,
padding: '6px',
color: 'white'
});
if (instrucStyles) tip.css(instrucStyles);
var instrText = instruction.text;
if (instrText.indexOf('<') === 0)
tip.html(instrText);
else {
tip.text(instrText);
if (instrText.indexOf('\n') > -1)
tip.html(tip.html().replace(/\n/g, '<br />'));
}
var s = getComputedStyle(focusElem[0]);
tip.attr('data-st', (pos.left + getNumber(s.paddingLeft) + focusElem.width() / 2) + ","
+ (pos.top + getNumber(s.paddingTop) + focusElem.height() / 2));
$.isFunction(instruction.after) && tip.bind("next", function() {
instruction.after(focusElem);
});
}
else {
//if not found, trigger click event to show next tip
setTimeout(function () { svg.click(); }, 0);
return;
}
lastTip = tip;
lastTip.appendTo('body');
var pos = lastTip.offset();
var st = lastTip.attr("data-st").split(',');
drawCircle(st[0], st[1], 5, bgColor);
drawLine(st[0], st[1], pos.left + lastTip.width() / 2, pos.top + lastTip.height() / 2, bgColor);
var y = st[1] - $(document).scrollTop()
console.log(y);
if (y > $(window).height() / 2) window.scrollTo(0, st[1]);
else if (y < 30) window.scrollTo(0, 0);
svg.hide().fadeIn('slow');
lastTip.hide().fadeIn('slow');
});
setTimeout(function () { svg.click(); }, 500);
}
afet.ShowNoviceGuide = showNoviceGuide;
})(afet || (afet = {}));
實際套用在幾個網頁上效果不錯,是個實用的好工具。好久沒寫前端程式,這個算是近期的得意之作,野人獻曝分享給大家~
Demostration of how to create simple novice guide for first time webpage user with shared JavaScript functions.
Recommend
-
25
Java 是一个多功能的编程语言,在某种程度上,它用在几乎所有可能涉及计算机的行业了里。Java 比较的大优势是,它运行在一个 Java 虚拟机(JVM)中,这是一个翻译 Java 代码为与操作系统兼容的字节码的层。只要有 JVM 存在于你的操作系统上...
-
14
網頁內嵌 JSON 注意事項 2021-01-07 08:29 PM 0 2,468 在輸出網頁時內嵌 JSON 轉成 JavaScript 物件是我愛用的手法,這點之前有
-
9
Web data scraping Company/網絡數據抓取公司
-
7
將 HTML 圖文網頁轉成 ePub 電子書試過純手工打造 ePub 電子書,寫過程式半自動轉換。前陣子試了另一種作法 - 用現成工...
-
6
網頁「新手提示」懶人工具 1.1 版 2021-04-04 08:20 AM 0 249 前幾天分享了我的私房「網頁新手...
-
5
第一次使用pg,在restore时,提示failed exit code:1,求教各位大佬问题出在哪里? 开源问答...
-
9
使用 luit 完美解決 Windows Subsystem for Linux 顯示 Big5 字集的問題對於 WSL (Windows Subsystem for Linux) 一直無法處理 Big5 字元這件事,對我來說就像在一...
-
6
【茶包射手日記】網頁圖片在 IE 無法顯示但 Chrome/Edge 可以-黑暗執行緒 同事遇到一個狀況:某網頁的圖檔用 Chrome/Edge 檢視 OK,用 IE 卻無法顯示。 用以下範例重現問題: demo.html 內容單純,未藏玄機: <!DOCT...
-
14
HTTPS Nginx Docker 之懶人安裝法 2022-12-11 05:45 PM 2
-
2
使用 Server-Sent Event-黑暗執行緒 多因素認證(Multiple Factor Authentication,MFA)網頁常會用到一種技巧,介面停在登入網頁,等待手機 App 操作,網頁能偵測 App 動作是否完成,若驗證成功自動導向已登入畫面。 以 Facebook 為例,...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK