整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          CSS 函數那些事(二)你不知道的 attr()

          CSS 函數那些事(二)你不知道的 attr()

          性函數 attr() 用于獲取HTML元素里面的屬性值,并用于樣式中,但目前暫時只能應用于CSS元素中的偽元素。

          例子

          實現一個Tooltip

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>css attr函數</title>
              <style>
                .tooltip {
                  width: 100px;
                  position: relative;
                  margin: 0 auto;
                }
                .tooltip:hover::after {
                  padding: 5px;
                  position: absolute;
          
                  /* 在偽元素中作為字符串中使用 */
                  content: attr(data-tooltip);
                  color: #fff;
                  background-color: #000;
                  border-radius: 10px;
                  top: 25px;
                  left: 0;
                }
          
                /* 箭頭 */
                .tooltip:hover .arrow::after {
                  content: "";
                  position: absolute;
                  bottom: -5px;
                  left: 20%;
                  margin-left: -5px;
                  border-width: 5px;
                  border-style: solid;
                  border-color: transparent transparent black transparent;
                }
          
              </style>
            </head>
            <body>
              <div class="tooltip" data-tooltip="一段提示">
                Hover me
                <span class="arrow"></span>
              </div>
            </body>
          </html>

          語法中的實驗屬性(目前所有瀏覽器都不支持)

          在新的語法中支持各種類型的CSS屬性,具體支持的可查看MDN文檔,舉個例子,假如需要設置一個margin-top,正常是需要去找到類名然后設置,稍微圖省事一點可能會集中書寫css類名,然后全局引入再調用.這種寫法一定程度上能方便一點,但是不夠個性化,假如我要設置成上邊距15px,又得重新加一個類名,還是很麻煩。

          <div class="mt10"></div>
          
          //style
          .mt10{
          	margin-top: 10px;
          }

          但是如果實驗屬性支持的話,可以寫成這樣。

          <div mt="10px"></div>
          
          //style
          
          [mt] {
          	margin-top: attr(mt,0);
          }

          這種寫法就很類似組件開發,不需要指定特定大小的px值,在HTML元素上直接能指定任意大小的PX值,而且基于CSS,沒有JS的參與,會更加輕巧。但是,很遺憾的是目前所有瀏覽器都不支持,估計很長一段時間內也是不支持的,這里做一下了解,提供一種組件開發的思路。幸運的是,在找資料的過程發現張鑫旭大佬已經探索過這種可能性,然后對這種特性做了 Polyfill,查看Polyfill。

          Polyfill attr()實驗屬性原理

          利用CSS自定義屬性傳遞attr的屬性值

                .test-attr {
                  --mbNum: attr(mb px);
                  margin-bottom: var(--mbNum);
                  --mlNum: attr(ml px);
                  margin-left: var(--mlNum);
                }

          然后獲取所有包含attr()函數的自定義的屬性名

              // 獲取頁面中所有的CSS自定義屬性
              var isSameDomain=function (styleSheet) {
                  if (!styleSheet.href) {
                      return true;
                  }
          
                  return styleSheet.href.indexOf(window.location.origin)===0;
              };
          
              var isStyleRule=function (rule) {
                  return rule.type===1;
              };
          
              var arrCSSCustomProps=(function () {
                  return [].slice.call(document.styleSheets).filter(isSameDomain).reduce(function (finalArr, sheet) {
                      return finalArr.concat([].slice.call(sheet.cssRules).filter(isStyleRule).reduce(function (propValArr, rule) {
                          var props=[].slice.call(rule.style).map(function (propName) {
                              return [
                                  propName.trim(),
                                  rule.style.getPropertyValue(propName).trim()
                              ];
                          }).filter(function ([propName]) {
                              return propName.indexOf('--')===0;
                          });
          
                          return [].concat(propValArr, props);
                      }, []));
                  }, []);
              })();

          打印下 arrCSSCustomProps ,得到

          最后一步是遍歷Dom,如果設置了對應的自定義屬性,就將通過attr定義屬性值,轉換成css能夠解析的自定義屬性值 var

              // attr()語法轉換成目前CSS變量可識別的語法
              var funAttrVar2NormalVar=function (objParseAttr, valueAttr) {
                  // attr()語法 attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )
                  // valueVar示意:attr(bgcolor color, deeppink)
                  // valueAttr示意: 'deepskyblue'或者null
          
                  var attrName=objParseAttr.attrName;
                  var typeOrUnit=objParseAttr.typeOrUnit;
          
                  // typeOrUnit值包括:
                  // string | color | url | integer | number | length | angle | time | frequency | cap | ch | em | ex | ic | lh | rlh | rem | vb | vi | vw | vh | vmin | vmax | mm | Q | cm | in | pt | pc | px | deg | grad | rad | turn | ms | s | Hz | kHz | %
          
                  var arrUnits=['ch', 'em', 'ex', 'ic', 'lh', 'rlh', 'rem', 'vb', 'vi', 'vw', 'vh', 'vmin', 'vmax', 'mm', 'cm', 'in', 'pt', 'pc', 'px', 'deg', 'grad', 'rad', 'turn', 'ms', 's', 'Hz', 'kHz', '%'];
          
                  var valueVarNormal=valueAttr;
                  // 如果是string類型
                  switch (typeOrUnit) {
                      case 'string': {
                          valueVarNormal='"' + valueAttr + '"';
                          break;
                      }
                      case 'url': {
                          if (/^url\(/i.test(valueAttr)==false) {
                              valueVarNormal='url(' + valueAttr + ')';
                          }
                          break;
                      }
                  }
          
                  // 數值變單位的處理
                  if (arrUnits.includes(typeOrUnit) && valueAttr.indexOf(typeOrUnit)==-1 && parseFloat(valueAttr)==valueAttr) {
                      valueVarNormal=parseFloat(valueAttr) + typeOrUnit;
                  }
          
                  return valueVarNormal;
              };
          
          		var valueVarNormal=funAttrVar2NormalVar(objParseAttr, strHtmlAttr);
          
                  console.log(valueVarNormal); //100px
                  // 設置
                  node.style.setProperty(cssProp, valueVarNormal);  // margin-bottom : 100px

          objParseAttr就是 attr(mb px)解析后的對象,valueAttr就是 自定義屬性的值,也就是例子中的 100

          效果圖

          最后

          attr()加上做兼容后的實驗功能很強大,非常的靈活,后面我打算整合一些常用的需要這種寫法的屬性,封裝成npm包,方便日常應用的開發。最近在整理CSS函數的相關知識,歡迎大家持續關注。

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
          <html>
           <head>
           <title> New Document </title>
           <meta name="Generator" content="EditPlus">
           <meta name="Author" content="">
           <meta name="Keywords" content="">
           <meta name="Description" content="">
           <script type="text/javascript" src="jquery-1.7.js"></script>
           <style type="text/css">
          	 p:hover{
          	 color:red;
          		 cursor:pointer;
          		 background:blue;
          	 }
          	 .cla{
          	 font-size:30px;
          		 color:red;
          	 }
           </style>
           <script type="text/javascript">
          
          
           //attr(屬性名稱) 獲取指定標簽的指定屬性值
          	 function f1()
          	 {
          		 //獲取iName文本框中的type屬性
          	 alert($("#iName").attr("type"));
          		 //獲取第一個p標簽的class值
          		 alert($("p").first().attr("class"));
          	 }
          
           //attr({屬性:'屬性值',屬性:'屬性值'})
          	function f2()
          	{
          	 //將p標簽中除了class為p1的所有p標簽的class樣式設置為cla
          	 $("p").not(".p1").attr({"class":'cla'});
          	}
          
           //removeAttr(屬性名稱)
           function f3()
          	{
          	 //將用戶名文本框的style屬性移除
          		$("#iName").removeAttr("style");
          	}
           
           </script>
           </head>
          
           <body>
           	<p class="p1">床前明月光</p>
          	<p>疑是地上霜</p>
          	<p>舉頭望明月</p>
          	<p>低頭思故鄉</p>
           用戶名: <input type="text" style="border:2px solid green" id="iName"><br/><br/>
           <input type="button" value="attr(xx)獲取指定屬性值" onclick="f1()">
           <input type="button" value="使用attr設置屬性" onclick="f2()">
           <input type="button" value="removeAttr移除屬性值" onclick="f3()">
           </body>
           
          </html>
          

          模板語法 #插值

          模板語法:

          Vue.js 使用了基于 HTML 的模板語法,允許開發者聲明式地將 DOM 綁定至底層 Vue 實例的數據

          文本插值:

          <p>{{message}}</p>    

          數據綁定最常見的形式就是使用“Mustache”語法 (雙大括號) 的文本插值,如上。

          Mustache 標簽將會被替代為對應數據對象上 message 屬性的值。

          無論何時,綁定的數據對象上 message 屬性發生了改變,插值處的內容都會更新。

              <p v-once>{{message}}</p>

          在Vue中,也可以使用v-once指令,執行一次性的插值,這樣以后便不再變化。

          使用時注意,綁定該指令的DOM其他的插值也會受到影響。

          插入原始HTML:

          <p>Using mustaches: {{ rawHtml }}</p>	

          雙大括號會將數據解釋為普通文本,而非 HTML 代碼。所以上例的運行結果如下:

          Using mustaches: <span style="color: red">This should be red.</span>

          為輸出真正的HTML元素,使用v-html指令,如下;

          <div id="app">	
          	<p>Using v-html directive: <span v-html="rawHtml"></span></p>
          </div>
          <script type="text/javascript">
                  var vm=new Vue({
                      el : "#app",
                      data : {
                          rawHtml : "<span style='color: red'>This should be red.</span>"
                      }
                  });
          </script>	

          PS:站點上動態渲染的任意 HTML 可能會非常危險,因為很容易導致 XSS 攻擊。

          請只對可信內容使用 HTML 插值,絕不要對用戶提供的內容使用插值。

          能使用 v-html 來復合局部模板,因為 Vue 不是基于字符串的模板引擎。

          對于用戶界面 (UI),組件更適合作為可重用和可組合的基本單位。

          Attribute|屬性:

          在 HTML DOM 中,Attr 對象表示 HTML 屬性。

          前面兩種使用的Mustache 語法不能作用在 HTML attribute 上。

          應該使用 v-bind 指令:

          <div id="app">
          	  <div v-bind:id="dynamicId">文字</div>
          </div>
          <script>
          	new Vue({
          	  el: '#app',
          	  data: {
          	    dynamicId: 'myid'
          	  }
          	})
          </script>

          此時,渲染結果為:

          <div id="myid">文字</div>

          使用JavaSCript表達式:

          對于所有的數據綁定,Vue.js 都提供了完全的 JavaScript 表達式支持。

          {{ number + 1 }}

          {{ ok ? 'YES' : 'NO' }}

          {{ message.split('').reverse().join('') }}

          表達式會在所屬 Vue 實例的數據作用域下作為 JavaScript 被解析。

          每個綁定都只能包含單個表達式。

          PS:模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如 Math 和 Date 。

          不應該在模板表達式中試圖訪問用戶定義的全局變量。


          主站蜘蛛池模板: 亚洲香蕉久久一区二区三区四区 | 天天综合色一区二区三区| 亚洲乱码av中文一区二区| 日本强伦姧人妻一区二区| 国产日本一区二区三区| 精品一区二区在线观看| 精品伦精品一区二区三区视频 | 中文字幕日本精品一区二区三区| 无码国产精品久久一区免费| 亚洲视频一区网站| 69福利视频一区二区| 日本免费一区二区三区| 性色AV一区二区三区无码| 亚洲一区综合在线播放| 久久高清一区二区三区| 国产内射在线激情一区| 国产美女精品一区二区三区| 亚洲欧洲∨国产一区二区三区| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 亚洲福利一区二区| 亚洲一区免费视频| 蜜桃无码AV一区二区| 日韩一区二区三区无码影院| 日韩精品无码中文字幕一区二区| 一区二区中文字幕| 亚洲国产av一区二区三区丶| 日韩精品一区二区三区老鸭窝| 竹菊影视欧美日韩一区二区三区四区五区| 国产主播一区二区| 久久伊人精品一区二区三区 | 国产在线精品一区在线观看| 欧洲精品码一区二区三区免费看 | 精品国产一区二区三区久久蜜臀| 色一情一乱一伦一区二区三区| 亚洲午夜精品第一区二区8050| 中文字幕国产一区| 无码人妻久久一区二区三区 | 日韩一区二区三区免费体验| 国产AⅤ精品一区二区三区久久 | 国产无人区一区二区三区| 一区二区三区福利|