簡體   English   中英

渲染和執行<script> on pageload after injecting it from external .js file

[英]Rendering and executing <script> on pageload after injecting it from external .js file

我仍然是 JavaScript 的初學者,正在嘗試使用它來使 Etsy Mini API 響應。 我有兩個<script>需要添加到<div>以便迷你商店出現:

<script type='text/javascript' src='https://www.etsy.com/assets/js/etsy_mini_shop.js'></script>
<script type='text/javascript'>new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',4,3,0,'https://www.etsy.com');</script>

在第二個<script>中,我可以指定縮略圖網格的大小(上例中為 4x3),但該網格沒有響應性,因此如果它加載到屏幕較小的設備上,或者筆記本電腦的瀏覽器窗口調整大小后,4x3 網格可能太大。 我想在外部 .js 文件中使用媒體查詢來更改此縮略圖網格,這就是我遇到問題的地方。

以下是我當前的外部 .js 文件:

var products = document.getElementById("products-card");
var grid5x3 = "<script type='text/javascript'>new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',5,3,0,'https://www.etsy.com');</script>";
var grid4x3 = "<script type='text/javascript'>new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',4,3,0,'https://www.etsy.com');</script>";
var grid3x3 = "<script type='text/javascript'>new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',3,3,0,'https://www.etsy.com');</script>";
var grid2x3 = "<script type='text/javascript'>new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',2,3,0,'https://www.etsy.com');</script>";
var grid1x3 = "<script type='text/javascript'>new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',1,3,0,'https://www.etsy.com');</script>";

(function () {
    function resize() {
        var min_2500 = window.matchMedia('only screen and (min-width: 2500px)').addListener(function () {
            products.innerText = grid5x3;
        });
        var min_1900_max_2499 = window.matchMedia('only screen and (min-width: 1900px) and ' +
        '(max-width: 2499px)').addListener(function () {
            products.innerText = grid4x3;
        });
        var min_1200_max_1899 = window.matchMedia('only screen and (min-width: 1200px) and ' +
        '(max-width: 1899px)').addListener(function () {
            products.innerText = grid3x3;
        });
        var min_900_max_1199 = window.matchMedia('only screen and (min-width: 900px) and ' +
        '(max-width: 1199px)').addListener(function () {
            products.innerText = grid2x3;
        });
        var max_899 = window.matchMedia('only screen and (max-width: 899px)').addListener(function () {
            products.innerText = grid1x3;
        });
    }

    resize();
}());

這是.html:

<head>
  ...
  <script type='text/javascript' src='https://www.etsy.com/assets/js/etsy_mini_shop.js'></script>
</head>
<body>
  ...
  <div class="products-card" id="products-card"></div>
  ...
</body>

問題 1:腳本沒有被執行,而是實際的文本,包括<script>標簽,出現在<div>中。 如何更改我的 Javascript 以使腳本執行並呈現迷你商店?

問題 2:頁面加載時<div>為空,但在調整瀏覽器屏幕大小並達到媒體查詢中指定的截止點之一后,文本會根據媒體查詢正確顯示並更改。 如何使商店在頁面加載時呈現在<div>中,而不僅僅是在調整瀏覽器窗口大小時?

更新 1所以我發現使用 innerText/innerHTML 在注入 html 文件時不允許執行/渲染任何腳本( 基於此處的答案)。 這是我的新 .js 文件:

var products = document.getElementById("products-card");
var grid5x3 = "new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',5,3,0,'https://www.etsy.com');";
var grid4x3 = "new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',4,3,0,'https://www.etsy.com');";
var grid3x3 = "new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',3,3,0,'https://www.etsy.com');";
var grid2x3 = "new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',2,3,0,'https://www.etsy.com');";
var grid1x3 = "new Etsy.Mini(<UNIQUE_SHOP_ID>,'thumbnail',1,3,0,'https://www.etsy.com');";

(function () {
    function resize() {
        var min_2500 = window.matchMedia('only screen and (min-width: 2500px)').addListener(function () {
            var eval_grid5x3 = eval(grid5x3);
            products.innerText = eval_grid5x3;
        });
        var min_1900_max_2499 = window.matchMedia('only screen and (min-width: 1900px) and ' +
        '(max-width: 2499px)').addListener(function () {
            var eval_grid4x3 = eval(grid4x3);
            products.innerText = eval_grid4x3;
        });
        var min_1200_max_1899 = window.matchMedia('only screen and (min-width: 1200px) and ' +
        '(max-width: 1899px)').addListener(function () {
            var eval_grid3x3 = eval(grid3x3);
            products.innerText = eval_grid3x3;
        });
        var min_900_max_1199 = window.matchMedia('only screen and (min-width: 900px) and ' +
        '(max-width: 1199px)').addListener(function () {
            var eval_grid2x3 = eval(grid2x3);
            products.innerText = eval_grid2x3;
        });
        var max_899 = window.matchMedia('only screen and (max-width: 899px)').addListener(function () {
            var eval_grid1x3 = eval(grid1x3);
            products.innerText = eval_grid1x3;
        });
    }

    resize();
}());

