简体   繁体   中英

Shorten Multiple and Repetitive properties

(I have the similar problem earlier today but now, it's different). I have a code that creates an element, set attribute to them, and lastly, append to the parent div.

I already tried this:

Object.entries(selectorsByProp).forEach(([prop, selector]) => {
    document.querySelector(selector).innerHTML = post[i][prop];
});

which actually works but it can only manipulate elements that shows and displays my data. What I need is that it has to create element, set attributes and append. Here's my ridiculous code...

var post = JSON.parse(this.response);
for (var i = 0; i < 3; i++) {
    var listcard = document.createElement("div"),
        imgcontent = document.createElement("div"),
        imgcntnr = document.createElement("div"),
        imglnk = document.createElement("a"),
        a = document.createElement("a"),
        img = document.createElement("img"),
        txtcntnt = document.createElement("div"),
        span = document.createElement("span");

    listcard.setAttribute('class', 'list-card');
    imgcontent.setAttribute('class', 'img-content');
    imgcntnr.setAttribute('class', 'img-container');
    imglnk.setAttribute('href', '#');
    img.setAttribute('class', 'thumb');
    txtcntnt.setAttribute('class', 'text-content');
    a.setAttribute('href', '#');
    a.setAttribute('class', 'title');
    span.setAttribute('class', 'excerpt');

    img.setAttribute('src', post[i].img);
    img.setAttribute('alt', post[i].titles);
    a.innerHTML = post[i].titles;
    span.innerHTML = post[i].descs;

    imglnk.appendChild(img);
    imgcntnr.appendChild(imglnk);
    imgcontent.appendChild(imgcntnr);
    txtcntnt.innerHTML += a.outerHTML + span.outerHTML;
    listcard.innerHTML += imgcontent.outerHTML + txtcntnt.outerHTML;
    parent.appendChild(listcard);
}
<div class="list-card">
    <div class="img-content">
        <div class="img-container">
            <a href="#"> <img src="https://picsum.photos/182/135/?random" alt="" class="thumb"></a>
        </div>
    </div>
    <div class="text-content">
        <a href="#" class="title">Lorem Ipsum</a>
        <span class="excerpt">Lorem Ipsum</span>
    </div>
</div>

You might consider inserting the HTML to insert all at once with insertAdjacentHTML instead, rather than (verbosely) creating and appending lots of elements. Use a template literal to keep things readable:

const makeHTML = ({ img, titles, descs }) => `
<div class="list-card">
    <div class="img-content">
        <div class="img-container">
            <a href="#"> <img src="${img}" alt="${titles}" class="thumb"></a>
        </div>
    </div>
    <div class="text-content">
        <a href="#" class="title">${descs}</a>
        <span class="excerpt">${descs}</span>
    </div>
</div>
`;

post.forEach((item) => {
  parent.insertAdjacentHTML('beforeend', makeHTML(item));
});

Keep in mind that this code, like your existing code, assumes that the input is trustworthy. If it isn't, strip the HTML tags first , eg

const makeHTML = ({ img, titles, descs }) => {
  const safeImg = stripHTML(img);
  const safeTitles = stripHTML(titles);
  const safeDescs = stripHTML(descs);
  return `
    // rest of the template literal
    // which references safeImg, etc
  `;
};

Otherwise, you'll be allowing arbitrary script execution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM