Megosztás a következőn keresztül:


Oktatóanyag: Képek feltöltése a Bing Visual Search API-ba

Figyelmeztetés

2020. október 30-án a Bing Search API-k átkerültek az Azure AI-szolgáltatásokból a Bing Search Servicesbe. Ez a dokumentáció csak referenciaként szolgál. A frissített dokumentációt a Bing search API dokumentációjában találja. Az új Azure-erőforrások Bing-kereséshez való létrehozásával kapcsolatos útmutatásért lásd: Bing Search-erőforrás létrehozása a Azure Marketplace keresztül.

A Bing Visual Search API lehetővé teszi, hogy a feltöltött képekhez hasonló képeket keressen a weben. Ebben az oktatóanyagban olyan webalkalmazást hozhat létre, amely képes képet küldeni az API-nak, és megjeleníti a weblapon visszaadott megállapításokat. Vegye figyelembe, hogy ez az alkalmazás nem felel meg az API használatához szükséges összes Bing-használati és megjelenítési követelménynek .

A minta teljes forráskódját további hibakezeléssel és széljegyzetekkel találja meg a GitHubon.

Az oktatóanyag részeként összeállított alkalmazás a következők bemutatására szolgál:

  • Kép feltöltése a Bing Visual Search API-ba
  • Képkeresési eredmények megjelenítése webalkalmazásban
  • Az API által biztosított különböző megállapítások megismerése

Előfeltételek

Azure-erőforrás létrehozása

Kezdje el használni a Bing Visual Search API-t az alábbi Azure-erőforrások egyikének létrehozásával:

Bing Search v7-erőforrás

  • Az Azure Portal keresztül érhető el, amíg el nem törli az erőforrást.
  • Válassza ki a tarifacsomagot S9 .

Többszolgáltatásos erőforrás

  • Az Azure Portal keresztül érhető el, amíg el nem törli az erőforrást.
  • Használja ugyanazt a kulcsot és végpontot az alkalmazásokhoz több Azure AI-szolgáltatásban.

A weblap létrehozása és strukturálása

Hozzon létre egy HTML-lapot, amely képet küld a Bing Visual Search API-nak, elemzéseket fogad és megjeleníti őket. A kedvenc szerkesztőjében vagy IDE-ben hozzon létre egy "uploaddemo.html" nevű fájlt. Adja hozzá a következő egyszerű HTML-struktúrát a fájlhoz:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Visual Search Upload Demo</title>
    </head>

    <body>
    </body>
</html>

Ossza fel a lapot egy kérelemszakaszra, ahol a felhasználó megadja a kéréshez szükséges összes információt, valamint egy válaszszakaszt, ahol az elemzések megjelennek. Adja hozzá a következő <div> címkéket a fájlhoz <body>. A <hr> címke vizuálisan elkülöníti a kérelemszakaszt a válaszszakasztól:

<div id="requestSection"></div>
<hr />
<div id="responseSection"></div>

Adjon hozzá egy címkét <script> a <head> címkéhez, amely tartalmazza az alkalmazás JavaScriptjét:

<script>
<\script>

A feltöltési fájl lekérése

Ahhoz, hogy a felhasználó kiválaszthassa a feltölteni kívánt képet, az alkalmazás a <input> címkét használja a típusattribútummal a következőre állítva: file. A felhasználói felületnek egyértelművé kell tennie, hogy az alkalmazás a Binget használja a keresési eredmények lekéréséhez.

Adja hozzá a következőt <div> a következőhöz: requestSection<div>. A bemeneti fájl egyetlen képet fogad el, amely bármilyen típusú lehet (például .jpg, .gif, .png). Az onchange esemény megadja a kezelőt, amelyet a rendszer akkor hív meg, amikor a felhasználó kiválaszt egy fájlt.

A <output> címke a kijelölt kép miniatűrjének megjelenítésére szolgál:

<div>
    <p>Select image to get insights from Bing:
        <input type="file" accept="image/*" id="uploadImage" name="files[]" size=40 onchange="handleFileSelect('uploadImage')" />
    </p>

    <output id="thumbnail"></output>
</div>

Fájlkezelő létrehozása