雖然這確實渲染了 Etsy 迷你商店,但它有一些奇怪的行為:

  1. 當我期望目標<div>被腳本替換時,整個<body>被注入的腳本替換。

  2. 每次我調整屏幕大小時,它都會添加另一個 Etsy 迷你商店(它不會替換當前存在的那個),導致頁面充滿了許多商店。

  3. 它沒有在頁面加載時呈現的問題仍然存在。

抱歉,如果這是一個相當簡單的問題。 我花了很多時間谷歌搜索解決方案,但我嘗試過的都沒有奏效。 我上面的代碼是我最接近響應式 Etsy Mini 商店的代碼。 感謝您的任何回答/意見/建議!

您應該始終將 JS 腳本放在 body 標記的關閉之前,這樣所有內容都加載到頁面上,然后執行 JS 文件,否則它會先運行文件然后加載頁面,導致它不執行任何功能,因為HTML 尚未加載。 代碼總是從左到右,從上到下閱讀。 希望這可以幫助。

我嘗試讓它與“更新和刷新<script>標簽”方法一起使用,但無法正確渲染。 然而,我做了一點挖掘,結果發現Etsy.Mini只是在頁面中注入了一個<iframe> 如果您抓取該<iframe>並更新其中的 URL,則可以更改 Etsy Mini 的大小。

這是 Etsy Mini 加載的<iframe>示例。

<iframe frameborder="0"
    src="https://www.etsy.com/mini.php?shop_id=9999999&amp;image_type=gallery&amp;rows=5&amp;columns=5&amp;featured=0"
    width="975" height="1025">
</iframe>

關鍵是<iframe>src部分中的 URL。 URL 中有兩個值得注意的屬性rowscolumns 在呈現頁面時更新這些屬性將改變 Etsy Mini 的大小,從而實現類似於混蛋響應的效果。

首先,將您的 Etsy Mini 腳本標簽包裝在帶有一些 id 的<div>中。 這使您可以輕松找到<iframe> 這將是<div>中唯一的一個,只要您除了<script>標記之外沒有放置任何其他內容。

<div id="etsy-iframe-container">
    <script type='text/javascript' src='https://www.etsy.com/assets/js/etsy_mini_shop.js'></script>
    <script type='text/javascript'> new Etsy.Mini(9999999, 'gallery', 5, 5, 0, 'https://www.etsy.com');</script>
</div>

出於參考目的,由於 Etsy 已從其網站上刪除了它的所有官方痕跡(但截至 2022 年它仍然有效!) Etsy.Mini的結構是。

Etsy.Mini(
    shopId (Integer), 
    type (String: 'gallery' or 'thumbnail'), 
    columns (Integer), 
    rows (Integer), 
    showUpTo4FeaturedItemsFirst (Boolean: 0 or 1), 
    etsyHomepageUrl (String: must be 'https://www.etsy.com')
)

您可以通過在此處粘貼您的商店 URL 來獲取您的 Etsy 商店 ID。 將 Etsy Mini <script>標簽包裝在<div>中后,您可以使用下面的 JavaScript(創建自定義 JS 文件並將其加載到 HTML 文檔中)通過修改其 URL 來動態調整<iframe>的大小。

這是基於對當前屏幕尺寸的了解。 單個 Etsy Mini 單元格的寬度和高度始終為184px 我通過在瀏覽器中檢查一個發現了這一點。 有了這些知識,您就可以計算出有多少 Etsy Mini 可以水平放置在屏幕上,並相應地更新<iframe> 可以使用相同的方法來更新行數,但鑒於現在大多數瀏覽器都支持無限滾動,我認為這並不是真正必要的。 設置minColumnsmaxColumns允許您為 Etsy Mini 在極端情況下的外觀提供一些界限。

let resizeEtsyMini = () => {
    let minColumns = 1;
    let maxColumns = 5;
    let clientWidth = document.documentElement.clientWidth;
    let etsyMiniColumns = Math.floor(clientWidth / 184);

    if (etsyMiniColumns < minColumns) {
        etsyMiniColumns = minColumns;
    }
    else if (etsyMiniColumns > maxColumns) {
        etsyMiniColumns = maxColumns
    }
    
    // Row value can be whatever, browsers have infinite scroll these days.
    setEtsyMiniSize(5, etsyMiniColumns, clientWidth);
}

let setEtsyMiniSize = (rows, columns, iframeWidth) => {
    let etsyIframe = document.getElementById("etsy-iframe-container").getElementsByTagName("iframe");
    let etsyURL = new URL(etsyIframe[0].src);
    etsyURL.searchParams.set("rows", rows);
    etsyURL.searchParams.set("columns", columns);

    etsyIframe[0].src = etsyURL.toString();
    etsyIframe[0].width = iframeWidth;
}

// On initial page load, and on every window resize, call resizeEtsyMini.
window.onload = window.onresize = resizeEtsyMini;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM