如何实现带有社交网络链接的图标的显示?



我有一个关于用户卡的小项目。

我有一个JSON文件,其中包含生成卡片的用户数据。

我的任务是在卡片中显示用户拥有的那些社交网络的图标。如果用户没有任何社交网络-不要在他的个人资料中显示此社交网络的图标。

坦率地说,我不明白该怎么做。

JSON中的数据以这种形式出现(以一个用户为例):

{
      "id": 7,
      "firstName": "Daniel",
      "lastName": "Day-Lewis",
      "profilePicture": "https://i2.wp.com/comicbookdebate.com/wp-content/uploads/2019/07/There20will20be20blood202-750x460.jpg?resize=750%2C460&ssl=1",
      "contacts": [
        "https://www.facebook.com/JasonStatham/",
        "https://twitter.com/realjstatham",
        "https://www.instagram.com/jasonstatham/?hl=ru"
      ]
    }

JS索引文件(添加,以便清楚我如何在这个项目中使用布局):

'use strict';
const cardsContainer = document.querySelector('#root');
async function loadCards(url) {
  try {
    const response = await fetch(url);
    const data = await response.json();
    const cards = data.map((data) => generateUserCard(data));
    cardsContainer.append(...cards);
  } catch(e) {
    throw new Error(e);
  }
}
loadCards('./assets/js/data.json');
function generateUserCard(userObj) {
  const fullName =
    `${userObj.firstName} ${userObj.lastName}`.trim() ||
    CARD_CONSTANTS.userName;
  
  const imgWrapper = createUserCardImageWrapper(userObj, fullName);
  const cardName = createElement('h2', {classNames: ['cardName']}, fullName);
  const cardDescription = createElement('p', {classNames: ['cardDescription']}, userObj.description || CARD_CONSTANTS.cardDescription);
  
  const cardArticle = createElement('article', {classNames: ['cardContainer']}, imgWrapper, cardName, cardDescription);
  const card = createElement('li', {classNames: ['userCardWrapper']}, cardArticle);
  return card;
}
function createUserCardImageWrapper(userObj, fullName) {
  const userImgElem = createElement('img', {
    classNames: ['cardImg'],
    attributes: {
      src: userObj.profilePicture,
      alt: fullName,
      'data-id': userObj.id,
    },
    listeners: {
      error: errorHandler,
      load: loadHandler,
    },
  });
  const initialsElem = createElement(
    'div',
    { classNames: ['initials'] },
    getInitials(fullName)
  );
  const imgWrapperElem = createElement(
    'div',
    {
      classNames: ['cardImgWrapper'],
      attributes: { id: `imgWrapper${userObj.id}` },
    },
    initialsElem
  );
  return imgWrapperElem;
}
function errorHandler({ target }) {
  target.remove();
}
function loadHandler({
  target,
  target: {
    dataset: { id },
  },
}) {
  document.getElementById(`imgWrapper${id}`).append(target);
}

我是这样把社交网络和图标联系起来的(以Twitter为例):

const SUPPORTED_SOCIAL_NETWORKS = new Map([
  [
    "twitter.com",
    {
      src: "https://w7.pngwing.com/pngs/872/50/png-transparent-computer-icons-social-media-logo-twitter-social-media-blue-logo-social-media-thumbnail.png",
      alt: "twitter link for",
    },
  ],
  ["www.facebook.com"],
]);

这实际上非常简单,参见代码

中的注释

// Get the network hosts for of a user and optionally filter them
let getNetworkHosts = (userId, filter) => {
  if (match = users.filter( user => userId === user.id )) {
    contacts = match[0].contacts.map( url => (new URL(url)).hostname) 
    if (filter) contacts = contacts.filter(filter)
    return contacts
  }
}
// A filter that can be applied to a list
let supportedNetworkFilter = elem => SUPPORTED_SOCIAL_NETWORKS[elem]
// Create an image tag
let createImage = (url) => {
  let img = document.createElement("img")
  img.src = url
  return img
}
users =
[ { "id": 7
  , "firstName": "Daniel"
  , "lastName": "Day-Lewis"
  , "profilePicture": "https://i2.wp.com/comicbookdebate.com/wp-content/uploads/2019/07/There20will20be20blood202-750x460.jpg?resize=750%2C460&ssl=1"
  , "contacts":
    [ "https://www.facebook.com/JasonStatham/"
    , "https://twitter.com/realjstatham"
    , "https://www.instagram.com/jasonstatham/?hl=ru"
    ]
  }
]
const SUPPORTED_SOCIAL_NETWORKS =
{ "twitter.com":
  { src: "https://w7.pngwing.com/pngs/872/50/png-transparent-computer-icons-social-media-logo-twitter-social-media-blue-logo-social-media-thumbnail.png"
  , alt: "twitter link for"
  }
, "www.facebook.com": {} // Oops, facebook has no face
}
// Add some images to a div
let div = document.getElementById('images')
for (network of getNetworkHosts(7, supportedNetworkFilter)) {
  div.appendChild(createImage(SUPPORTED_SOCIAL_NETWORKS[network].src))
}
<div id="images"></div>

最新更新