整合營銷服務商

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

          免費咨詢熱線:

          性能測試YSLOW前端調優23大規則(八)-JavaScript和CSS置于外部

          謂的將JavaScript和CSS置于外部,就是我們說的外置JavaScript和CSS。關于JavaScript和CSS在前端頁面中的使用通常有兩種方式:一種是內聯方式;另外一種是外置方式。

          內聯方式是指將JavaScript和CSS直接嵌入到前端頁面,如以下代碼:

          [head]

          [script type="text/javascript"]

          function IsEven()

          {

          var number = document.getElementById("TextBox1").value;

          if (number % 2 == 0)

          {

          alert(number + " is even number");

          }

          else

          {

          alert(number + " is odd number");

          }

          }

          [/script]

          [/head]

          外置方式是指將JavaScript或CSS寫在一個單獨的文件中,后綴名為“.js”或“.css”格式,然后在HTML頁面中調用這個單獨的文件,如以下代碼:

          [head]

          [script type="text/javascript" src="ExternalJavaScript.js"][/script]

          [/head]

          內聯JavaScript和CSS的優點如下:

          1) 有效減少 HTTP 請求次數,提升前端頁面性能,緩解服務器壓力。

          2) 瀏覽器加載完CSS才能渲染頁面,因此可以防止CSS文件無法讀取而造成頁面裸奔的現象。

          內聯JavaScript和CSS的缺點如下:

          1) 可維護性差,每天如果有需要修改內容,必須對很多頁面進行修改。

          2) 內聯JavaScript和CSS在每次頁面加載的都必須重新加載。

          3) 協同開發的能力差,不方便多名開者同步工作。

          外聯JavaScript和CSS的優點如下:

          1) 如果JavaScript和CSS被多個頁面調用時,這樣修改更方便,只要修改一個文件就可以。

          2) 分離HTML、CSS和Javascript可以更容易操縱它們,方便協同工作。

          3) 外置Javascript文件可以被瀏覽器緩存。

          外聯JavaScript和CSS的缺點如下:

          1) 外置的方式增加了HTTP的請求數。

          2) 瀏覽器要加載完CSS才能渲染頁面,因此影響頁面的性能。

          在現實世界中使用外部文件通常會產生更快的頁面,因為瀏覽器會緩存JavaScript和CSS文件。每次請求HTML文檔時,都會下載HTML文檔中內聯的JavaScript和CSS。這減少了所需的HTTP請求數量,但增加了HTML文檔的大小。另一方面,如果JavaScript和CSS位于瀏覽器緩存的外部文件中,則HTML文檔的大小會減少,而不會增加HTTP請求的數量。

          關鍵因素是外部JavaScript和CSS組件相對于所請求的HTML文檔數量的緩存頻率。這個因素盡管難以量化,但可以使用各種指標進行衡量。如果您的網站上的用戶每個會話有多個頁面瀏覽量,并且許多網頁重復使用相同的腳本和樣式表,則緩存的外部文件可能帶來更大的潛在收益。

          在比較內聯和外置文件時,知道用戶緩存外部組件的可能性的可能性很重要,通常用戶在第一次訪問頁面時是空緩存,之后的多次后續頁面查看都是具有完整緩存的。如果在訪問系統時,具有完整緩存的頁面占所有查看數量的比例越多,那說明外置文件的收益越高也就越有利,當然如果具有完整緩存的頁面占所有查看數量的比例很低,那么內聯文件的方式更有利。

          如果網站中有很多頁面使用相同的JavaScript和CSS,那么使用外部文件可以更好的提高這些組件的重用率,在這種情況下使用外部文件更有優勢,因為當用戶在頁面導航時JavaScript和CSS組件已經位于瀏覽器的緩存中。當然反過來也很容易理解了,如果沒有任何兩個頁面共享相同的JavaScript和CSS,重用率就會很低,當然很少有網站會出現這兩種極端的情況了。

          如果主頁服務器知道一個組件是否在瀏覽器的緩存中,那么就可以在內聯或使用外部文件之間做出最佳選擇,當然服務器不能查看瀏覽器緩存中有那些內容,但可以使用Cookies做指示器,如果Cookies不存在,就使用內聯JavaScript和CSS,如果Cookies出現了,則可以使用外部組件位于瀏覽器的緩存中,這就是我們通常說的“動態內聯”。

          基于以上原因通常我們建議將JavaScript和CSS置于外部。

          Vue 應用中,需要使用 el-dialog 彈出一個 iframe 頁面,該頁面來源于其他項目,這就要解決 Vue 父頁面和 iframe 子頁面的兩個通信問題:

          1. Vue 父頁面向 iframe 子頁面傳遞初始化數據
          2. 子頁面的關閉按鈕,需要通知父頁面關閉 el-dialog

          本文將整理 Vue 中嵌入 iframe 并進行雙向通信的完整過程。

          子頁面直接調用父頁面方法的跨域問題

          理論上,如果 iframe 的 src 跟父頁面同源,是可以直接用 window.parent.func 方法調用父類的 close 方法,完成 el-dialog 彈框關閉的。

          但是,如果不同源,就會報錯:

          DOMException: Blocked a frame with origin "http://localhost:8085" 
          from accessing a cross-origin frame.

          網上搜索到的解決辦法是,使用 iframe 的 contentWindow.postMessage 方法傳遞數據給子頁面。但是有一個問題,什么時候調用能得到真正的 iframe 對象呢?

          父組件傳遞數據的時機

          經過反復測試,筆者發現:如果直接在 Vue 父組件的 created 方法中向 iframe 傳遞數據,此時 iframe 因為并沒有被訪問,導致無法傳數據,無論是通過 id 還是 $refs 都不能獲取到這個 iframe 對象。

          看這段網上搜到的通用方法:

          <el-dialog :visible="showIFrame" :close-on-click-modal="false"
                         @close="closeSelf" title="彈框配置" >
                <iframe id="myFrame"  ref="myframe" src="http://localhost:8085/myIFrame.html" 
                frameborder="0" scrolling="auto" marginheight="0" marginwidth="0" 
                width="100%" height="726px;">
                </iframe>
              </el-dialog>

          此時,如果在 created 方法中傳遞數據:

          created() {
              // 監聽子組件的關閉事件消息
              window.addEventListener('message', () => {
                this.closeSelf();
              }, false);
          
              // 向子組件傳遞初始化數據
              this.$refs.myframe.contentWindow.postMessage(data, '*'); // 取到的是 undefined
              const iframe = document.getElementById('myframe');  // 為 null
              iframe.contentWindow.postMessage(data,"*");
            },

          代碼運行會報兩種錯誤。

          錯誤一,$refs 中沒有該組件:

          錯誤一

          錯誤二,id 為 myframe 的元素為 null:

          錯誤二

          解決辦法:在 iframe 的 load 事件中向子頁面傳遞數據,上面兩種用法就不會報錯了。

          完整流程

          父組件的 created 中監聽子組件消息,調用關閉邏輯;同時,為 iframe 提供一個 @load="loaded" 事件,在該事件中調用 postMessage 向子組件發送初始化數據。

          首先,彈框 Vue 組件 PopupIframe.vue 代碼如下:

          <template>
            <div id="app">
              <el-dialog :visible="showIFrame" :close-on-click-modal="false"
                         @close="closeSelf" title="Ifram配置">
                <iframe v-show="src!==''"  
                id="myframe" 
                @load="loaded" 
                ref="myframe" 
                :src="src" frameborder="0" scrolling="auto" marginheight="0" marginwidth="0" width="100%" height="726px;"></iframe>
              </el-dialog>
            </div>
          </template>
          <script>
          export default {
            name: 'PopupIframe',
            props: ['showIFrame'],
            data() {
              return {
                src: '',
                data: {
                },
              };
            },
            created() {
              // 設置 src
              this.src = 'http://localhost:8087/myIfram.html";
              // 監聽子組件的關閉事件
              window.addEventListener('message', () => {
                this.closeSelf();
              }, false);
            },
            methods: {
              loaded() {
                // 只有在 iframe 加載時傳遞數據給子組件,$refs 才是非空的
                this.$refs.myframe.contentWindow.postMessage({
                  type: 'myData',
                  data: this.data,
                }, '*');
              },
              closeSelf() { // 關閉當前彈框
                this.$emit('closeIframe');
              },
            },
          };
          </script>

          第二步,iframe 子頁面添加監聽數據的方法:

          window.addEventListener('message', (e) => {
                   console.log(e.data);
                   if (e.data.type === 'myData') {
                      // TODO 使用父組件傳遞的初始化數據
                    }
          });

          第三步,iframe 的頁面的關閉按鈕向父組件發送消息,通知關閉:

          window.parent.postMessage('close', '*');

          PopupIframe.vue 被其他組件引用就可以了。

          postMessage 數據類型

          測試發現,this.$refs.myframe.contentWindow.postMessage 向 iframe 子組件發送數據后,子組件收到的數據除了第一步定義的數據外,還有其他數據,它的監聽方法里面會執行兩次:

          postMessage 的內容

          這說明,框架也向子組件發送了一些數據,類型為打包的告警數據。

          因此,父組件傳遞數據時,也可以按照這個格式添加一個 type 標識我們的數據,前面第二步操作中,子組件使用時再根據它處理自己需要的數據。

          總結:本文的核心知識點是 iframe 的 load 事件,要想順利傳遞數據給 iframe ,必須在這里調用才能得到 iframe 對象。

          是展示廣告或為自己的內容添加促銷塊的完美方式。它還為您的布局提供了一個有趣的視覺突破,從重復的網格中脫穎而出。

          為了更好地理解我們將要構建的內容,有一個隨附的演示。但是,由于此演示使用一些PHP代碼,因此需要服務器才能運行。

          可以從此 GitHub 存儲庫下載項目文件(https://github.com/tutsplus/How-to-Embed-Random-Content-Inside-a-Grid-Layout)。

          通過服務器運行演示,請注意兩件事:

          • 嵌入式橫幅
          • 重新加載頁面時,橫幅圖像會發生變化。

          了解布局

          在前面的教程中,我們使用自己的標記重新創建了一個這樣的教程列表。

          標記

          我們使用簡單的HTML來構建結構。自動化并將數據內容存儲在 PHP 數組中。在這里,我們將使用 PHP,但無論語言或 CMS/框架如何,邏輯都將保持不變。我們應該遍歷源代碼并檢索帖子。

          我們的數據內容格式如下所示:

          $articles      = array(
            array(
              'title'      => 'Quick Tip: Create a Very Simple Parallax Effect With CSS & JavaScript',
              'image'      => 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/162656/parallax-pre.jpg',
              'link'       => 'https://webdesign.tutsplus.com/tutorials/quick-tip-how-to-build-a-dead-simple-parallax-effect-with-css-javascript--cms-33061',
              'categories' => array(
                'CSS',
                'JavaScript',
              ),
            ),
            array(
              'title'      => 'How to Build a Static Portfolio Page With CSS & JavaScript',
              'image'      => 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/162656/chart-pre.png',
              'link'       => 'https://webdesign.tutsplus.com/tutorials/how-to-build-a-portfolio-page-with-css-javascript--cms-32933',
              'categories' => array(
                'CSS',
                'JavaScript',
              ),
            ),
              
            // more articles here 
          );

          這是我們的循環邏輯:

          <?php if ( ! empty( $articles ) ) : ?>
            <div class="container">
              <ol class="posts">
                <?php foreach ( $articles as $key => $article ) : ?>
                  <li class="post">
                    <article>
                      <figure>
                        <a href="<?php echo $article['link']; ?>" target="_blank">
                          <img width="300" height="208" src="<?php echo $article['image']; ?>" alt="<?php echo $article['title']; ?>">
                        </a>
                        <figcaption>
                          <ol class="post-categories">
                            <?php foreach ( $article['categories'] as $cat ) : ?>
                              <li>
                                <a href="">
                                  <?php echo $cat; ?>
                                </a>
                              </li>
                            <?php endforeach; ?>
                          </ol>
                          <h2 class="post-title">
                            <a href="<?php echo $article['link']; ?>" target="_blank">
                              <?php echo $article['title']; ?>
                            </a>
                          </h2>
                        </figcaption>
                      </figure>
                    </article>
                  </li>
                <?php endforeach; ?>
              </ol>
            </div>
          <?php endif; ?>

          如前所述,根據你將要使用的語言或CMS,情況會發生變化。例如,WordPress有一個用于所有主要查詢的內置循環

          <!-- Start the Loop. -->
          <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
           
            <!-- Add post info using WP built-in functions -->
          <?php endwhile; else : ?>
            <!-- The very first "if" tested to see if there were any Posts to -->
            <!-- display. This "else" part tells what do if there weren't any. -->
            <p><?php esc_html_e( 'Sorry, no posts matched your criteria.' ); ?></p>
            <!-- REALLY stop The Loop. -->
          <?php endif; ?>

          風格

          除了標記之外,我們還將保留上一教程中的大多數樣式。我們只會進行一些更改以使布局響應。

          以下是所有樣式:

          :root {
            --black: #3a3a3a;  --white: #fff;  --green: #49b293;
          }
          * {
            margin: 0;  padding: 0;
          }
          img {
            display: block;  max-width: 100%;  height: auto;
          }
          ol {
            list-style: none;
          }
          a {
            text-decoration: none;  color: inherit;
          }
          body {
            margin: 50px 0;  color: var(--black); 
            font: 1rem/1.3 sans-serif;
          }
          .container {
            max-width: 1200px;  padding: 0 15px; 
            margin: 0 auto;
          }
          h1 {
            text-align: center;  margin-bottom: 2rem;
          }
          h1 a {
            text-decoration: underline;
          }
          .posts {
            display: grid;  grid-gap: 1.5rem;
          }
          .posts .post {
            width: 300px;  margin: 0 auto;  
            border: 1px solid rgba(0, 0, 0, 0.1);
          }
          .posts > li {
            background: #fafafa;
          }
          .posts .post-title {
            font-size: 1.3rem;
          }
          .posts .post-title:hover {
            text-decoration: underline;
          }
          .posts figcaption {
            padding: 1rem;
          }
          .posts .post-categories {
            margin-bottom: 0.75rem;  font-size: 0.75rem;
          }
          .posts .post-categories * {
            display: inline-block;
          }
          .posts .post-categories li {
            margin-bottom: 0.2rem;
          }
          .posts .post-categories a {
            padding: 0.2rem 0.5rem;  border-radius: 1rem; 
            border: 1px solid;  line-height: normal;  transition: all 0.1s;
          }
          .posts .post-categories a:hover {
            background: var(--green);  color: var(--white);
          }
          @media (min-width: 500px) {
            .posts {
              grid-template-columns: repeat(2, 1fr);
            }
            .posts .post {
              width: auto;
            }
          }
          @media (min-width: 600px) {
            .posts {
              grid-template-columns: repeat(3, 1fr);
            }
          }
          @media (min-width: 900px) {
            .posts {
              grid-template-columns: repeat(4, 1fr);
            }
          }

          現在讓我們假設我們要在網格內放置橫幅。在這種情況下,我們只會使用圖片橫幅,但在您的情況下,您可以插入來自不同來源的廣告、輪播、視頻或您喜歡的任何其他內容。

          我們的橫幅必須滿足以下要求:

          • 它們應該在每五列之后出現。在我們的例子中,有 12 個帖子,所以我們的網格將包含兩個橫幅。當然,在您的情況下,您可以擁有更多。
          • 在每個頁面加載時,它們應該隨機出現,這意味著某些橫幅不會有任何固定的位置。
          • 此外,嵌入的橫幅應該是唯一的,這意味著單個橫幅不會在同一頁面中出現兩次。

          下面是我們想要生成的布局示例:

          如前所述,橫幅將隨機出現,因此在另一個頁面加載時,我們可能會看到不同的橫幅,如下所示:

          為了實現此行為,我們將使用不同的 PHP 數組函數(、array_diffarray_push)。array_keysarray_rand

          讓我們記下我們將遵循的步驟:

          1. 將所有橫幅(來自 Unsplash)存儲在數組內,并從該數組中獲取密鑰。$images
          2. 初始化數組,我們將在其中添加要添加到網格的每個橫幅的鍵。默認情況下,它將為空。$exclude_images_keys
          3. 在循環中,我們將檢查當前元素的索引是否不為 0 并且能被 5 整除。
          4. 如果發生這種情況,我們將比較 和 數組。我們將返回它們的唯一值(如果有),并將它們存儲在數組中。$images_keys$exclude_images_keys$in_items
          5. 從數組中獲取一個隨機密鑰。$in_items
          6. 將此鍵添加到數組中,以從將來的選擇中排除關聯的橫幅。$exclude_images_keys
          7. 使用此鍵選擇橫幅并將其放置在網格中。

          以下是負責此功能的 PHP 代碼:

          <?php 
          // 1 
          $images              = array(
            'banner1.jpg',
            'banner2.jpg',
            'banner3.jpg',
            'banner4.jpg',
            'banner5.jpg',
            'banner6.jpg',
          );
          $images_keys         = array_keys( $images );
          $exclude_images_keys = array();
          foreach ( $articles as $key => $article ) :
            // 3 
            if ( 0 !== $key && 0 === $key % 5 ) :
              // 4 
              $in_items         = array_diff( $images_keys, $exclude_images_keys );
              // 5 
              $random_image_key = array_rand( $in_items );
              // 6 
              array_push( $exclude_images_keys, $random_image_key );
              // 7 
              $random_image = $images[ $random_image_key ];
              ?>
              <li class="banner">
                <img width="800" height="533" src="img/<?php echo $random_image; ?>" alt="banner">
              </li>
          	<?php
            endif;
            ...
           endforeach;

          以及我們橫幅的附加 CSS:

          .posts .banner img {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
            
          @media (min-width: 900px) {
            .posts .banner {
              grid-column: span 2;
            }
          }

          結論

          就是這樣,伙計們!我希望你和我一樣喜歡這個小練習,它給了你一些關于如何在網格布局中嵌入廣告項目的想法。此外,通過以我們在此處介紹的方式使用模運算符 (),您可以創建具有動態模式的多列布局。

          與往常一樣,非常感謝您的閱讀!


          主站蜘蛛池模板: 91精品国产一区| 麻豆aⅴ精品无码一区二区| 亚洲性日韩精品一区二区三区| 韩日午夜在线资源一区二区 | 在线精品国产一区二区三区| 国产精品夜色一区二区三区| 精品人妻一区二区三区毛片| 国产日韩精品视频一区二区三区| 日韩精品一区二区三区视频 | 无码囯产精品一区二区免费 | 一本一道波多野结衣一区| 精品无码综合一区| 无码国产精品一区二区高潮| 久久高清一区二区三区| 国产精品毛片一区二区 | 无码人妻一区二区三区在线视频 | 日韩一区二区三区在线精品| 国产精品视频免费一区二区| 色欲综合一区二区三区| AV天堂午夜精品一区| 一区二区三区四区电影视频在线观看 | 日韩电影在线观看第一区| 曰韩人妻无码一区二区三区综合部| 日本不卡在线一区二区三区视频| 福利一区二区视频| 国产高清视频一区二区| 亚洲中文字幕久久久一区| 日韩精品一区二区亚洲AV观看| 在线观看国产区亚洲一区成人| 无码AV动漫精品一区二区免费| 免费精品一区二区三区在线观看| 国产精品一区二区久久| 中文字幕在线看视频一区二区三区| 国产午夜精品一区二区三区| 一区二区三区在线免费| 国产精品一区在线观看你懂的| 一区二区在线视频观看| 国产福利电影一区二区三区| 亚洲一区精品伊人久久伊人| 久久久久国产一区二区| 成人免费一区二区三区|