hung pro vn

[Blogger] Tạo khung chứa code có nút Copy và Download cho Blogger / Blogspot

Bài viết này sẽ hướng dẫn các bạn tạo một khung chứa code (Pre code box) tuyệt đẹp cho Blogger/Blogspot, hơn nữa khung code này còn có tích hợp thêm nút Copy và Download giúp người đọc dễ dàng trong việc sao chép code ở bài viết.
Cách tạo khung chứa code có nút Copy và Download cho Blogger / Blogspot.
Bước 1: Đăng nhập vào trang quản trị của Blogger ~> Chủ đề ~> Vào phần chỉnh sửa HTML của template ~> Thêm đoạn code CSS này vào phía trên thẻ ]]></b:skin>
/* Code Box */
.pre{background:#f6f6f6;color:#2f3337;direction: ltr;position:relative;border-radius:3px;overflow:hidden;margin:1.7em auto} 
.pre pre{margin:0;color:inherit;background:inherit;display:block;position:relative;font-size:13px;line-height:1.6em;border-radius:3px;padding:30px 20px 20px;-moz-tab-size:2;tab-size:2;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none; overflow:auto;direction:ltr;white-space:pre} 
.pre.adv{border-radius:10px}
.pre.adv::before{display:none}
.pre:not(.str) .prCd{display:none}
.pre.str .prTl{display:none;}
.pre.adv pre{padding-top:60px}
.preM{position:absolute;top:0;right:0;left:0;width:100%;background: rgba(0,0,0,.04);padding:10px 10px 10px 20px;display:flex;justify-content:space-between;align-items:center;flex-wrap:nowrap;z-index:2}
.preT{font-size:12px;font-family: var(--fontC);line-height:1rem;position:relative;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-right:10px;}
.preA{display:flex;gap:8px;white-space:nowrap;}
.preA button{outline:none;border:none;width:30px;height:30px;background:#d9d9d9;padding:0;margin:0;border-radius:50%;transition:border-radius .2s ease;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;}
.preA button:hover{border-radius:40%;}
.preA button >svg{width:18px;height:18px;stroke:none;fill:#2e2e2e;transition: all .5s ease;}
.pre.cpd .prCp svg, .pre.pnd .prDl svg, .pre.dwn .prDl svg{animation: jiggle 1s}
.pre.cpd .prCp svg .a,.pre:not(.cpd) .prCp svg .b{opacity:0}
.pre.dwn .prDl svg .a, .pre.pnd .prDl svg .a,.pre:not(.pnd) .prDl svg .b,.pre:not(.dwn) .prDl svg .c{opacity:0}
@keyframes jiggle{0%{transform:rotate(0)}20%{transform:rotate(26deg)}40%{transform:rotate(-26deg)}60%{transform:rotate(26deg)}80%{transform:rotate(-26deg)}100%{transform:rotate(0)}}
@-webkit-keyframes jiggle{0%{transform:rotate(0)}20%{transform:rotate(26deg)}40%{transform:rotate(-26deg)}60%{transform:rotate(26deg)}80%{transform:rotate(-26deg)}100%{transform:rotate(0)}}

Bước 2: Thêm đoạn JavaScript dưới đây vào phía trên thẻ </body>
<script>/*<![CDATA[*/
0<document.querySelectorAll('div.pre.nb').length&&(() => {
let preD = document.querySelectorAll('div.pre.nb');
function saveDoc(x, d, n) {
    if (n = typeof n == 'string' ? n : 'text/plain', d = typeof d == 'string' ? d : 'File_' + (new Date).getTime() + '.txt', x) {
        n = new Blob([x], {
            type: n
        });
        if (navigator.msSaveBlob) return navigator.msSaveBlob(n, d); {
            let x = window.URL.createObjectURL(n),
                c = document.createElement("a");
            c.classList.add('hidden'), c.href = x, c.download = d, document.body.appendChild(c), c.click(), c.remove(), window.URL.revokeObjectURL(x)
        }
    }
}
for (let r = 0; r < preD.length; r++) {
    let b = preD[r];
    b.classList.add('adv');
    let x = b.dataset.text || 'File_' + (new Date).getTime(),
        e = b.dataset.file || x,
        _ = b.dataset.lang || '.txt',
        m = 'undefined' !== typeof b.dataset.time ? isNaN(Number(b.dataset.time)) ? 'false' === b.dataset.time ? 0 : 3 : Number(b.dataset.time) : 3,
        c = 'undefined' === typeof b.dataset.download || b.dataset.download == 'true',
        d = 'undefined' === typeof b.dataset.copy || b.dataset.copy == 'true',
        n = 'undefined' === typeof b.dataset.view || b.dataset.view == 'true',
        a = b.querySelector('pre'),
        t = a.innerText;
    b.insertAdjacentHTML('afterbegin', "<div class='preM'><div class='preT'><span class='prTl'>" + (null == x ? '&lt;/&gt;' : x) + "</span><span class='prCd'></span></div><div class='preA'>" + (n ? '\x3C!--[ Prev' + "iew ]--><button class='prVw'><svg viewBox='0 0 24 24'><path d='M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z'/></svg></button>" : "") + (c ? "\x3C!--[ Download ]--><button class='prDl'><svg viewBox='0 0 24 24'><path class='a' d='M8 17V15H16V17H8M16 10L12 14L8 10H10.5V6H13.5V10H16M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4Z'/><path class='b' d='M13,2.03C17.73,2.5 21.5,6.25 21.95,11C22.5,16.5 18.5,21.38 13,21.93V19.93C16.64,19.5 19.5,16.61 19.96,12.97C20.5,8.58 17.39,4.59 13,4.05V2.05L13,2.03M11,2.06V4.06C9.57,4.26 8.22,4.84 7.1,5.74L5.67,4.26C7.19,3 9.05,2.25 11,2.06M4.26,5.67L5.69,7.1C4.8,8.23 4.24,9.58 4.05,11H2.05C2.25,9.04 3,7.19 4.26,5.67M2.06,13H4.06C4.24,14.42 4.81,15.77 5.69,16.9L4.27,18.33C3.03,16.81 2.26,14.96 2.06,13M7.1,18.37C8.23,19.25 9.58,19.82 11,20V22C9.04,21.79 7.18,21 5.67,19.74L7.1,18.37M12,16.5L7.5,12H11V8H13V12H16.5L12,16.5Z'/><path class='c' d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M7,15H17V17H7V15M10.3,11.2L8.4,9.3L7,10.7L10.3,14L17,7.3L15.6,5.9L10.3,11.2Z'/></svg></button>" : "") + (d ? "\x3C!--[ Copy ]--><button class='prCp'><svg viewBox='0 0 24 24'><path class='a' d='M20,16V4H8V16H20M22,16A2,2 0 0,1 20,18H8C6.89,18 6,17.1 6,16V4C6,2.89 6.89,2 8,2H20A2,2 0 0,1 22,4V16M16,20V22H4A2,2 0 0,1 2,20V7H4V20H16Z'/><path class='b' d='M20,16V10H22V16A2,2 0 0,1 20,18H8C6.89,18 6,17.1 6,16V4C6,2.89 6.89,2 8,2H16V4H8V16H20M10.91,7.08L14,10.17L20.59,3.58L22,5L14,13L9.5,8.5L10.91,7.08M16,20V22H4A2,2 0 0,1 2,20V7H4V20H16Z'/></svg></button>" : "") + '</div></di' + "v>");
    let i = b.querySelector('.prVw'),
        l = b.querySelector('.prDl'),
        f = b.querySelector('.prCp'),
        W = b.querySelector('.prCd');
    null !== i && i.addEventListener('click', () => {
        var x = '#252526';
        x = '<!DOCTYPE html><html><head><title>' + e.replace(/\./g, "").replace(/ /g, "_") + _ + "</title><meta content='width=device-width,initial-scale=1,user-scalable=1,minimum-scale=1,maximum-scale=5' name='viewport'/><meta content='" + x + "' name='theme-color'/><meta content='" + x + "' name='msapplication-navbutton-color'/><meta content='" + x + "' name='apple-mobile-web-app-status-bar-style'/><link rel='shortcut icon' type='image/png' href='https://www.nldblog.com/main/android-icon-192x192.png'><style>body{min-height:100vh;background:#252526;color:#fff}*{margin:0;padding:0}html{line-height:1em;background:#1d1f21;color:#c5c8c6}pre{white-space:pre-wrap;word-wrap:break-word;word-break:break-all;padding:20px}pre i{font-style:normal}</style></head><body><div class='pre'>" + a.outerHTML + '</div></body></html>';
        x = new Blob([x], {
            type: 'text/html'
        });
        window.navigator.msSaveOrOpenBlob ? window.navigator.msSaveOrOpenBlob(blobObject, fileName) : (x = window.URL.createObjectURL(x), window.open(x, '_blank'), window.URL.revokeObjectURL(x))
    }), 
    null !== l && l.addEventListener('click', () => {
        l.disabled = !0;
        let c = m;
        b.classList.add('pnd', 'str'), W.innerHTML = 0 !== m ? 'Please wai' + "t " + c + 's...' : 'Please wai' + 't...';
        let a = setInterval(() => {
            0 !== m && --c, 0 !== m && (W.innerHTML = 'Please wait ' + c + 's...'), c <= 0 && (clearInterval(a), setTimeout(() => {
                W.innerHTML = 'Downloading...', setTimeout(() => {
                    b.classList.remove('pnd'), b.classList.add('dwn'), saveDoc(t, e.replace(/\./g, "").replace(/ /g, "_") + '_by_BlogDX_ducxoan.com' + _, 'text/plain'), W.innerHTML = 'Download started...', setTimeout(() => {
                        b.classList.remove('dwn', 'str'), l.disabled = !1
                    }, 3e3)
                }, 2e3)
            }, 1e3))
        }, 1e3)
    }), 
    null !== f && f.addEventListener('click', () => {
        var x = getSelection(),
            c = document.createRange();
        c.selectNodeContents(a), x.removeAllRanges(), x.addRange(c), document.execCommand('copy'), x.removeAllRanges(), f.disabled = !0, b.classList.add('cpd'), setTimeout(function() {
            b.classList.remove('cpd'), f.disabled = !1
        }, 3e3)
    })
}})();
/*]]>*/</script>

Vậy là xong, bây giờ khi bạn muốn chèn khung chứa code vào bài viết thì bạn sử dụng cú pháp sau để hiển thị code:
<div class="pre nb" data-copy="true" data-download="true" data-file="filename" data-lang="fileformat" data-text="typecode" data-time="true" data-view="true">
  <pre>
        <!--Code-->
  </pre>
</div>

Trong đó:
  • data-text là loại code, ví dụ: CSS, HTML hoặc JavaScript
  • data-file là tên tải xuống của file
  • data-lang là định dạng tải xuống của file, ví dụ: .css, .js, .html, .txt
  • data-time là thời gian đếm ngược tải xuống, giá trị true hoặc false
  • data-download là hiển thị nút tải xuống, giá trị true hoặc false
  • data-copy là hiển thị nút copy, giá trị true hoặc false
  • data-view là hiển thị nút preview, giá trị true hoặc false
Nhớ thay phần <!--Code--> bằng đoạn code mà bạn muốn chèn vào khung nhé. Chúc mọi người thành công.

Hướng dẫn bình luận

Mọi người để lại bình luận góp ý, nhận xét về những bài viết mà mình chia sẽ văn minh lịch sự hay kích động, Không spam, không chèn link quảng cáo, bán hàng, Không sử dụng từ ngữ thô tục, xúc phạm, kích động, Link chỉ được phép khi thực sự liên quan đến nội dung bài viết, Không mạo danh người khác hoặc sử dụng email giả, Bình luận vi phạm sẽ bị xóa không cần thông báo trước.
Mọi người lưu ý răng, nếu muốn chia sẽ code ở bình luần thì cần mã hóa code trước khi bỏ vào khung nhé. :)
⑴ Chèn ℂ𝕤𝕤 theo mẫu : [pre css] CSS [/pre]
⑵ Chèn ℍ𝕥𝕞𝕝 theo mẫu : [pre html] HTML [/pre]
⑶ Chèn 𝕁𝕒𝕧𝕒𝕤𝕔𝕣𝕚𝕡𝕥 theo mẫu : [pre js] Javascript [/pre]

🖼️ Chèn 𝕀𝕞𝕒𝕘𝕖 theo mẫu : [img] Link hình ảnh [/img]
🎞️ Chèn Video 𝕐𝕠𝕦𝕥𝕦𝕓𝕖 theo mẫu : [youtube] Link Youtube [/youtube]

8 Nhận xét

  1. khung chưa code đẹp đó e, nhưng demo bị lỗi vì e chưa xóa hết những phần tử của khung pre trc của e, làm nó bị ảnh hưởng e nhé.

    Trả lờiXóa
  2. Trả lời
    1. hehe, tks c, e đã cập nhạt link demo đó vào bài viết r`c nhé <3

      Xóa
    2. link của c đã đc bảo vệ, hehe e đang phát triển trang bảo mật link nè c, thủ thuật này thì có nhiều r` nhưng e chưa áp dụng cho blog demo : https://protect-hungqb.blogspot.com/p/link.html?u=U2FsdGVkX18nKQt%2B368owLcAAFca5Pi%2BWCoM2TgLsgPJuThfzBtbvPVfyjw8FA9wTFi0XmWgz9xojzQlchBJkka4KVNA50Hd7%2B8PWrBPw01e1JFIDp1Exkmp40y4gjZlYe2QAvvSF0o1t79FaaFr%2B%2BwE%2BX63Al2Ge9yo2qw%2BqgA%3D

      Xóa
    3. Đẹp đó e. Nhưng rơi rắc rối, tối giản lại chút thì ok

      Xóa

Top