今天发现同事前段大牛Alex写了两个js文件 方便用于 已写好的web页面突然要支持手机的, 比如有个页面所有宽度是 640px 可引入这两个js文件之后再你的页面写一句话
$(document).ready(function(){ sun.md.setViewPortContent({ initWidth : 640 }); });
之后便可以用手机看看了, 一般情况只需要很小的调整就可以了,但是有可能及特殊情况不适用, 欢迎有bug通过留言反馈
若有使用的情况特殊可以看下setViewPortContent这个方法, 主要就是根据手机类型设置它的viewport的属性 ,里面还有许多定义好的js常用方法
用此js文件如有bug等等问题带来利益损失概不负责
下面是js代码引入要有顺序 先引入sun.js 再引入sun.md.js, (这两个文件时在jquery下写的所以jquery必须最先引入)
sun.js
var sun = sun || {}; /** * it is for alex to shortcut method * delete before online */ (function shortCut() { tojs = function(vmodel) { return ko.mapping.toJS(vmodel) }; log = function (){ console.log(arguments) }; write = function(txt){ var p = document.createElement('p'); var hr = document.createElement('hr'); p.innerHTML = txt; document.body.appendChild(hr); document.body.appendChild(p); }; })() sun.ajax = function() { var mime = { html: 'html', js: 'script', json: 'json', xml: 'xml', txt: 'text' } var _stringifyData = function(sType, oData) { var _data = oData; if ((sType.toUpperCase() === 'POST') && ( !! oData)) { _data = JSON.stringify(oData); } return _data; }; base = function(sUrl, sType, sDataType, oData, fnCallBack, isShlowLoading, isAsync) { var _data = oData, _isAsync = typeof isAsync === 'boolean' ? isAsync : true; if (sUrl.indexOf('?') === -1){ sUrl = sUrl + '?t=' + Math.random(); }else { sUrl = sUrl + '&t=' + Math.random(); } $.ajax({ async: _isAsync, type: sType, url: sUrl, data: _stringifyData(sType, oData), contentType: 'application/json', dataType: sDataType, beforeSend: function(XMLHttpRequest) { if (!!isShlowLoading) { } }, success: function(data, textStatus) { if (!!isShlowLoading) { } if(!_isAsync && (typeof fnCallBack === 'function')){ fnCallBack(data, textStatus); }; _data = data; }, error: function(XMLHttpRequest, textStatus, errorThrown) { if (!!isShlowLoading) { } _data = errorThrown; } }).done(function(data, textStatus, _self) { if (!!isShlowLoading) { } if (!!_isAsync && (typeof fnCallBack === 'function')) { fnCallBack(data, textStatus); } });; return _data; }; return { post: function(sPageUrl, oData, fnCallBack, isAsync) { if ((typeof oData === 'function') && (!fnCallBack)) { fnCallBack = oData; oData = null; } return base(sPageUrl, 'POST', mime.json, oData, fnCallBack, false, isAsync); }, getJSON: function(sPageUrl, oData, fnCallBack, isAsync) { if ((typeof oData === 'function') && (!fnCallBack)) { fnCallBack = oData; oData = null; } return base(sPageUrl, 'get', mime.json, oData, fnCallBack, false, isAsync); } } }(); sun.$ = function(query) { return document.querySelectorAll(query); }; // var __readyFuns = []; // function DOMReady(){ // for(var i=0,l=readyFuns.length;i<l;i++){ // readyFun(); // } // readyFuns = null; // document.removeEventListener('DOMContentLoaded',DOMReady,false); // }; // sun.ready = function(fn){ // if(readyFuns.length == 0){ // document.addEventListener('DOMContentLoaded',DOMReady,false); // } // readyFuns.push(fn); // } sun.context = sun.context || {}; sun.context.getQueryStringByName = function(name) { var result = location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i")); if (result == null || result.length < 1) { return ""; } return result[1]; }; sun.context.cookie = sun.context.cookie || {}; // article detail http://www.cnblogs.com/Darren_code/archive/2011/11/24/Cookie.html sun.context.cookie.setExpires = function (name,value,expiresValue){ var Days = expiresValue; var exp = new Date(); //new Date("December 31, 9998"); exp.setTime(exp.getTime() + Days*24*60*60*1000); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); }; sun.context.cookie.set = function (name,value){ var Days = 30; //此 cookie 将被保存 30 天 this.setExpires(name, value, Days); }; sun.context.cookie.get = function (name){ var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)")); if(arr != null) { return unescape(arr[2]); } return null; }; sun.context.cookie.del = function (name){ var exp = new Date(); var cval= this.get(name); exp.setTime(exp.getTime() - 1); if(cval!=null) { document.cookie= name + "="+cval+";expires="+exp.toGMTString(); } }; sun.context.localStorage = sun.context.localStorage || {}; sun.context.localStorage._ls = window.localStorage; sun.context.localStorage.set = function(name, value) { this._ls.setItem(name,value.toString()) }; sun.context.localStorage.get = function() { return this._ls.getItem(name); }; sun.context.localStorage.del = function(name) { var val = this.get(name); if (!!val) { this.__ls.removeItem("c"); } }; sun.context.localStorage.clearAll = function() { window.localStorage.clear() }; //----------------------------- undealed ----------------------------------- function addEvent (type, element, fun) { if (element.addEventListener) { addEvent = function (type, element, fun) { element.addEventListener(type, fun, false); } } else if(element.attachEvent){ addEvent = function (type, element, fun) { element.attachEvent('on' + type, fun); } } else{ addEvent = function (type, element, fun) { element['on' + type] = fun; } } return addEvent(type, element, fun); } sun.util = sun.util || {}; sun.util.array = sun.util.array || {}; /** * @param => ([1,2,32,4]) * return [1, 2, 4, 32] * * @param => ([1,2,32,4], false) * return [32, 4, 2, 1] * */ sun.util.array.sort = function(arrayList, isAsc) { if (typeof isAsc != 'boolean') { isAsc = true; } function sortNumber(a, b) { if (!!isAsc) { return a - b } else { return b - a } } return arrayList.sort(sortNumber); }; /** * @param => ([0,1,2,3,4,5,6,7,8,9], 6) * return [0, 1, 2, 3, 4, 5, 7, 8, 9] * * @param => ([0,1,2,3,4,5,6,7,8,9], [2,6,8]) * return [0, 1, 3, 4, 5, 7, 9] * */ sun.util.array.remove = function(arrayList, n) { //prototype为对象原型,注意这里为对象增加自定义方法的方法。 if ( n < 0 || typeof n === 'undefined') { return arrayList; } else if (sun.util.isArray(n)) { var _tmp = null; n = this.sort(n, false); for(index in n) { arrayList = this.remove(arrayList, n[index]); } return arrayList; } else { return arrayList.slice(0,n).concat(arrayList.slice(n+1,arrayList.length)); } /* concat方法:返回一个新数组,这个新数组是由两个或更多数组组合而成的。 这里就是返回arrayList.slice(0,n)/arrayList.slice(n+1,arrayList.length) 组成的新数组,这中间,刚好少了第n项。 slice方法: 返回一个数组的一段,两个参数,分别指定开始和结束的位置。 */ }; /** * format number * e.g. 12000 => 1,2000 * @param amtStr number * @return string */ sun.util.formatIntNum = function (amtStr) { var isInt = function (num) { return (num % 1 === 0) }; var amtStr = (isInt(amtStr)) ? amtStr : Number(amtStr).toFixed(0); amtStr = "" + amtStr; var a, renum = ''; var j = 0; var a1 = '', a2 = '', a3 = ''; var tes = /^-/; var isCurrency = (typeof (isCurrency) != 'undefined') ? isCurrency : true; a = amtStr.replace(/,/g, ""); a = a.replace(/[^-\.,0-9]/g, ""); a = a.replace(/(^\s*)|(\s*$)/g, ""); if (tes.test(a)) a1 = '-'; else a1 = ''; a = a.replace(/-/g, ""); if (a != "0" && a.substr(0, 2) != "0.") a = a.replace(/^0*/g, ""); j = a.indexOf('.'); if (j < 0) j = a.length; a2 = a.substr(0, j); a3 = a.substr(j); j = 0; for (i = a2.length; i > 3; i = i - 3) { renum = "," + a2.substr(i - 3, 3) + renum; j++; } renum = a1 + a2.substr(0, a2.length - j * 3) + renum + a3; return renum; } /** * format number of money. * e.g. 12000.235 => 12,000.24 * @param amtStr number * @return string */ sun.util.formatFloat = function (amtStr, isCurrency) { var isInt = function (num) { return (num % 1 === 0); }; var amtStr = (isInt(amtStr)) ? amtStr : Number(amtStr).toFixed(2); amtStr = "" + amtStr; var a, renum = ''; var j = 0; var a1 = '', a2 = '', a3 = ''; var tes = /^-/; var isCurrency = (typeof (isCurrency) != 'undefined') ? isCurrency : true; var subfix = (isInt(amtStr) && isCurrency) ? '.00' : ''; a = amtStr.replace(/,/g, ""); a = a.replace(/[^-\.,0-9]/g, ""); a = a.replace(/(^\s*)|(\s*$)/g, ""); if (tes.test(a)) a1 = '-'; else a1 = ''; a = a.replace(/-/g, ""); if (a != "0" && a.substr(0, 2) != "0.") a = a.replace(/^0*/g, ""); j = a.indexOf('.'); if (j < 0) j = a.length; a2 = a.substr(0, j); a3 = a.substr(j); j = 0; for (i = a2.length; i > 3; i = i - 3) { renum = "," + a2.substr(i - 3, 3) + renum; j++; } renum = a1 + a2.substr(0, a2.length - j * 3) + renum + a3 + subfix; return renum; } sun.util.isEven = function(num) { return num % 2 == 0 ? true : false; }; /** * @param => ([]) * return true * * * @param => ({}) * return false * */ sun.util.isArray = function(arg) { // first way: return Object.prototype.toString.call(arg) === '[object Array]'; // second way: //return (arr instanceof Array); }; /** * * eg. format = 'yyyy-MM-dd hh:mm:ss' * */ sun.util.getCurrentTime = function(format) { var _this = new Date(); var o = { "M+": _this.getMonth() + 1, //month "d+": _this.getDate(), //day "h+": _this.getHours(), //hour "m+": _this.getMinutes(), //minute "s+": _this.getSeconds(), //second "q+": Math.floor((_this.getMonth() + 3) / 3), //quarter "S": _this.getMilliseconds() //millisecond } if(!format) { format = "yyyy-MM-dd hh:mm:ss"; } if (/(y+)/.test(format)) format = format.replace(RegExp.$1, (_this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)); return format; }; /** * * @param '<span>I am Hero!</span>' * @return '<span>I am Hero!</span>' */ sun.util.htmlDecode = function(html) { var a = document.createElement( 'a' ); a.innerHTML = html; return a.textContent; }; /** * * @param '<span>I am Hero!</span>' * @return '<span>I am Hero!</span>' */ sun.util.htmlEncode = function ( html ) { return document.createElement( 'a' ).appendChild( document.createTextNode( html ) ).parentNode.innerHTML; }; sun.util.parseToInt = function(obj, defaultNum, radix){ var _t = 0; if (typeof radix != 'number'){ radix = 10; } _t = parseInt(obj, radix); if (!_t){ _t = defaultNum; } return _t; }; /** * @param => ('I am a boy', 'boy', 'girl') * return 'I am a girl' * enhance replace * @param oString string * @param AFindText string * @param ARepText string * @return string */ sun.util.replaceAll = function (oString, AFindText, ARepText) { var raRegExp = new RegExp(AFindText.replace(/([\(\)\[\]\{\}\^\$\+\-\*\?\.\"\'\|\/\\])/g, "\\$1"), "ig"); return oString.replace(raRegExp, ARepText); }; /** * @param => ('best {0} for {1}', 'wish', 'you') * return 'best wish for you' */ sun.util.stringFormat = function(txt) { var arg = arguments, matchResult, matLength, str = txt, reg = /\{\d+?\}/gmi, i; matchResult = str.match(reg); if (matchResult) { matLength = matchResult.length; if (arg.length >= matLength) { for (i = 0; i < matLength; i++) { str = str.replace(matchResult[i], arg[i + 1]); } } } return str; }; sun.util.transforTime = function (time) { var date = parseInt(time); var weekdays = ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"]; var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"]; var result = ""; result += weekdays[new Date(date).getDay()]; result += " "; result += months[new Date(date).getMonth()]; result += " "; result += new Date(date).getDate(); result += " "; result += new Date(date).getFullYear(); result += " "; result += new Date(date).getHours(); result += ":"; result += new Date(date).getMinutes(); return result; };
sun.md.js
sun = sun || {};
sun.md = (function(global){
var self,
_userAgent = navigator.userAgent,
_rWins = /Windows/i,
_rWP = /IEMobile/i,
_rAndroid = /Android/i,
_rIPhone = /iPhone/i;
androidScreenPixelRatio = {
pr : null,
screenHeight : null,
getScreenHeight : function() {
var that = this;
if (null == that.screenHeight) {
that.screenHeight = (screen.width < screen.height) ? screen.height : screen.width;
}
return that.screenHeight;
},
getDpi : function() {
var that = this, dpi = 320;
if (1200 <= that.getScreenHeight()) {
dpi = "device-dpi";
}
return dpi;
},
getPixelRatio : function() {
var that = this;
if (null == that.pr) {
that.pr = window.devicePixelRatio;
}
return that.pr;
},
judgePixelRatio : function(pr) {
var that = this;
return (pr === that.getPixelRatio());
},
isLdpi : function() {
var that = this;
return that.judgePixelRatio(0.75);
},
isMdpi : function() {
var that = this;
return that.judgePixelRatio(1);
},
isHdpi : function() {
var that = this;
return that.judgePixelRatio(1.5);
}
};
BOMHeight = function() {
var pageHeight = window.innerHeight;
if(typeof pageHeight != "number"){
if(document.compatMode == "CSS1Compat"){
pageHeight = document.documentElement.clientHeight;
}else{
pageHeight = document.body.clientHeight;
}
}
return pageHeight;
};
_parseViewPortContent = function(initWidth, initHeight, isUserScale, initScale, minScale, maxScale, isIntelligence) {
var w = !!initWidth ? initWidth : "100%",
h = !!initHeight ? initHeight : BOMHeight(),
isUserScale = !!isUserScale ? 'yes' : 'no',
initScale = !!initScale ? initScale : 1.0, //最大极限是 1.69
minScale = !!minScale ? minScale : 0.1,
maxScale = !!maxScale ? maxScale : 1.0,
domeMeta = '',
targetDensitydpi = 'device-dpi', // [dpi_value(70 - 400) | device-dpi | high-dpi | medium-dpi | low-dpi]
clientW = document.documentElement.clientWidth,
screenW = window.screen.width;
if (w === '100%') {
w = "device-width";
initScale = 1.0;
targetDensitydpi = 'device-dpi';
if (!!isIntelligence) {
initScale = (screenW/clientW).toFixed(4);
if(self.isAndroid()) {
targetDensitydpi = 'device-dpi';
}
}
}
if (typeof w === 'number') {
if (!!isIntelligence) {
w = Math.max(w, screenW);
}
initScale = (screenW/w).toFixed(4);
if(self.isAndroid()) {
initScale = 1;
targetDensitydpi = (w/2.25714).toFixed(4);
if (targetDensitydpi < 70) {
targetDensitydpi = 70;
}
if (targetDensitydpi > 400) {
targetDensitydpi = 400;
}
}
}
domeMeta =
'width=' + w +
//', height=' + h +
', minimum-scale=' + minScale +
', maximum-scale=' + maxScale +
', initial-scale=' + initScale +
', user-scalable=' + isUserScale +
', target-densitydpi=' + targetDensitydpi;
return domeMeta.trim();
};
_getScreen = function(){
// detail information to http://www.cnblogs.com/tearer/archive/2010/09/06/1819471.html
// window.devicePixelRatio = 物理像素 / dips
// window.screen.width = Android设备返回的是物理像素宽,IOS =》 dips宽
var s = "网页可见区域宽:" + document.body.clientWidth + "\n";
s += " 网页可见区域高:" + document.body.clientHeight + "\n";
s += " 网页可见区域宽:" + document.body.offsetWidth + " (包括边线和滚动条的宽)" + "\n";
s += " 网页可见区域高:" + document.body.offsetHeight + " (包括边线的宽)" + "\n";
s += " 网页正文全文宽:" + document.body.scrollWidth + "\n";
s += " 网页正文全文高:" + document.body.scrollHeight + "\n";
s += " 网页被卷去的高(ff):" + document.body.scrollTop + "\n";
s += " 网页被卷去的高(ie):" + document.documentElement.scrollTop + "\n";
s += " 网页被卷去的左:" + document.body.scrollLeft + "\n";
s += " 网页正文部分上:" + window.screenTop + "\n";
s += " 网页正文部分左:" + window.screenLeft + "\n";
s += " 屏幕分辨率的高:" + window.screen.height + "\n";
s += " 屏幕分辨率的宽:" + window.screen.width + "\n";
s += " 屏幕可用工作区高度:" + window.screen.availHeight + "\n";
s += " 屏幕可用工作区宽度:" + window.screen.availWidth + "\n";
s += " 你的屏幕设置是 " + window.screen.colorDepth + " 位彩色" + "\n";
s += " 物理像素/独立像素比: " + window.devicePixelRatio + " 像素/英寸" + "\n";
s += " 你的屏幕设置 " + window.screen.deviceXDPI + " 像素/英寸" + "\n";
return s;
};
self = {};
self.userAgent = _userAgent;
//self.screen = _getScreen();
self.getViewPortContent = function() {
var domeMeta = document.getElementsByName('viewport')[0];
return domeMeta.content;
};
// var options = {
// initWidth: null,
// initHeight: null,
// isUserScale: null,
// initScale: null,
// minScale: null,
// maxScale: null,
// isIntelligence: bool /default null
// }
// default options likes: { initWidth : '100%' } or { initWidth : 540 }
// <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0">
self.setViewPortContent = function (options) {
var DOM_meta = document.getElementsByName('viewport')[0],
_content = '';
if (!DOM_meta) {
DOM_meta = document.createElement('meta');
DOM_meta.name = 'viewport';
document.head.appendChild(DOM_meta);
}
if (typeof options === 'string'){
_content = _content;
} else if (typeof options === 'object') {
_content = _parseViewPortContent(options.initWidth,
options.initHeight,
options.isUserScale,
options.initScale,
options.minScale,
options.maxScale,
options.isIntelligence);
} else {
_content = _parseViewPortContent();
}
DOM_meta.content = _content;
};
self.isAndroid = function () {
var me = this,
result = false;
if((_userAgent.match(_rAndroid))&& (_userAgent.match(_rAndroid).length > 0)) {
result = true;
}
return result;
};
self.isWindows = function () {
var me = this,
result = false;
if((_userAgent.match(_rWins)) && (_userAgent.match(_rWins).length > 0)) {
result = true;
}
return result;
};
self.isWinPhone = function () {
var me = this,
result = false;
if((_userAgent.match(_rWP)) && (_userAgent.match(_rWP).length > 0)) {
result = true;
}
return result;
};
self.isIOS = function () {
var me = this,
result = false;
if((_userAgent.match(_rIPhone))&& (_userAgent.match(_rIPhone).length > 0)) {
result = true;
}
return result;
};
return self;
})(this);
相关推荐
2. `page-break-after/before` 属性:这些属性可以用来指定元素之后或之前添加分页符,确保元素在新的页面开始。 3. `break-inside/avoid` 属性:防止元素跨越多页,保证内容完整性。 4. 使用CSS Flexbox或Grid布局...
在jQuery Mobile框架中,开发移动应用时,确保图片能够自适应不同手机屏幕大小是一项关键任务。这不仅可以提高用户体验,还能确保应用在各种设备上显示得美观且功能正常。标题和描述提到的问题,主要关注如何利用...
首先,jQuery Mobile的核心是其UI框架,它提供了一套完整的组件和样式,包括导航条、页签、表单、按钮、弹出对话框等,这些都经过精心设计,能够自动适应各种屏幕尺寸。在开发过程中,利用这些预定义的UI元素,可以...
这通常通过调用浏览器的`window.print()`函数实现,但需要确保页面布局和CSS样式适配打印环境。 5. **优化与兼容性**: 虽然PDF.js具有良好的跨浏览器兼容性,但在一些老版本或者非主流浏览器上可能存在问题。...
1. **MobilePage**: 这是所有移动Web应用程序的基础,它可以自动检测用户的设备并呈现相应的页面布局。 2. **MobileForm**: 专为移动设备设计的表单控件,它提供了更友好的交互体验,如触摸友好型按钮和输入字段。 3...
本项目提供了一个"HTML手机单页demo",包括个人中心详情页面和H5详情页面,旨在展示如何构建适应不同平台的响应式Web应用。 1. HTML5:HTML5是超文本标记语言的最新版本,增加了许多新的语义元素和功能,如离线存储...
10. **响应式设计**:在Web开发中考虑移动优先,实现不同设备的适配和优化。 在学习过程中,结合"图片与代码",我们可以通过实例来加深理解,观察代码是如何与页面元素相互作用,以及如何通过调试和测试来完善应用...
例如,对于名为mwamobilewebapplication的项目,默认首页文件可能命名为myPage.aspx,这个页面继承了`System.Web.UI.MobileControls.MobilePage`类而非传统的`System.Web.UI.Page`类。`MobilePage`类扩展了`Page`类...
鉴于市场上用户的手机型号、种类、屏幕分辨率等参差不齐,传统方式根据主流系统分别开发相应的系统耗时又耗力,为了高效开发并节约开发项目成本,本文采用Android+HTML5相结合的方式进行移动端Web系统的设计研发工作...
在现代Web应用中,打印功能不仅限于简单的文档输出,还涉及到复杂的页面布局、分页处理以及定制化的打印样式。本文将深入探讨JavaScript在实现Web打印时的关键知识点,并结合“打印分页相关”的主题进行详述。 首先...
在这个项目中,CSS文件可能包含手机屏幕适配的样式规则,如响应式设计,确保页面在不同尺寸的设备上都能良好展示。 2. **page.html、single.html、index.html等HTML文件**:这些是网站的主要页面结构,HTML(超文本...
在移动Web开发中,一个重要的挑战是如何使Web应用能够适应各种不同的屏幕尺寸和分辨率,这正是ASP.NET 2.0所擅长的领域。通过使用System.Web.UI.MobileControls命名空间下的控件,如MobilePage和MobileControl,...
【Web网页设计制作-毕业设计期末大作业源码】(FZY031)微信系统分离出的手机网站模板首页(单页)是一个专为移动端设计的网站模板,旨在帮助学生进行毕业设计或期末大作业时,快速构建适应手机浏览的微信系统页面。...
随着移动设备的普及和技术的发展,创建一个既能在桌面浏览器上良好运行又能适应各种移动设备屏幕大小的网站变得尤为重要。本书旨在通过详细介绍如何结合HTML5和SharePoint 2013来实现这一目标。 #### 知识点详解 *...
WebApp/Web Page设置:可以通过`<link rel="apple-touch-icon">`设置应用图标,`<meta name="apple-mobile-web-app-capable" content="yes">`开启离线应用模式,`<meta name="viewport">`用于适配不同设备的屏幕尺寸...
- **题目**: `page`指令的哪个属性可以设置JSP页面是否可多线程访问? - **答案**:C. `isThreadSafe` **6. 解决客户端乱码问题** - **题目**: 客户端出现乱码的原因可能是没有设置`page`指令中的哪个属性? - *...
- 弹性布局(Flexbox)和网格布局(CSS Grid):适应不同设备屏幕。 - 媒体查询:根据设备特性调整布局和样式。 - 图片适配:使用srcset和sizes属性,提供不同分辨率的图片。 5. **网络优化**: - HTTP/2:...
- **全局性设置**:Web.config中的配置只能为整个站点或单个页面指定单一的Master Page和Theme,限制了针对不同页面的个性化风格切换。 - **配置复杂性**:使用location结点进行逐个页面的设置繁琐且不易维护。 ...
WAP网站是为了适应手机屏幕大小和网络速度而设计的一种特殊类型的网站。 2. **触屏版**:指专门针对触摸屏设备优化的网站版本。随着智能手机和平板电脑的普及,触屏版网站变得越来越重要。 3. **单页应用**:单页...
语言:中文 (简体) 一键生成骨架屏create web skeleton in first screen基于饿了么骨架屏方案改造,目前适配移动端方案1.打开网页2.点击应用图标,选择生成骨架屏3.会自动生成当前页面的骨架屏内