Hozzon létre egy kezelőfüggvényt, amely beolvasható a feltölteni kívánt képbe. Az objektum fájljain FileList keresztüli iterálás során a kezelőnek meg kell győződnie arról, hogy a kijelölt fájl képfájl, és hogy a mérete 1 MB vagy kevesebb. Ha a kép nagyobb, a feltöltés előtt csökkentenie kell a méretét. Végül a kezelő megjeleníti a kép miniatűrjeit:

function handleFileSelect(selector) {

    var files = document.getElementById(selector).files; // A FileList object

    for (var i = 0, f; f = files[i]; i++) {

        // Ensure the file is an image file.
        if (!f.type.match('image.*')) {
            alert("Selected file must be an image file.");
            document.getElementById("uploadImage").value = null;
            continue;
        }

        // Image must be <= 1 MB and should be about 1500px.
        if (f.size > 1000000) {
            alert("Image must be less than 1 MB.");
            document.getElementById("uploadImage").value = null;
            continue;
        }

        var reader = new FileReader();

        // Capture the file information.
        reader.onload = (function(theFile) {
            return function(e) {
                var fileOutput = document.getElementById('thumbnail');

                if (fileOutput.childElementCount > 0) {
                    fileOutput.removeChild(fileOutput.lastChild);  // Remove the current pic, if it exists
                }

                // Render thumbnail.
                var span = document.createElement('span');
                span.innerHTML = ['<img class="thumb" src="', e.target.result,
                                    '" title="', escape(theFile.name), '"/>'].join('');
                fileOutput.insertBefore(span, null);
            };
        })(f);

        // Read in the image file as a data URL.
        reader.readAsDataURL(f);
    }
}

Előfizetési kulcs hozzáadása és tárolása

Az alkalmazásnak előfizetési kulcsra van szüksége a Bing Visual Search API hívásához. Ehhez az oktatóanyaghoz a felhasználói felületen kell megadnia. Adja hozzá a következő <input> címkét (a típusattribútum szövegre van állítva) a <body> fájl címkéje <output> alatt:

    <div>
        <p>Subscription key: 
            <input type="text" id="key" name="subscription" size=40 maxlength="32" />
        </p>
    </div>

A képpel és az előfizetési kulccsal meghívhatja a Bing Visual Searcht, hogy betekintést nyerjen a képbe. Ebben az oktatóanyagban a hívás az alapértelmezett piacot () és a biztonságos keresési értéket (en-usmoderate) használja.

Ez az alkalmazás módosíthatja ezeket az értékeket. Adja hozzá a következőt <div> az előfizetési kulcs <div>alatt. Az alkalmazás egy címkét <select> használ a piaci és biztonságos keresési értékek legördülő listájának megadásához. Mindkét lista az alapértelmezett értéket jeleníti meg.

<div>
    <p><a href="#" onclick="expandCollapse(options.id)">Query options</a></p>

    <div id="options" style="display:none">
        <p style="margin-left: 20px">Market: 
            <select id="mkt">
                <option value="es-AR">Argentina (Spanish)</option>
                <option value="en-AU">Australia (English)</option>
                <option value="de-AT">Austria (German)</option>
                <option value="nl-BE">Belgium (Dutch)</option>
                <option value="fr-BE">Belgium (French)</option>
                <option value="pt-BR">Brazil (Portuguese)</option>
                <option value="en-CA">Canada (English)</option>
                <option value="fr-CA">Canada (French)</option>
                <option value="es-CL">Chile (Spanish)</option>
                <option value="da-DK">Denmark (Danish)</option>
                <option value="fi-FI">Finland (Finnish)</option>
                <option value="fr-FR">France (French)</option>
                <option value="de-DE">Germany (German)</option>
                <option value="zh-HK">Hong Kong SAR(Traditional Chinese)</option>
                <option value="en-IN">India (English)</option>
                <option value="en-ID">Indonesia (English)</option>
                <option value="it-IT">Italy (Italian)</option>
                <option value="ja-JP">Japan (Japanese)</option>
                <option value="ko-KR">Korea (Korean)</option>
                <option value="en-MY">Malaysia (English)</option>
                <option value="es-MX">Mexico (Spanish)</option>
                <option value="nl-NL">Netherlands (Dutch)</option>
                <option value="en-NZ">New Zealand (English)</option>
                <option value="no-NO">Norway (Norwegian)</option>
                <option value="zh-CN">People's Republic of China (Chinese)</option>
                <option value="pl-PL">Poland (Polish)</option>
                <option value="pt-PT">Portugal (Portuguese)</option>
                <option value="en-PH">Philippines (English)</option>
                <option value="ru-RU">Russia (Russian)</option>
                <option value="ar-SA">Saudi Arabia (Arabic)</option>
                <option value="en-ZA">South Africa (English)</option>
                <option value="es-ES">Spain (Spanish)</option>
                <option value="sv-SE">Sweden (Swedish)</option>
                <option value="fr-CH">Switzerland (French)</option>
                <option value="de-CH">Switzerland (German)</option>
                <option value="zh-TW">Taiwan (Traditional Chinese)</option>
                <option value="tr-TR">Türkiye (Turkish)</option>
                <option value="en-GB">United Kingdom (English)</option>
                <option value="en-US" selected>United States (English)</option>
                <option value="es-US">United States (Spanish)</option>
            </select>
        </p>
        <p style="margin-left: 20px">Safe search: 
            <select id="safesearch">
                <option value="moderate" selected>Moderate</option>
                <option value="strict">Strict</option>
                <option value="off">off</option>
            </select>
        </p>
    </div>
