精华内容
下载资源
问答
  • QQ:285679784 欢迎加入博主CSDN资源QQ群799473954(附加信息:CSDN博客)一起学习 ! 公众号配置 第一步:配置js安全域名(微信公众平台=>公众号设置=>功能设置=>js接口安全域名) 第二步:配置白名单...

     QQ:285679784   欢迎加入博主CSDN资源QQ群799473954(附加信息:CSDN博客)一起学习 !

     

    公众号配置

    第一步:配置js安全域名(微信公众平台=>公众号设置=>功能设置=>js接口安全域名)

    第二步:配置白名单(微信公众平台=>基本配置=>ip白名单=>查看,配置多ip,可以换行输入),如果是本地测试,可以在百度中搜索ip,获取本地公网IP地址

    webapi

    第一步:获取access_token,access_token是获取其他接口信息的钥匙,所有接口都需要调用access_token

    AccessToken.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.Web;
    using System.Web.Script.Serialization;//需要添加System.Web.Extensions引用
    
    namespace Third.WeChat
    {
        /// <summary>
        /// 获取微信token的类(获取access_token,access_token是获取其他接口信息的钥匙,所有接口都需要调用access_token)
        /// @Author LiKely
        /// @Date 2019-9-18 20:17:39
        /// </summary>
        public static class AccessToken
        {
            /// <summary>
            /// 拉取AccessToken,微信每天公共2000次AccessToken的获取,所以需要缓存AccessToken
            /// </summary>
            /// <returns>用户凭证:AccessToken</returns>
            public static string GetTokenCache(string appid, string appsecret)
            {
                string TokenCache;
                if (HttpContext.Current.Cache["AccessToken"] != null)
                {
                    TokenCache = HttpContext.Current.Cache["AccessToken"].ToString();
                }
                else
                {
                    TokenCache = AddTokenCache(appid, appsecret);
                }
                return TokenCache;
            }
    
            /// <summary>
            /// 将AccessToken添加到缓存
            /// </summary>
            /// <returns>AccessToken</returns>
            private static string AddTokenCache(string appid, string appsecret)
            {
                //获取AccessToken
                string AccessToken = GetAccessToken(appid, appsecret);
                HttpContext.Current.Cache.Insert("AccessToken", AccessToken,null,DateTime.Now.AddSeconds(7200),TimeSpan.Zero);
                return AccessToken;
            }
    
            /// <summary>
            /// 获取AccessToken
            /// </summary>
            /// <returns>AccessToken</returns>
            private static string GetAccessToken(string appid, string appsecret)
            {
                string accessToken = "";
                string respText = "";
                string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appid, appsecret);
    
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
                using (Stream resStream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(resStream, Encoding.Default);
                    respText = reader.ReadToEnd();
                    resStream.Close();
                }
    
                JavaScriptSerializer jss = new JavaScriptSerializer();
                Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(respText);
                accessToken = respDic["access_token"].ToString();
                return accessToken;
            }
        }
    }
    

    第二步:验证权限我们需要获取四个参数appId、timestamp、nonceStr、signature,jsapi_ticket获取到jsapi_ticket有效时间为7200s

    JsapiTicket.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.Web.Security;
    using System.Net;
    using System.IO;
    using Model.Third.WeChat;
    using System.Web.Script.Serialization;//需要添加System.Web.Extensions引用
    
    namespace Third.WeChat.business
    {
        /// <summary>
        /// 获取微信Jssdk分享签名信息的参数
        /// @Author LiKely
        /// @Date 2019-9-18 20:21:51
        /// </summary>
        public static class JsapiTicket
        {
            private static JavaScriptSerializer jss = new JavaScriptSerializer();
    
            /// <summary>
            /// 获取JsApi权限配置的数组/四个参数
            /// </summary>
            /// <param name="AppId"></param>
            /// <param name="AppSecret"></param>
            /// <param name="reqUrl">当前的地址</param>
            /// <returns></returns>
            public static JsapiTicketInfo GetObject(string AppId, string AppSecret, string reqUrl)
            {
                string jsapi_ticket = "";
                string access_token = "";
                //ticket 缓存7200秒
                if (System.Web.HttpContext.Current.Cache["jsapi_ticket"] != null)
                {
                    access_token = AccessToken.GetTokenCache(AppId, AppSecret);
                    jsapi_ticket = System.Web.HttpContext.Current.Cache["jsapi_ticket"].ToString();
                }
                else
                {
                    access_token = AccessToken.GetTokenCache(AppId, AppSecret);
                    jsapi_ticket = GetTicket(access_token);
                    System.Web.HttpContext.Current.Cache.Insert("jsapi_ticket", jsapi_ticket, null, DateTime.Now.AddSeconds(7200), TimeSpan.Zero);
                }
    
                //string access_token = AccessToken.GetTokenCache(AppId, AppSecret);
                //jsapi_ticket = GetTicket(access_token);
    
                //string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.ToString();//当前的地址
                string timestamp = WxPayApi.GenerateTimeStamp();//生成签名的时间戳
                string nonceStr = WxPayApi.GenerateNonceStr();//生成签名的随机串
    
                Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(jsapi_ticket);
                jsapi_ticket = respDic["ticket"].ToString();//获取ticket
                string[] ArrayList = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + nonceStr, "url=" + reqUrl };
                Array.Sort(ArrayList);
                string signature = string.Join("&", ArrayList);
                signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
    
                JsapiTicketInfo ticket = new JsapiTicketInfo();
                ticket.appId = AppId;
                ticket.timestamp = timestamp;
                ticket.nonceStr = nonceStr;
                ticket.signature = signature;
                ticket.access_token = access_token;
                ticket.jsapi_ticket = jsapi_ticket;
    
                return ticket;
            }
    
            /// <summary>
            /// 获取JsApi权限配置的数组/四个参数
            /// </summary>
            /// <returns></returns>
            public static string GetJsApiString(string AppId, string AppSecret)
            {
    
                string timestamp = WxPayApi.GenerateTimeStamp();//生成签名的时间戳
                string nonceStr = WxPayApi.GenerateNonceStr();//生成签名的随机串
                string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.ToString();//当前的地址
                string jsapi_ticket = "";
                //ticket 缓存7200秒
                if (System.Web.HttpContext.Current.Cache["jsapi_ticket"] == null)
                {
                    string access_token = AccessToken.GetTokenCache(AppId, AppSecret);
                    jsapi_ticket = GetTicket(access_token);
                    System.Web.HttpContext.Current.Cache.Insert("jsapi_ticket", jsapi_ticket, null, DateTime.Now.AddSeconds(7200), TimeSpan.Zero);
                }
                else
                {
                    jsapi_ticket = System.Web.HttpContext.Current.Cache["jsapi_ticket"].ToString();
                }
    
                Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(jsapi_ticket);
                jsapi_ticket = respDic["ticket"].ToString();//获取ticket
                string[] ArrayList = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + nonceStr, "url=" + url };
                Array.Sort(ArrayList);
                string signature = string.Join("&", ArrayList);
                signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
    
                JsapiTicketInfo ticket = new JsapiTicketInfo();
                ticket.appId = AppId;
                ticket.timestamp = timestamp;
                ticket.nonceStr = nonceStr;
                ticket.signature = signature;
    
                return jss.Serialize(ticket);
            }
    
            /// <summary>
            /// 获取Ticket Json
            /// </summary>
            /// <returns>ticket对象</returns>
            private static string GetTicket(string access_token)
            {
                string respText = "";
                string url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", access_token);
    
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
                using (Stream resStream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(resStream, Encoding.Default);
                    respText = reader.ReadToEnd();
                    resStream.Close();
                }
    
                //Dictionary<string, object> respDic = (Dictionary<string, object>)jss.DeserializeObject(respText);
                return respText;
            }
        }
    }
    

    JsapiTicketInfo.cs 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Model.Third.WeChat
    {
        /// <summary>
        /// 微信Jssdk分享签名信息
        /// </summary>
        [Serializable]
        public class JsapiTicketInfo
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            public JsapiTicketInfo()
            {
                //
                //TODO: 在此处添加构造函数逻辑
                //
            }
    
            /// <summary>
            /// 必填,公众号的唯一标识
            /// </summary>
            public string appId { get; set; }
    
            /// <summary>
            /// 必填,生成签名的时间戳
            /// </summary>
            public string timestamp { get; set; }
    
            /// <summary>
            /// 必填,生成签名的随机串
            /// </summary>
            public string nonceStr { get; set; }
    
            /// <summary>
            /// 必填,签名
            /// </summary>
            public string signature { get; set; }
    
            /// <summary>
            /// access_token
            /// </summary>
            public string access_token { get; set; }
    
            /// <summary>
            /// jsapi_ticket
            /// </summary>
            public string jsapi_ticket { get; set; }
        }
    }
    

    扩展方法

    /**
    * 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数
     * @return 时间戳
    */
    public static string GenerateTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return Convert.ToInt64(ts.TotalSeconds).ToString();
    }
    
    /**
    * 生成随机串,随机串包含字母或数字
    * @return 随机串
    */
    public static string GenerateNonceStr()
    {
        RandomGenerator randomGenerator = new RandomGenerator();
        return randomGenerator.GetRandomUInt().ToString();
    }

    WebApi接口实现

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    
    using System.Data;
    using Newtonsoft.Json.Linq;
    
    namespace API.Controllers
    {
        /// <summary>
        /// 微信分享模块API
        /// </summary>
        [RoutePrefix("Share")]
        public class ShareController : ApiController
        {
            /// <summary>
            /// 获取微信Jssdk分享签名信息的参数
            /// </summary>
            /// <returns></returns>
            [Route("~/wx/jsapi/ticket"), HttpPost, AllowAnonymous]
            public HttpResponseMessage GetTicket([FromBody] JObject obj)
            {
                ResultData result = new ResultData();
                try
                {
                    string shareUrl = obj["shareUrl"] != null ? obj["shareUrl"].ToString() : "";
                    if (string.IsNullOrWhiteSpace(shareUrl))
                    {
                        result.success = false;
                        result.return_code = HttpStatusCode.OK;
                        result.return_msg = "参数错误";
                        return Request.CreateResponse(HttpStatusCode.OK, result);
                    }
    
                    result.return_code = HttpStatusCode.OK;
                    result.return_msg = "请求成功";
                    result.success = true;
    
                    string AppID ="微信公众号APPID";
                    string AppSecret ="微信公众号SECRET";
                    result.data = JsapiTicket.GetObject(AppID, AppSecret, shareUrl);
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }
                catch (Exception ex)
                {
                    result.success = false;
                    result.return_code = HttpStatusCode.OK;
                    result.return_msg = "接口异常,请稍后再试!" + ex.Message;
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }
            }
        }
    }
    

     

    mui h5

     wx.share.js

    /* 
    描述:微信浏览器,自定义分享
    作者:LiKely
    时间:2019-9-19 14:31:34
    */
    
    /* 自定义类 */
    var wx = wx || {};
    
    wx.Share = function(shareParam, shareUrl) {
    
    	//当前URL
    	shareUrl = shareUrl ? shareUrl : window.location.href;
    
    	//获取签名信息
    	mui.ajax('https://你的api域名.com/wx/jsapi/ticket', {
    		type: 'post', //HTTP请求类型
    		dataType: 'json', //服务器返回json格式数据
    		timeout: 10000, //超时时间设置为10秒;
    		headers: {
    			'Content-Type': "application/x-www-form-urlencoded"
    		},
    		data: {
    			'shareUrl': shareUrl
    		},
    		success: function(res) {
    
    			//请求失败时的处理
    			if (!res.success) {
    				mui.toast(res.return_msg);
    				return false;
    			}
    
    			// 分享配置
    			wx.config({
    				debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    				appId: res.data.appId, // 必填,企业号的唯一标识
    				timestamp: res.data.timestamp, // 必填,生成签名的时间戳
    				nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
    				signature: res.data.signature, // 必填,签名,见附录1
    				jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo',
    					'onMenuShareQZone'
    				] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    			});
    
    			wx.ready(function() {
    				//分享到朋友圈
    				wx.onMenuShareTimeline({
    					title: shareParam.title,
    					link: shareParam.link,
    					imgUrl: shareParam.imgUrl,
    					success: function() {
    						if (shareParam.successFn) {
    							shareParam.successFn();
    						}
    					},
    					cancel: function() {
    						if (shareParam.cancelFn) {
    							shareParam.cancelFn();
    						}
    					}
    				});
    
    				//分享给朋友
    				wx.onMenuShareAppMessage({
    					title: shareParam.title,
    					desc: shareParam.desc,
    					link: shareParam.link,
    					imgUrl: shareParam.imgUrl,
    					type: shareParam.type,
    					dataUrl: shareParam.dataUrl,
    					success: function() {
    						if (shareParam.successFn) {
    							shareParam.successFn();
    						}
    					},
    					cancel: function() {
    						if (shareParam.cancelFn) {
    							shareParam.cancelFn();
    						}
    					}
    				});
    
    				//分享到QQ
    				wx.onMenuShareQQ({
    					title: shareParam.title,
    					desc: shareParam.desc,
    					link: shareParam.link,
    					imgUrl: shareParam.imgUrl,
    					success: function() {
    						if (shareParam.successFn) {
    							shareParam.successFn();
    						}
    					},
    					cancel: function() {
    						if (shareParam.cancelFn) {
    							shareParam.cancelFn();
    						}
    					}
    				});
    
    				//分享到腾讯微博
    				wx.onMenuShareWeibo({
    					title: shareParam.title,
    					desc: shareParam.desc,
    					link: shareParam.link,
    					imgUrl: shareParam.imgUrl,
    					success: function() {
    						if (shareParam.successFn) {
    							shareParam.successFn();
    						}
    					},
    					cancel: function() {
    						if (shareParam.cancelFn) {
    							shareParam.cancelFn();
    						}
    					}
    				});
    
    				//分享到QQ空间
    				wx.onMenuShareQZone({
    					title: shareParam.title,
    					desc: shareParam.desc,
    					link: shareParam.link,
    					imgUrl: shareParam.imgUrl,
    					success: function() {
    						if (shareParam.successFn) {
    							shareParam.successFn();
    						}
    					},
    					cancel: function() {
    						if (shareParam.cancelFn) {
    							shareParam.cancelFn();
    						}
    					}
    				});
    			});
    
    		},
    		error: function(xhr, type, errorThrown) {}
    	});
    }
    

    h5.html 初始化调用js

    <!DOCTYPE html>
    <html lang="zh-Hans" xml:lang="zh-Hans" class="hairlines" style="font-size: 37.5px;">
    	<head>
    		<meta charset="utf-8">
    		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    		<title>微信H5自定义分享</title>
    		<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    	</head>
    	<body>
    	分享页面内容
    	</body>
    	<script type="text/javascript" src="js/mui.js?v=186522030"></script>
    	<script type="text/javascript" src="js/wx.share.js?v=186522030"></script>
    	<script type="text/javascript">
    		mui.ready(function() {
    			loadWxShare();
    		})
    		
    		// 微信浏览器,自定义分享
    		function loadWxShare() {
    			var _self = this;
    		 
    			var shareUrl = window.location.href;
    			var shareParam = {
    				title: '', //分享标题
    				desc: '', //分享描述
    				link: 'http://xxxx.com', //分享链接,该链接域名必须与当前企业的可信域名一致
    				imgUrl: 'http://xxxxxxx/logo.png', //分享图标
    				type: 'link', //分享类型 music、 video或link, 不填默认为link
    				dataUrl: '', // 如果type是music或video, 则要提供数据链接, 默认为空
    				successFn: function() { // 用户确认分享后执行的回调函数
    		 
    				},
    				cancelFn: function() { // 用户取消分享后执行的回调函数
    		 
    				}
    			};
    		 
    			wx.Share(shareParam, shareUrl);
    		 
    		}
    	</script>
    </html>
    

     

    展开全文
  • 使用 Chrome 浏览器 无痕模式 登录 ,按 F12 打开控制台并切换到 Network 标签 私信小冰,找到包含 send 路径的 Network 请求,复制对应 Request Headers 粘贴到项目 config 目录的 ice.header 文件中,覆盖掉默认...
  • 此文严格按照W3C规范和部分实际项目可读性,浏览器加载,性能等众多属性权衡,做出平时前端编码规范文 档。供广大web工作者参考并实施,对维护和项目扩展升级都能省时省力。 转载请注明出处,JS前端实用开发QQ群 :...

    此文严格按照W3C规范和部分实际项目可读性,浏览器加载,性能等众多属性权衡,做出平时前端编码规范文

    档。供广大web工作者参考并实施,对维护和项目扩展升级都能省时省力。

    转载请注明出处,JS前端实用开发QQ群 :147250970  欢迎加入~!



    HTML编码规范

    1 前言

    2 代码风格

      2.1 缩进与换行

      2.2 命名

      2.3 标签

      2.4 属性

    3 通用

      3.1 DOCTYPE

      3.2 编码

      3.3 CSS 和 JavaScript 引入

    4 head

      4.1 title

      4.2 favicon

      4.3 viewport

    5 图片

    6 表单

      6.1 控件标题

      6.2 按钮

      6.3 可访问性 (A11Y)

    7 多媒体

    8 模板中的 HTML

    1 前言

    HTML 作为描述网页结构的超文本标记语言,在百度一直有着广泛的应用。本文档的目标是使 HTML 代码风格保持一致,容易被理解和被维护。

    2 代码风格

    2.1 缩进与换行

    [强制] 使用 4 个空格做为一个缩进层级,不允许使用 2 个空格 或 tab 字符。

    示例:

    <ul>
        <li>first</li>
        <li>second</li>
    </ul>

    [建议] 每行不得超过 120 个字符。

    解释:

    过长的代码不容易阅读与维护。但是考虑到 HTML 的特殊性,不做硬性要求。

    2.2 命名

    [强制] class 必须单词全字母小写,单词间以 - 分隔。

    [强制] class 必须代表相应模块或部件的内容或功能,不得以样式信息进行命名。

    示例:

    <!-- good -->
    <div class="sidebar"></div>
    
    <!-- bad -->
    <div class="left"></div>

    [强制] 元素 id 必须保证页面唯一。

    解释:

    同一个页面中,不同的元素包含相同的 id,不符合 id 的属性含义。并且使用 document.getElementById 时可能导致难以追查的问题。

    [建议] id 建议单词全字母小写,单词间以 - 分隔。同项目必须保持风格一致。

    [建议] idclass 命名,在避免冲突并描述清楚的前提下尽可能短。

    示例:

    <!-- good -->
    <div id="nav"></div>
    <!-- bad -->
    <div id="navigation"></div>
    
    <!-- good -->
    <p class="comment"></p>
    <!-- bad -->
    <p class="com"></p>
    
    <!-- good -->
    <span class="author"></span>
    <!-- bad -->
    <span class="red"></span>

    [强制] 禁止为了 hook 脚本,创建无样式信息的 class

    解释:

    不允许 class 只用于让 JavaScript 选择某些元素,class 应该具有明确的语义和样式。否则容易导致 CSS class 泛滥。

    使用 id、属性选择作为 hook 是更好的方式。

    [强制] 同一页面,应避免使用相同的 name 与 id

    解释:

    IE 浏览器会混淆元素的 id 和 name 属性, document.getElementById 可能获得不期望的元素。所以在对元素的 id 与name 属性的命名需要非常小心。

    一个比较好的实践是,为 id 和 name 使用不同的命名法。

    示例:

    <input name="foo">
    <div id="foo"></div>
    <script>
    // IE6 将显示 INPUT
    alert(document.getElementById('foo').tagName);
    </script>

    2.3 标签

    [强制] 标签名必须使用小写字母。

    示例:

    <!-- good -->
    <p>Hello StyleGuide!</p>
    
    <!-- bad -->
    <P>Hello StyleGuide!</P>

    [强制] 对于无需自闭合的标签,不允许自闭合。

    解释:

    常见无需自闭合标签有 inputbrimghr 等。

    示例:

    <!-- good -->
    <input type="text" name="title">
    
    <!-- bad -->
    <input type="text" name="title" />

    [强制] 对 HTML5 中规定允许省略的闭合标签,不允许省略闭合标签。

    解释:

    对代码体积要求非常严苛的场景,可以例外。比如:第三方页面使用的投放系统。

    示例:

    <!-- good -->
    <ul>
        <li>first</li>
        <li>second</li>
    </ul>
    
    <!-- bad -->
    <ul>
        <li>first
        <li>second
    </ul>

    [强制] 标签使用必须符合标签嵌套规则。

    解释:

    比如 div 不得置于 p 中,tbody 必须置于 table 中。

    详细的标签嵌套规则参见HTML DTD中的 Elements 定义部分。

    [建议] HTML 标签的使用应该遵循标签的语义。

    解释:

    下面是常见标签语义

    • p - 段落
    • h1,h2,h3,h4,h5,h6 - 层级标题
    • strong,em - 强调
    • ins - 插入
    • del - 删除
    • abbr - 缩写
    • code - 代码标识
    • cite - 引述来源作品的标题
    • q - 引用
    • blockquote - 一段或长篇引用
    • ul - 无序列表
    • ol - 有序列表
    • dl,dt,dd - 定义列表

    示例:

    <!-- good -->
    <p>Esprima serves as an important <strong>building block</strong> for some JavaScript language tools.</p>
    
    <!-- bad -->
    <div>Esprima serves as an important <span class="strong">building block</span> for some JavaScript language tools.</div>

    [建议] 在 CSS 可以实现相同需求的情况下不得使用表格进行布局。

    解释:

    在兼容性允许的情况下应尽量保持语义正确性。对网格对齐和拉伸性有严格要求的场景允许例外,如多列复杂表单。

    [建议] 标签的使用应尽量简洁,减少不必要的标签。

    示例:

    <!-- good -->
    <img class="avatar" src="image.png">
    
    <!-- bad -->
    <span class="avatar">
        <img src="image.png">
    </span>

    2.4 属性

    [强制] 属性名必须使用小写字母。

    示例:

    <!-- good -->
    <table cellspacing="0">...</table>
    
    <!-- bad -->
    <table cellSpacing="0">...</table>

    [强制] 属性值必须用双引号包围。

    解释:

    不允许使用单引号,不允许不使用引号。

    示例:

    <!-- good -->
    <script src="esl.js"></script>
    
    <!-- bad -->
    <script src='esl.js'></script>
    <script src=esl.js></script>

    [建议] 布尔类型的属性,建议不添加属性值。

    示例:

    <input type="text" disabled>
    <input type="checkbox" value="1" checked>

    [建议] 自定义属性建议以 xxx- 为前缀,推荐使用 data-

    解释:

    使用前缀有助于区分自定义属性和标准定义的属性。

    示例:

    <ol data-ui-type="Select"></ol>

    3 通用

    3.1 DOCTYPE

    [强制] 使用 HTML5 的 doctype 来启用标准模式,建议使用大写的 DOCTYPE

    示例:

    <!DOCTYPE html>

    [建议] 启用 IE Edge 模式。

    示例:

    <meta http-equiv="X-UA-Compatible" content="IE=Edge">

    [建议] 在 html 标签上设置正确的 lang 属性。

    解释:

    有助于提高页面的可访问性,如:让语音合成工具确定其所应该采用的发音,令翻译工具确定其翻译语言等。

    示例:

    <html lang="zh-CN">

    3.2 编码

    [强制] 页面必须使用精简形式,明确指定字符编码。指定字符编码的 meta 必须是 head 的第一个直接子元素。

    解释:

    见 HTML5 Charset能用吗 一文。

    示例:

    <html>
        <head>
            <meta charset="UTF-8">
            ......
        </head>
        <body>
            ......
        </body>
    </html>

    [建议] HTML 文件使用无 BOM 的 UTF-8 编码。

    解释:

    UTF-8 编码具有更广泛的适应性。BOM 在使用程序或工具处理文件时可能造成不必要的干扰。

    3.3 CSS 和 JavaScript 引入

    [强制] 引入 CSS 时必须指明 rel="stylesheet"

    示例:

    <link rel="stylesheet" href="page.css">

    [建议] 引入 CSS 和 JavaScript 时无须指明 type 属性。

    解释:

    text/css 和 text/javascript 是 type 的默认值。

    [建议] 展现定义放置于外部 CSS 中,行为定义放置于外部 JavaScript 中。

    解释:

    结构-样式-行为的代码分离,对于提高代码的可阅读性和维护性都有好处。

    [建议] 在 head 中引入页面需要的所有 CSS 资源。

    解释:

    在页面渲染的过程中,新的CSS可能导致元素的样式重新计算和绘制,页面闪烁。

    [建议] JavaScript 应当放在页面末尾,或采用异步加载。

    解释:

    将 script 放在页面中间将阻断页面的渲染。出于性能方面的考虑,如非必要,请遵守此条建议。

    示例:

    <body>
        <!-- a lot of elements -->
        <script src="init-behavior.js"></script>
    </body>

    [建议] 移动环境或只针对现代浏览器设计的 Web 应用,如果引用外部资源的 URL 协议部分与页面相同,建议省略协议前缀。

    解释:

    使用 protocol-relative URL 引入 CSS,在 IE7/8 下,会发两次请求。是否使用 protocol-relative URL 应充分考虑页面针对的环境。

    示例:

    <script src="//s1.bdstatic.com/cache/static/jquery-1.10.2.min_f2fb5194.js"></script>

    4 head

    4.1 title

    [强制] 页面必须包含 title 标签声明标题。

    [强制] title 必须作为 head 的直接子元素,并紧随 charset 声明之后。

    解释:

    title 中如果包含 ASCII 之外的字符,浏览器需要知道字符编码类型才能进行解码,否则可能导致乱码。

    示例:

    <head>
        <meta charset="UTF-8">
        <title>页面标题</title>
    </head>

    4.2 favicon

    [强制] 保证 favicon 可访问。

    解释:

    在未指定 favicon 时,大多数浏览器会请求 Web Server 根目录下的 favicon.ico 。为了保证 favicon 可访问,避免 404,必须遵循以下两种方法之一:

    1. 在 Web Server 根目录放置 favicon.ico 文件。
    2. 使用 link 指定 favicon。

    示例:

    <link rel="shortcut icon" href="path/to/favicon.ico">

    4.3 viewport

    [建议] 若页面欲对移动设备友好,需指定页面的 viewport

    解释:

    viewport meta tag 可以设置可视区域的宽度和初始缩放大小,避免在移动设备上出现页面展示不正常。

    比如,在页面宽度小于 980px 时,若需 iOS 设备友好,应当设置 viewport 的 width 值来适应你的页面宽度。同时因为不同移动设备分辨率不同,在设置时,应当使用 device-width 和 device-height 变量。

    另外,为了使 viewport 正常工作,在页面内容样式布局设计上也要做相应调整,如避免绝对定位等。关于 viewport 的更多介绍,可以参见 Safari Web Content Guide的介绍

    5 图片

    [强制] 禁止 img 的 src 取值为空。延迟加载的图片也要增加默认的 src

    解释:

    src 取值为空,会导致部分浏览器重新加载一次当前页面,参考:https://developer.yahoo.com/performance/rules.html#emptysrc

    [建议] 避免为 img 添加不必要的 title 属性。

    解释:

    多余的 title 影响看图体验,并且增加了页面尺寸。

    [建议] 为重要图片添加 alt 属性。

    解释:

    可以提高图片加载失败时的用户体验。

    [建议] 添加 width 和 height 属性,以避免页面抖动。

    [建议] 有下载需求的图片采用 img 标签实现,无下载需求的图片采用 CSS 背景图实现。

    解释:

    1. 产品 logo、用户头像、用户产生的图片等有潜在下载需求的图片,以 img 形式实现,能方便用户下载。
    2. 无下载需求的图片,比如:icon、背景、代码使用的图片等,尽可能采用 CSS 背景图实现。

    6 表单

    6.1 控件标题

    [强制] 有文本标题的控件必须使用 label 标签将其与其标题相关联。

    解释:

    有两种方式:

    1. 将控件置于 label 内。
    2. label 的 for 属性指向控件的 id

    推荐使用第一种,减少不必要的 id。如果 DOM 结构不允许直接嵌套,则应使用第二种。

    示例:

    <label><input type="checkbox" name="confirm" value="on"> 我已确认上述条款</label>
    
    <label for="username">用户名:</label> <input type="textbox" name="username" id="username">

    6.2 按钮

    [强制] 使用 button 元素时必须指明 type 属性值。

    解释:

    button 元素的默认 type 为 submit,如果被置于 form 元素中,点击后将导致表单提交。为显示区分其作用方便理解,必须给出 type 属性。

    示例:

    <button type="submit">提交</button>
    <button type="button">取消</button>

    [建议] 尽量不要使用按钮类元素的 name 属性。

    解释:

    由于浏览器兼容性问题,使用按钮的 name 属性会带来许多难以发现的问题。具体情况可参考此文

    6.3 可访问性 (A11Y)

    [建议] 负责主要功能的按钮在 DOM 中的顺序应靠前。

    解释:

    负责主要功能的按钮应相对靠前,以提高可访问性。如果在 CSS 中指定了 float: right 则可能导致视觉上主按钮在前,而 DOM 中主按钮靠后的情况。

    示例:

    <!-- good -->
    <style>
    .buttons .button-group {
        float: right;
    }
    </style>
    
    <div class="buttons">
        <div class="button-group">
            <button type="submit">提交</button>
            <button type="button">取消</button>
        </div>
    </div>
    
    <!-- bad -->
    <style>
    .buttons button {
        float: right;
    }
    </style>
    
    <div class="buttons">
        <button type="button">取消</button>
        <button type="submit">提交</button>
    </div>

    [建议] 当使用 JavaScript 进行表单提交时,如果条件允许,应使原生提交功能正常工作。

    解释:

    当浏览器 JS 运行错误或关闭 JS 时,提交功能将无法工作。如果正确指定了 form 元素的 action 属性和表单控件的 name属性时,提交仍可继续进行。

    示例:

    <form action="/login" method="post">
        <p><input name="username" type="text" placeholder="用户名"></p>
        <p><input name="password" type="password" placeholder="密码"></p>
    </form>

    [建议] 在针对移动设备开发的页面时,根据内容类型指定输入框的 type 属性。

    解释:

    根据内容类型指定输入框类型,能获得能友好的输入体验。

    示例:

    <input type="date">

    7 多媒体

    [建议] 当在现代浏览器中使用 audio 以及 video 标签来播放音频、视频时,应当注意格式。

    解释:

    音频应尽可能覆盖到如下格式:

    • MP3
    • WAV
    • Ogg

    视频应尽可能覆盖到如下格式:

    • MP4
    • WebM
    • Ogg

    [建议] 在支持 HTML5 的浏览器中优先使用 audio 和 video 标签来定义音视频元素。

    [建议] 使用退化到插件的方式来对多浏览器进行支持。

    示例:

    <audio controls>
        <source src="audio.mp3" type="audio/mpeg">
        <source src="audio.ogg" type="audio/ogg">
        <object width="100" height="50" data="audio.mp3">
            <embed width="100" height="50" src="audio.swf">
        </object>
    </audio>
    
    <video width="100" height="50" controls>
        <source src="video.mp4" type="video/mp4">
        <source src="video.ogg" type="video/ogg">
        <object width="100" height="50" data="video.mp4">
            <embed width="100" height="50" src="video.swf">
        </object>
    </video>

    [建议] 只在必要的时候开启音视频的自动播放。

    [建议] 在 object 标签内部提供指示浏览器不支持该标签的说明。

    示例:

    <object width="100" height="50" data="something.swf">DO NOT SUPPORT THIS TAG</object>

    8 模板中的 HTML

    [建议] 模板代码的缩进优先保证 HTML 代码的缩进规则。

    示例:

    <!-- good -->
    {if $display == true}
    <div>
        <ul>
        {foreach $item_list as $item}
            <li>{$item.name}<li>
        {/foreach}
        </ul>
    </div>
    {/if}
    
    <!-- bad -->
    {if $display == true}
        <div>
            <ul>
        {foreach $item_list as $item}
            <li>{$item.name}<li>
        {/foreach}
            </ul>
        </div>
    {/if}

    [建议] 模板代码应以保证 HTML 单个标签语法的正确性为基本原则。

    示例:

    <!-- good -->
    <li class="{if $item.type_id == $current_type}focus{/if}">{ $item.type_name }</li>
    
    <!-- bad -->
    <li {if $item.type_id == $current_type} class="focus"{/if}>{ $item.type_name }</li>

    [建议] 在循环处理模板数据构造表格时,若要求每行输出固定的个数,建议先将数据分组,之后再循环输出。

    示例:

    <!-- good -->
    <table>
        {foreach $item_list as $item_group}
        <tr>
            {foreach $item_group as $item}
            <td>{ $item.name }</td>
            {/foreach}
        <tr>
        {/foreach}
    </table>
    
    <!-- bad -->
    <table>
    <tr>
        {foreach $item_list as $item}
        <td>{ $item.name }</td>
            {if $item@iteration is div by 5}
        </tr>
        <tr>
            {/if}
        {/foreach}
    </tr>
    </table>

    入坑方式:   欢迎加入~!气氛热情,欢乐多,妹子多!

    enlightenedweb前端 聚集地,汇聚了全国顶尖的web前端热爱者,最新技术,最炫潮流,最靠谱的话题:
      做好现在!技术只是为了改变生活!JS前端实用开发QQ群 :
    147250970
    Web前端HTML5/JS交流群

    enlightened 扫描屏幕下方的二维码,可以关注 我的前端公众号 。听说妹子挺多的,及时更新一些前端解惑和段子

    展开全文
  • 开始使用的flexbox新版语法,都做了几个页面了,在微信上测试就错位了,原来是微信QQ使用使用的腾讯自己的X5内核的浏览器。该浏览器不支持flex-wrap:wrap宽度不够自动换行的语法。 后来通过浮动的方式来调整自动换行...

    最近做移动端页面开发,在微信和qq上测试遇到了许多意想不到的问题。

    问题

    • 开始使用的flexbox新版语法,都做了几个页面了,在微信上测试就错位了,原来是微信QQ使用使用的腾讯自己的X5内核的浏览器。该浏览器不支持flex-wrap:wrap宽度不够自动换行的语法。
    • 后来通过浮动的方式来调整自动换行的问题,结果又遇到有朋友的手机是ios6的系统,打开页面一片惨淡。后来查阅到,ios8以下的系统不支持flexBox新版语法,只能用旧版语法。没办法,只能写兼容性语法了。
    • 但是发现写兼容性语法很恼火,又要改之前的代码。就另谋出路,采用了bootstrap的栅格化系统,开发起来挺顺畅的。
    • X5内核是不支持border:0.5的。

    总结

    • 现在做移动端页面开发并且要求照顾到大多数的移动设备的话,不要使用flexbox,要等主流浏览器都支持了再说。目前最好使用的就是栅格化页面。
    展开全文
  • 开始使用的flexbox新版语法,都做了几个页面了,在微信上测试就错位了,原来是微信QQ使用使用的腾讯自己的X5内核的浏览器。该浏览器不支持flex-wrap:wrap宽度不够自动换行的语法。后来通过浮动的方式来调整自动换行...

    问题

    • 开始使用的flexbox新版语法,都做了几个页面了,在微信上测试就错位了,原来是微信QQ使用使用的腾讯自己的X5内核的浏览器。该浏览器不支持flex-wrap:wrap宽度不够自动换行的语法。
    • 后来通过浮动的方式来调整自动换行的问题,结果又遇到有朋友的手机是ios6的系统,打开页面一片惨淡。后来查阅到,ios8以下的系统不支持flexBox新版语法,只能用旧版语法。没办法,只能写兼容性语法了。
    • 但是发现写兼容性语法很恼火,又要改之前的代码。就另谋出路,采用了bootstrap的栅格化系统,开发起来挺顺畅的。
    • X5内核是不支持border:0.5的。

    总结

    • 现在做移动端页面开发并且要求照顾到大多数的移动设备的话,不要使用flexbox,要等主流浏览器都支持了再说。目前最好使用的就是栅格化页面。
    展开全文
  • 1、桌面图标的显示样式、自动换行、拖动及页面图标选择器 2、修正了部分BUG 3、加入了许多WebQQ的元素 4、写了一个JavaScript版的浏览器,不过是个半成品 5、加入了豆瓣FM、QQ地图、QQ音乐等应用
  • CSS--文本溢出的处理

    千次阅读 2018-12-24 11:51:13
    1.单行文本溢出 单行文本溢出一般没有代码上的兼容问题, //需要对元素盒子设置一个宽度以兼容部分浏览器 overflow: hidden;...适用于webkit浏览器(如chrome、QQ极速、搜狗等)和移动端。 displa...
  • HTML-复习笔记

    2021-03-24 11:56:43
    5、C/S:客户端/服务器,QQ,地下城以下,百度云盘,需要安装。 6、B/S:浏览器/服务器,无需安装,只要浏览器就可以,交互性强。 7、a标签 8、img标签 title 光标放在图片上显示, alt图片加载失败显示。 9、 ...
  • *修正了“备注”编辑框不支持换行的问题 *修正了一些小BUG 密码管家 V1.7 (2008.12.6) =========================== *修正了对话框皮肤的BUG,不再有界面显示错误的问题 *增加了QQ自动登录功能 *在帐号分类中添加了...
  • F5在线HTML编辑器 v4.0

    2019-11-09 03:26:06
    4、提供插入标准换行,及水平线功能;5、支持全选、剪贴、复制、常规粘贴,以及纯文本粘贴;6、支持删除文本格式、清理HTML代码等快速文字处理功能;7、提供完美的表格插入,增减行、列等功能;8、支持文字、文字...
  • 4、提供插入标准换行 ,及水**线功能; 5、支持全选、剪贴、复制、常规粘贴,以及纯文本粘贴; 6、支持删除文本格式、清理HTML代码等快速文字处理功能; 7、提供完美的表格插入,增减行、列等功能; 8、支持文字、...
  • 4、提供插入标准换行 ,及水平线功能; 5、支持全选、剪贴、复制、常规粘贴,以及纯文本粘贴; 6、支持删除文本格式、清理HTML代码等快速文字处理功能; 7、提供完美的表格插入,增减行、列等功能; 8、支持...
  • 11前端开发基础视频-什么是浏览器什么是服务器端.avi 12前端开发基础视频-浏览器与服务器端补充.avi 13前端开发基础视频-HTML协议发展的历程(可以略过,非重点,了解即可).avi 14前端开发基础视频-常见前端的...
  • (3)、浏览器前台需要用户开启Cookie功能(浏览需要IE6、火狐 3.x 以上) 二、PHP云人才系统产品特点: (1)、PHP OOP思想编写方便维护和升级有很好的安全性 (2)、采用PHP模板分离可以方便修改页面和二次开发升级 (3...
  • QQ 插件3. 首页标题截短修正4. 中文搜索完美解决 3.2 版本(可以在改进的二元分割算法(效率高、负载小)和直接搜索 post 表(更准确、数据库空间占用小)两种方式选择)5. 金钱银行插件 2.06. 隐藏帖插件 3.07. ...
  • 技 术 QQ:861118936 联系邮箱:admin@fangka.net ========================================== 程序定位 本程序定位于学校或企业单位进行非严格要求的随机抽题考试,系统采用考试项目数据库独立方式,虽采用了...
  • html入门到放弃笔记

    2018-05-15 15:06:12
    5、换行元素 6、分割线元素 作用:在页面中表现为一条直线 语法: 属性: 1、size 尺寸,以 px 为单位的数值 2、width 宽度,以 px 或 % 为单位的数值 3、align 水平对其方式 4、color 颜色 ...
  • 物流公司网站源码

    2013-03-24 09:49:44
    物流公司 网站源码 ╭═══════════════╮ ║ 〖中文信息〗 ║ ╭═══════┤ 脚本之家 ├═══...相关软件查看,避免记事本不识别换行导致的查看困难. =====================================
  • xheditor-1.1.14

    2012-08-07 09:25:30
    参数:可定义多个JSON对象数组,示例如下:{qq:{name:'QQ',count:55,width:25,height:25,line:11},msn:{name:'MSN',count:40,width:22,height:22,line:8}} name:表情分组名 count:表情数量 list:表情列表,例...
  • 9.5 表格的宽度固定后内容自动换行 9.6 表格的排序 9.7 表格的斜线 9.8 table中的文字滚动 9.9 JavaScript遍历table的行和列 9.10 表格按回车自动生成新行 9.11 单击单元格背景变色 9.12 单击表格某行后其他行隐藏 ...
  • 9.5 表格的宽度固定后内容自动换行 9.6 表格的排序 9.7 表格的斜线 9.8 table中的文字滚动 9.9 JavaScript遍历table的行和列 9.10 表格按回车自动生成新行 9.11 单击单元格背景变色 9.12 单击表格某行后其他行隐藏 ...
  • 实例315 按设定值使标签自动换行 实例316 使用标签控件模拟按钮动作 实例317 限制文本框输入字符数 实例318 限制文本框只能输入数字 实例319 自动删除文本中的非法字符 实例320 格式化文本为指定格式 实例321...
  • 实例315 按设定值使标签自动换行 实例316 使用标签控件模拟按钮动作 实例317 限制文本框输入字符数 实例318 限制文本框只能输入数字 实例319 自动删除文本中的非法字符 实例320 格式化文本为指定格式 实例321...
  • 实例021 类QQ导航菜单 1.6 界面窗体应用实例 实例022 背景为渐变色的程序界面 实例023 椭圆形的程序界面 实例024 自绘窗体界面 实例025 类似Windows XP的程序界面 实例026 窗体融合技术 实例027 限制对话框...
  • 实例021 类QQ导航菜单 1.6 界面窗体应用实例 实例022 背景为渐变色的程序界面 实例023 椭圆形的程序界面 实例024 自绘窗体界面 实例025 类似Windows XP的程序界面 实例026 窗体融合技术 实例027 限制对话框...
  • 实例021 类QQ导航菜单 1.6 界面窗体应用实例 实例022 背景为渐变色的程序界面 实例023 椭圆形的程序界面 实例024 自绘窗体界面 实例025 类似Windows XP的程序界面 实例026 窗体融合技术 实例027 限制对话框...
  • 实例021 类QQ导航菜单 1.6 界面窗体应用实例 实例022 背景为渐变色的程序界面 实例023 椭圆形的程序界面 实例024 自绘窗体界面 实例025 类似Windows XP的程序界面 实例026 窗体融合技术 实例027 限制对话框...
  • 实例021 类QQ导航菜单 1.6 界面窗体应用实例 实例022 背景为渐变色的程序界面 实例023 椭圆形的程序界面 实例024 自绘窗体界面 实例025 类似Windows XP的程序界面 实例026 窗体融合技术 实例027 限制对话框...
  • 实例021 类QQ导航菜单 1.6 界面窗体应用实例 实例022 背景为渐变色的程序界面 实例023 椭圆形的程序界面 实例024 自绘窗体界面 实例025 类似Windows XP的程序界面 实例026 窗体融合技术 实例027 限制对话框...

空空如也

空空如也

1 2 3
收藏数 48
精华内容 19
关键字:

qq浏览器换行