</div>

Keresési beállítások hozzáadása a weblaphoz

Az alkalmazás elrejti a listákat egy összecsukható <div> helyen, amelyet a Lekérdezés beállításai hivatkozás vezérel. Amikor a Lekérdezés beállításai hivatkozásra kattint, a <div> kinyílik, hogy láthassa és módosíthassa a lekérdezési beállításokat. Ha ismét a Lekérdezés beállításai hivatkozásra kattint, az <div> összecsukódik, és el van rejtve. Az alábbi kódrészlet a Lekérdezési beállítások hivatkozás kezelőjét onclick mutatja be. A kezelő határozza meg, hogy a <div> ki van-e bontva vagy összecsukva. Adja hozzá ezt a kezelőt a <script> szakaszhoz. A kezelőt a bemutató összes összecsukható <div> szakasza használja.

// Contains the toggle state of divs.
var divToggleMap = {};  // divToggleMap['foo'] = 0;  // 1 = show, 0 = hide


// Toggles between showing and hiding the specified div.
function expandCollapse(divToToggle) {
    var div = document.getElementById(divToToggle);

    if (divToggleMap[divToToggle] == 1) {   // if div is expanded
        div.style.display = "none";
        divToggleMap[divToToggle] = 0;
    }
    else {                                  // if div is collapsed
        div.style.display = "inline-block";
        divToggleMap[divToToggle] = 1;
    }
}

A kezelő meghívása onclick

Adja hozzá a következő "Get insights" gombot a törzs beállításai <div> alatt. A gomb lehetővé teszi a hívás indítását. Amikor a gombra kattint, a kurzort a fonó várakozási kurzorra módosítja, és meghívja a onclick kezelőt.

<p><input type="button" id="query" value="Get insights" onclick="document.body.style.cursor='wait'; handleQuery()" /></p>

Adja hozzá a gomb kezelőjét onclickhandleQuery() a <script> címkéhez.

A lekérdezés kezelése

A kezelő handleQuery() biztosítja, hogy az előfizetési kulcs jelen legyen, és 32 karakter hosszú legyen, és hogy egy kép legyen kijelölve. Eltávolítja az előző lekérdezésből származó megállapításokat is. Ezután meghívja a függvényt a sendRequest() hívás indításához.

function handleQuery() {
    var subscriptionKey = document.getElementById('key').value;

    // Make sure user provided a subscription key and image.
    // For this demo, the user provides the key but typically you'd
    // get it from secured storage.
    if (subscriptionKey.length !== 32) {
        alert("Subscription key length is not valid. Enter a valid key.");
        document.getElementById('key').focus();
        return;
    }

    var imagePath = document.getElementById('uploadImage').value;

    if (imagePath.length === 0)
    {
        alert("Please select an image to upload.");
        document.getElementById('uploadImage').focus();
        return;
    }

    var responseDiv = document.getElementById('responseSection');

    // Clear out the response from the last query.
    while (responseDiv.childElementCount > 0) {
        responseDiv.removeChild(responseDiv.lastChild);
    }

    // Send the request to Bing to get insights about the image.
    var f = document.getElementById('uploadImage').files[0];
    sendRequest(f, subscriptionKey);
}

A keresési kérelem elküldése

A sendRequest() függvény formázja a végpont URL-címét, beállítja a Ocp-Apim-Subscription-Key fejlécet az előfizetési kulcshoz, hozzáfűzi a feltöltendő kép bináris fájlját, megadja a válaszkezelőt, és elindítja a hívást:

function sendRequest(file, key) {
    var market = document.getElementById('mkt').value;
    var safeSearch = document.getElementById('safesearch').value;
    var baseUri = `https://api.cognitive.microsoft.com/bing/v7.0/images/visualsearch?mkt=${market}&safesearch=${safeSearch}`;

    var form = new FormData();
    form.append("image", file);

    var request = new XMLHttpRequest();

    request.open("POST", baseUri);
    request.setRequestHeader('Ocp-Apim-Subscription-Key', key);
    request.addEventListener('load', handleResponse);
    request.send(form);
}

Az API-válasz lekérése és kezelése

A handleResponse() függvény kezeli a Bing Visual Search hívásának válaszát. Ha a hívás sikeres, elemzi a JSON-választ az egyes címkéknek megfelelően, amelyek a megállapításokat tartalmazzák. Ezután hozzáadja a keresési eredményeket a laphoz. Az alkalmazás ezután összecsukható <div> adatokat hoz létre az egyes címkékhez, hogy kezelni tudja, mennyi adat jelenjen meg. Adja hozzá a kezelőt a <script> szakaszhoz.

function handleResponse() {
    if(this.status !== 200){
        alert("Error calling Bing Visual Search. See console log for details.");
        console.log(this.responseText);
        return;
    }

    var tags = parseResponse(JSON.parse(this.responseText));
    var h4 = document.createElement('h4');
    h4.textContent = 'Bing internet search results';
    document.getElementById('responseSection').appendChild(h4);
    buildTagSections(tags);

    document.body.style.cursor = 'default'; // reset the wait cursor set by query insights button
}

A válasz feldolgozása

A parseResponse függvény a JSON-választ szótárobjektummá alakítja a segítségével történő iterálással json.tags.

function parseResponse(json) {
    var dict = {};

    for (var i =0; i < json.tags.length; i++) {
        var tag = json.tags[i];

        if (tag.displayName === '') {
            dict['Default'] = JSON.stringify(tag);
        }
        else {
            dict[tag.displayName] = JSON.stringify(tag);
        }
    }

    return(dict);
}

Címkeszakasz létrehozása

A buildTagSections() függvény végigfut az elemezett JSON-címkéken, és meghívja a buildDiv() függvényt, hogy minden címkéhez hozzon létre egy-egy <div> elemet. Minden címke hivatkozásként jelenik meg. Amikor a hivatkozásra kattint, a címke kinyílik, és megjeleníti a címkéhez társított megállapításokat. Ha ismét a hivatkozásra kattint, a szakasz összecsukva jelenik meg.

function buildTagSections(tags) {
    for (var tag in tags) {
        if (tags.hasOwnProperty(tag)) {
            var tagSection = buildDiv(tags, tag);
            document.getElementById('responseSection').appendChild(tagSection);
        }
    }  
}

function buildDiv(tags, tag) {
    var tagSection = document.createElement('div');
    tagSection.setAttribute('class', 'subSection');

    var link = document.createElement('a');
    link.setAttribute('href', '#');
    link.setAttribute('style', 'float: left;')
    link.text = tag;
    tagSection.appendChild(link);

    var contentDiv = document.createElement('div');
    contentDiv.setAttribute('id', tag);
    contentDiv.setAttribute('style', 'clear: left;')
    contentDiv.setAttribute('class', 'section');
    tagSection.appendChild(contentDiv);

    link.setAttribute('onclick', `expandCollapse("${tag}")`);
    divToggleMap[tag] = 0;  // 1 = show, 0 = hide

    addDivContent(contentDiv, tag, tags[tag]);

    return tagSection;
}

A keresési eredmények megjelenítése a weblapon

A buildDiv() függvény meghívja a addDivContent függvényt az egyes címkék összecsukható <div>tartalmának összeállításához.

A címke tartalmazza a címkéhez tartozó válaszból származó JSON-t. Kezdetben csak a JSON első 100 karaktere látható, de a JSON-sztringre kattintva megjelenítheti az összes JSON-t. Ha ismét rákattint, a JSON-sztring összecsukódik, és ismét csak 100 karakter látható.

Következő lépésként adja hozzá a címkében található művelettípusokat. Minden művelettípushoz hívja meg a megfelelő függvényeket az elemzések hozzáadásához:

function addDivContent(div, tag, json) {

    // Adds the first 100 characters of the json that contains
    // the tag's data. The user can click the text to show the
    // full json. They can click it again to collapse the json.
    var para = document.createElement('p');
    para.textContent = String(json).substr(0, 100) + '...';
    para.setAttribute('title', 'click to expand');
    para.setAttribute('style', 'cursor: pointer;')
    para.setAttribute('data-json', json);
    para.addEventListener('click', function(e) {
        var json = e.target.getAttribute('data-json');

        if (e.target.textContent.length <= 103) {  // 100 + '...'
            e.target.textContent = json;
            para.setAttribute('title', 'click to collapse');
        }
        else {
            para.textContent = String(json).substr(0, 100) + '...';
            para.setAttribute('title', 'click to expand');
        }
    });
    div.appendChild(para); 

    var parsedJson = JSON.parse(json);

    // Loop through all the actions in the tag and display them.
    for (var j = 0; j < parsedJson.actions.length; j++) {
        var action = parsedJson.actions[j];

        var subSectionDiv = document.createElement('div');
        subSectionDiv.setAttribute('class', 'subSection');
        div.appendChild(subSectionDiv);

        var h4 = document.createElement('h4');
        h4.innerHTML = action.actionType;
        subSectionDiv.appendChild(h4);

        if (action.actionType === 'ImageResults') {
            addImageWithWebSearchUrl(subSectionDiv, parsedJson.image, action);
        }
        else if (action.actionType === 'DocumentLevelSuggestions') {
            addRelatedSearches(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'RelatedSearches') {
            addRelatedSearches(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'PagesIncluding') {
            addPagesIncluding(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'VisualSearch') {
            addRelatedImages(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'Recipes') {
            addRecipes(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'ShoppingSources') {
            addShopping(subSectionDiv, action.data.offers);
        }
        else if (action.actionType === 'ProductVisualSearch') {
            addProducts(subSectionDiv, action.data.value);
        }
        else if (action.actionType === 'TextResults') {
            addTextResult(subSectionDiv, action);
        }
        else if (action.actionType === 'Entity') {
            addEntity(subSectionDiv, action);
        }
    }
}

Elemzések megjelenítése különböző műveletekhez

Az alábbi függvények különböző műveletek elemzését jelenítik meg. A függvények vagy egy kattintható képet vagy kattintható hivatkozást biztosítanak, amely a képről további információkat tartalmazó weblapra küldi. Ezt a lapot Bing.com vagy a kép eredeti webhelye üzemelteti. Nem minden elemzési adat jelenik meg ebben az alkalmazásban. Az elemzéshez elérhető összes mező megtekintéséhez tekintse meg a Képek – Visual Search referenciát.

Megjegyzés

Minimális mennyiségű megállapítási információt kell megjelenítenie a lapon. További információért tekintse meg a Bing Search API használati és megjelenítési követelményeit.

RelatedImages insights

A addRelatedImages() függvény létrehoz egy címet a kapcsolódó képet üzemeltető webhelyeknek a műveletek listáján RelatedImages keresztüli iterálással, és egy <img> címkét fűz a külsőhöz <div> mindegyikhez:

    function addRelatedImages(div, images) {
        var length = (images.length > 10) ? 10 : images.length;

        // Set the title to the website that hosts the image. The title displays
        // when the user hovers over the image.

        // Make the image clickable. If the user clicks the image, they're taken
        // to the image in Bing.com.

        for (var j = 0; j < length; j++) {
            var img = document.createElement('img');
            img.setAttribute('src', images[j].thumbnailUrl + '&w=120&h=120');
            img.setAttribute('style', 'margin: 20px 20px 0 0; cursor: pointer;');
            img.setAttribute('title', images[j].hostPageDisplayUrl);
            img.setAttribute('data-webSearchUrl', images[j].webSearchUrl)

            img.addEventListener('click', function(e) {
                var url = e.target.getAttribute('data-webSearchUrl');
                window.open(url, 'foo');
            })

            div.appendChild(img);
        }
    }

PagesIncluding insights

A addPagesIncluding() függvény létrehoz egy hivatkozást a feltöltött képet üzemeltető webhelyek mindegyikéhez a műveletek listájának PagesIncluding iterálásával, és egy <img> címkének a külső elemekhez <div> való hozzáfűzésével:


    // Display links to the first 5 webpages that include the image.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addPagesIncluding(div, pages) {
        var length = (pages.length > 5) ? 5 : pages.length;

        for (var j = 0; j < length; j++) {
            var page = document.createElement('a');
            page.text = pages[j].name;
            page.setAttribute('href', pages[j].hostPageUrl);
            page.setAttribute('style', 'margin: 20px 20px 0 0');
            page.setAttribute('target', '_blank')
            div.appendChild(page);

            div.appendChild(document.createElement('br'));
        }
    }

RelatedSearches insights

A addRelatedSearches() függvény létrehoz egy hivatkozást a rendszerképet üzemeltető webhely számára a műveletek listájának RelatedSearches iterálásával, és egy <img> címkének a külső oldalhoz <div> való hozzáfűzésével:


    // Display the first 10 related searches. Include a link with the image
    // that when clicked, takes the user to Bing.com and displays the 
    // related search results.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addRelatedSearches(div, relatedSearches) {
        var length = (relatedSearches.length > 10) ? 10 : relatedSearches.length;

        for (var j = 0; j < length; j++) {
            var childDiv = document.createElement('div');
            childDiv.setAttribute('class', 'stackLink');
            div.appendChild(childDiv);

            var img = document.createElement('img');
            img.setAttribute('src', relatedSearches[j].thumbnail.url + '&w=120&h=120');
            img.setAttribute('style', 'margin: 20px 20px 0 0;');
            childDiv.appendChild(img);

            var relatedSearch = document.createElement('a');
            relatedSearch.text = relatedSearches[j].displayText;
            relatedSearch.setAttribute('href', relatedSearches[j].webSearchUrl);
            relatedSearch.setAttribute('target', '_blank');
            childDiv.appendChild(relatedSearch);

        }
    }

Receptek – megállapítások

A addRecipes() függvény létrehoz egy hivatkozást az egyes visszaadott receptekhez a műveletek listájának Recipes iterálásával, és egy <img> címkét fűz a külsőhöz <div> az egyes műveletekhez:

    // Display links to the first 10 recipes. Include the recipe's rating,
    // if available.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addRecipes(div, recipes) {
        var length = (recipes.length > 10) ? 10 : recipes.length;

        for (var j = 0; j < length; j++) {
            var para = document.createElement('p');

            var recipe = document.createElement('a');
            recipe.text = recipes[j].name;
            recipe.setAttribute('href', recipes[j].url);
            recipe.setAttribute('style', 'margin: 20px 20px 0 0');
            recipe.setAttribute('target', '_blank')
            para.appendChild(recipe);

            if (recipes[j].hasOwnProperty('aggregateRating')) {
                var span = document.createElement('span');
                span.textContent = 'rating: ' + recipes[j].aggregateRating.text;
                para.appendChild(span);
            }

            div.appendChild(para);
        }
    }

Vásárlási megállapítások

A addShopping() függvény létrehoz egy hivatkozást az esetlegesen visszaadott vásárlási eredményekhez a műveletek listájának RelatedImages iterálásával, valamint egy <img> címkének az egyes műveletekhez való hozzáfűzésével <div> :

    // Display links for the first 10 shopping offers.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addShopping(div, offers) {
        var length = (offers.length > 10) ? 10 : offers.length;

        for (var j = 0; j < length; j++) {
            var para = document.createElement('p');

            var offer = document.createElement('a');
            offer.text = offers[j].name;
            offer.setAttribute('href', offers[j].url);
            offer.setAttribute('style', 'margin: 20px 20px 0 0');
            offer.setAttribute('target', '_blank')
            para.appendChild(offer);

            var span = document.createElement('span');
            span.textContent = 'by ' + offers[j].seller.name + ' | ' + offers[j].price + ' ' + offers[j].priceCurrency;
            para.appendChild(span);

            div.appendChild(para);
        }
    }

Termékelemzések

A addProducts() függvény létrehoz egy hivatkozást a visszaadott termékek eredményeihez a műveletek listájának Products iterálásával, és egy <img> címkét fűz a külsőhöz <div> az egyes műveletekhez:


    // Display the first 10 related products. Display a clickable image of the
    // product that takes the user to Bing.com search results for the product.
    // If there are any offers associated with the product, provide links to the offers.
    // TODO: Add 'more' link in case the user wants to see all of them.
    function addProducts(div, products) {
        var length = (products.length > 10) ? 10 : products.length;

        for (var j = 0; j < length; j++) {
            var childDiv = document.createElement('div');
            childDiv.setAttribute('class', 'stackLink');
            div.appendChild(childDiv);

            var img = document.createElement('img');
            img.setAttribute('src', products[j].thumbnailUrl + '&w=120&h=120');
            img.setAttribute('title', products[j].name);
            img.setAttribute('style', 'margin: 20px 20px 0 0; cursor: pointer;');
            img.setAttribute('data-webSearchUrl', products[j].webSearchUrl)
            img.addEventListener('click', function(e) {
                var url = e.target.getAttribute('data-webSearchUrl');
                window.open(url, 'foo');
            })
            childDiv.appendChild(img);

            if (products[j].insightsMetadata.hasOwnProperty('aggregateOffer')) {
                if (products[j].insightsMetadata.aggregateOffer.offerCount > 0) {
                    var offers = products[j].insightsMetadata.aggregateOffer.offers;

                    // Show all the offers. Not all markets provide links to offers.
                    for (var i = 0; i < offers.length; i++) {  
                        var para = document.createElement('p');

                        var offer = document.createElement('a');
                        offer.text = offers[i].name;
                        offer.setAttribute('href', offers[i].url);
                        offer.setAttribute('style', 'margin: 20px 20px 0 0');
                        offer.setAttribute('target', '_blank')
                        para.appendChild(offer);

                        var span = document.createElement('span');
                        span.textContent = 'by ' + offers[i].seller.name + ' | ' + offers[i].price + ' ' + offers[i].priceCurrency;
                        para.appendChild(span);

                        childDiv.appendChild(para);
                    }
                }
                else {  // Otherwise, just show the lowest price that Bing found.
                    var offer = products[j].insightsMetadata.aggregateOffer;

                    var para = document.createElement('p');
                    para.textContent = `${offer.name} | ${offer.lowPrice} ${offer.priceCurrency}`; 

                    childDiv.appendChild(para);
                }
            }
        }
    }

TextResult insights

A addTextResult() függvény a képen felismert szövegeket jeleníti meg:


    function addTextResult(div, action) {
        var text = document.createElement('p');
        text.textContent = action.displayName;
        div.appendChild(text);
    }

A addEntity() függvény egy olyan hivatkozást jelenít meg, amely a felhasználó Bing.com, ahol a rendszerkép entitástípusának részleteit lekérheti, ha észlelték:

    // If the image is of a person, the tag might include an entity
    // action type. Display a link that takes the user to Bing.com
    // where they can get details about the entity.
    function addEntity(div, action) {
        var entity = document.createElement('a');
        entity.text = action.displayName;
        entity.setAttribute('href', action.webSearchUrl);
        entity.setAttribute('style', 'margin: 20px 20px 0 0');
        entity.setAttribute('target', '_blank');
        div.appendChild(entity);
    }

A addImageWithWebSearchUrl() függvény egy kattintható képet jelenít meg, <div> amely a felhasználót a találatok Bing.com:

    function addImageWithWebSearchUrl(div, image, action) {
        var img = document.createElement('img');
        img.setAttribute('src', image.thumbnailUrl + '&w=120&h=120');
        img.setAttribute('style', 'margin: 20px 20px 0 0; cursor: pointer;');
        img.setAttribute('data-webSearchUrl', action.webSearchUrl);
        img.addEventListener('click', function(e) {
            var url = e.target.getAttribute('data-webSearchUrl');
            window.open(url, 'foo');
        })
        div.appendChild(img);
    }

CSS-stílus hozzáadása

Adja hozzá a következő <style> szakaszt a <head> címkéhez a weblap elrendezésének rendszerezéséhez:

        <style>

            .thumb {
                height: 75px;
                border: 1px solid #000;
            }

            .stackLink {
                width:180px;
                min-height:210px;
                display:inline-block;
            }
            .stackLink a {
                float:left;
                clear:left;
            }

            .section {
                float:left;
                display:none;
            }

            .subSection {
                clear:left;
                float:left;
            }

        </style>

Következő lépések