多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > web前端 > htmlcss > 【應(yīng)用】Markdown 在線閱讀器

【應(yīng)用】Markdown 在線閱讀器

來源:程序員人生   發(fā)布時(shí)間:2017-02-14 08:37:09 閱讀次數(shù):4939次

前言

1款在線的 Markdown 瀏覽器,主要用來展現(xiàn) Markdown 內(nèi)容。支持 HTML 導(dǎo)出,同時(shí)可以方便的添加擴(kuò)大功能。在這個(gè)瀏覽器的基礎(chǔ)又做了1款在線 Github Pages 頁面生成器,可以方便的生成不同主題風(fēng)格的 GitHub Page 頁面。

功能

瀏覽器

  • 支持文件拖拽
  • 兼容移動(dòng)端
  • Prism.js / Highlight.js 代碼高亮
  • 自動(dòng)生成目錄
  • 本地圖片顯示
  • 導(dǎo)出 Html (包括樣式)
  • 擴(kuò)大功能
    • Toto 列表
    • MathJax
    • 時(shí)序圖 (Js sequence diagrams)
    • Emoji (Emojify.js)
    • 圖表 (ECharts)

Github Page 生成器

在上面的基礎(chǔ)上加上了下面的功能

  • 支持多種頁面主題
    • Architect
    • Cayman
    • Minimal
    • Modernist
    • Slate
    • Time machine
  • 評(píng)論
    • 多說
    • Disqus

地址

瀏覽器
在線地址  效果預(yù)覽  源碼

生成器
在線地址  效果預(yù)覽  源碼

效果

瀏覽器

生成器

實(shí)現(xiàn)

文件解析

程序使用 marked 將 markdown 格式轉(zhuǎn)為 html 格式,這是1個(gè) js 的庫,可以直接在閱讀器端使用。下面是1個(gè)基本的示例

var htmlContent = marked(mdContent);
$("#content").html(htmlContent);

同時(shí) marked 提供了1些接口,讓我們可以方便的定制自己的功能。具體的可以參考它的 說明文件 。在下面我們會(huì)介紹我們是如何利用這些接口來實(shí)現(xiàn)擴(kuò)大功能。

文件上傳

自定義上傳按鈕樣式

原始的上傳按鈕太丑了,所以我們需要自定義自己的樣式。這里使用的方式是使用在 input 上面覆蓋1個(gè) button,用 button 來顯示樣式。同時(shí)我們將 buttonpointer-events 設(shè)為 none,就能夠禁止 button 的事件響應(yīng)(具體可以參考這里)。下面是具體的實(shí)現(xiàn)代碼:
html:

<div class="upload-area" id="upload-area">
    <input type="file" id="select-file" class="select-file">
    <button class="select-file-style" id="drop">選擇或拖拽 Markdown 文件到此</button>
 </div>

css

.upload-area {
  width: auto;
  height: 200px;
  margin: 0 2.6em 0 0.4em;
  padding: 0;
  position: relative;
  cursor: pointer;
  transition: height 0.5s;
}
.upload-area .select-file {
  border-width: 0px;
  width: 100%;
  height: 200px;
  margin: 0;
  cursor: pointer;
}
.upload-area .select-file-style {
  background: #F5F7FA;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 200px;
  border: 0px;
  pointer-events: none;
  color: #AAB2BD;
  font-size: 2em;
  line-height: 2em;
  font-family: "Microsoft YaHei", "Tahoma", arial;
}

下面是效果圖

讀取文件內(nèi)容

由于程序完全是運(yùn)行在閱讀器端,所以我們使用 html5 的 FileReader 來讀取本地文件。FileReader 提供 4 種讀取文件的方式:

  • readAsBinaryString(Blob|File)
  • readAsText(Blob|File, opt_encoding)
  • readAsDataURL(Blob|File)
  • readAsArrayBuffer(Blob|File)

其中 readAsText 用來讀取文本文件,readAsDataUrl 可以用來讀取圖片。具體的介紹可以參考 這里 。FileReader 1般結(jié)合文件選擇事件或拖拽事件使用,由于通過這兩個(gè)事件可以取得源文件。另外 FileReader 是異步讀取的,通過 onload 事件可以監(jiān)聽文件是不是讀取終了。下面是1個(gè)示例, 通過點(diǎn)擊 <input type= "file"> 選擇文件,然后讀取文件內(nèi)容。

document.getElementById("file-select").addEventListener("change", function(e) {
    e.stopPropagation();
    e.preventDefault();
    var reader = new FileReader();
    reader.readAsText(this.files[0]);
    reader.onload = function (e) {
        var content = e.target.result;
        //......
    };
}, false);

拖拽文件

為了方便用戶操作,我們提供了點(diǎn)擊和拖拽兩種方式來上傳文件。現(xiàn)在的主流閱讀器都支持文件拖拽功能,下面是拖拽進(jìn)程中觸發(fā)的事件

事件 描寫
dragstart 用戶開始拖動(dòng)對象時(shí)觸發(fā)。
dragenter 鼠標(biāo)初次移到目標(biāo)元素并且正在進(jìn)行拖動(dòng)時(shí)觸發(fā)。這個(gè)事件的監(jiān)聽器應(yīng)當(dāng)之指出這個(gè)位置是不是允許放置元素。如果沒有監(jiān)聽器或監(jiān)聽器不履行任何操作,默許情況下不允許放置。
dragover 拖動(dòng)時(shí)鼠標(biāo)移到某個(gè)元素上的時(shí)候觸發(fā)。
dragleave 拖動(dòng)時(shí)鼠標(biāo)離開某個(gè)元素的時(shí)候觸發(fā)。
drag 對象被拖拽時(shí)每次鼠標(biāo)移動(dòng)都會(huì)觸發(fā)。
drop 拖動(dòng)操作結(jié)束,放置元素時(shí)觸發(fā)。
dragend 拖動(dòng)對象時(shí)用戶釋放鼠標(biāo)按鍵的時(shí)候觸發(fā)。

另外在拖拽進(jìn)程中是不觸發(fā)鼠標(biāo)事件的。文件讀取完后文件信息會(huì)保存在 DataTransfer 對象中。詳細(xì)的介紹可以參考 這里 。下面是添加事件的示例

fileSelect.addEventListener("dragenter", dragMdEnter, false);
fileSelect.addEventListener("dragleave", dragMdLeave, false);
fileSelect.addEventListener('drop', dropMdFile, false);

讀取拖拽的文件

function dropMdFile(e) {
    // 取消閱讀器默許行動(dòng)
    e.stopPropagation();
    e.preventDefault();
    var reader = new FileReader();
    reader.readAsText(e.dataTransfer.files[0]);
    reader.onload = function (e) {
        var content = e.target.result;
        //......
    };
}

本地圖片顯示

由于沒有服務(wù)器,所以為了顯示本地圖片,使用了替換圖片 src 的方式。首先讀取本地文件,然后將 <img>src 路徑替換為圖片內(nèi)容 。以下所示:

<img src="path">
// 替換為
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgI...">

下面是具體的代碼實(shí)現(xiàn):

// 讀取選擇或拖拽的文件(多個(gè)文件)
function processImages(imgFiles) {
   var index = 0;
    for (i = 0; i < imgFiles.length; i++) {
        var file = imgFiles[i];
        var reader = new FileReader();
        reader.readAsDataURL(file);
        (function (reader, file) {
            reader.onload = function (e) {
                cacheImages[file.name] = e.target.result;
                index++;
                if (index == length) {
                    replaceImage();
                }
            }
        })(reader, file);
    }
}

// 將路徑替換為圖片內(nèi)容
function replaceImage() {
    var images = $("img");
    var i;
    for (i = 0; i < images.length; i++) {
        var imgSrc = images[i].src;
        var imgName = getImgName(imgSrc);
        if (cacheImages.hasOwnProperty(imgName)) {
            images[i].src = cacheImages[imgName];
        }
    }
}

如果圖片過大,我們可以將圖片緊縮1下,具體方法就是創(chuàng)建1個(gè) canvas 元素,將圖片繪制到 canvas 上,然后將 canvas 轉(zhuǎn)為圖片。這類方式對 jpg 文件緊縮效果較好,對 png 文件緊縮效果不太好。下面是代碼實(shí)現(xiàn):

function compressImage(img, format) {
    var max_width = 862;
    var canvas = document.createElement('canvas');

    var width = img.width;
    var height = img.height;
    if (format == null || format == "") {
        format = "image/png";
    }

    if (width > max_width) {
        height = Math.round(height *= max_width / width);
        width = max_width;
    }

    // resize the canvas and draw the image data into it
    canvas.width = width;
    canvas.height = height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, width, height);
    return canvas.toDataURL(format);
}

循環(huán)中使用異步回調(diào)函數(shù)

為了方便使用,我們可以同時(shí)上傳多個(gè)圖片,我們使用 for 循環(huán)來讀取多個(gè)文件,但是有個(gè)問題是文件的讀取是異步的,也就是說在 for 循環(huán)履行完以后,圖片可能仍在讀取中,當(dāng)圖片讀取完后,再調(diào)用 onload 回調(diào)函數(shù)進(jìn)行處理。簡單1點(diǎn)就是說如何在 for 循環(huán)中正確使用延遲調(diào)用的回調(diào)函數(shù)。看下面的例子:

function print(value, callback) {
    console.log("value in print", value);
    setTimeout(callback, 1000);
}

for(var i = 0; i < 4; i++) {
    var value = i;
    print(value, function() {
        console.log("value in callback", value);
    });
}

上面打的代碼和我們讀取圖片文件的邏輯類似,callback 函數(shù)會(huì)在調(diào)用 print 函數(shù)1秒后履行,下面是輸出結(jié)果

value in print 0
value in print 1
value in print 2
value in print 3
value in callback 3
value in callback 3
value in callback 3
value in callback 3

最后在 callbackvalue 值都是3,這是由于在 js 中沒有塊級(jí)作用域,只有函數(shù)作用域,也就是說下面的兩段代碼是同等的:

for(var i = 0; i < 4; i++) {
    var value = i;
    // do someting
}
// 同等于
var value;
for(var i = 0; i < 4; i++) {
    value = i;
    // do someting
}

因此,為了解決這個(gè)問題,我們只需要為循環(huán)中的回調(diào)函數(shù)添加1個(gè)單獨(dú)的作用域便可,我們使用閉包來實(shí)現(xiàn):

for(var i = 0; i < 4; i++) {
    var value = i;
    (function(value) {
        print(value, function() {
            console.log("value in callback", value);
        });
    }(value));
}

代碼高亮

我們使用兩款代碼高亮插件 – highlight.js 和 prism.js,根據(jù)喜好可以自由切換。這兩款插件對代碼塊的 html 格式有不同的要求,我們重寫了 marked 中解析代碼塊的方法,根據(jù)高亮方式來生成不同的 html 代碼:

renderer.code = function (code, lang) {
    if (Setting.highlight == Constants.highlight) {
        return "<pre><code class='" + lang + "'>" + code + "</code></pre>";
    }
    return "<pre><code class='language-" + lang + "'>" + code + "</code></pre>";
};

然后調(diào)用 highlight.js 和 prism.js 的代碼高亮方法便可

if (Setting.highlight == Constants.highlight) {
    $('pre code').each(function (i, block) {
        hljs.highlightBlock(block);
    });
} else {
    // 添加行號(hào)支持
    $("pre").addClass("line-numbers");
    Prism.highlightAll();
}

目錄

為了生成文件的目錄,我們需要首先取得目錄信息,因此我們重寫 markedheading 方法, 將目錄信息保存起來,同時(shí)為每一個(gè)標(biāo)題添加鏈接圖標(biāo)(仿照 github),下面是代碼:

renderer.heading = function (text, level) {
    var slug = text.toLowerCase().replace(/[\s]+/g, '-');
    if (tocStr.indexOf(slug) != -1) {
        slug += "-" + tocDumpIndex;
        tocDumpIndex++;
    }

    tocStr += slug;
    toc.push({
        level: level,
        slug: slug,
        title: text
    });

    return "<h" + level + " id=\"" + slug + "\"><a href=\"#" + slug + "\" class=\"anchor\">" + '' +
        '<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c⑴.5 0⑶⑴.69⑶⑶.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72⑵ 3.25V8.59c.58-.45 1⑴.27 1⑵.09C10 5.22 8.98 4 8 4H4c-.98 0⑵ 1.22⑵ 2.5S3 9 4 9zm9⑶h⑴v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0⑵⑴.22⑵⑵.5 0-.83.42⑴.64 1⑵.09V6.25c⑴.09.53⑵ 1.84⑵ 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3⑴.69 3⑶.5S14.5 6 13 6z"></path></svg>' +
        '' + "</a>" + text + "</h" + level + ">";
};

同時(shí)需要加入下面的 css,以是標(biāo)題的鏈接圖片正常顯示:

h1:hover .anchor, h2:hover .anchor, h3:hover .anchor, h4:hover .anchor, h5:hover .anchor, h6:hover .anchor {
    text-decoration: none
}

h1:hover .anchor .octicon-link, h2:hover .anchor .octicon-link, h3:hover .anchor .octicon-link, h4:hover .anchor .octicon-link, h5:hover .anchor .octicon-link, h6:hover .anchor .octicon-link {
    visibility: visible
}

.octicon {
    display: inline-block;
    vertical-align: text-top;
    fill: currentColor;
}

.anchor {
    float: left;
    padding-right: 4px;
    margin-left: -20px;
    line-height: 1;
}

為了生成目錄,我們只需依照保存的目錄信息,生成 <ul><li> 標(biāo)簽便可,具體的可以參考源碼中的實(shí)現(xiàn)。

配置頁面錨鏈接

目錄使用的是頁內(nèi)錨鏈接的方式進(jìn)行跳轉(zhuǎn),以下面所示:

<a href="#h1">跳轉(zhuǎn)到 H1</a>
...
<h1 id="h1">我是 H1</h1>
...

默許情況下,頁內(nèi)錨鏈接跳轉(zhuǎn)以后,目標(biāo)標(biāo)簽(上面代碼中的 <h1> )會(huì)移動(dòng)到頁面的最頂部,但是在我們的程序中有1個(gè)固定的 header,如果跳轉(zhuǎn)到最頂部,目標(biāo)標(biāo)簽會(huì)被 header 遮擋住,所以我們希望目標(biāo)標(biāo)簽移動(dòng)到距離頁面頂部 header-height 的地方。為了實(shí)現(xiàn)我們的需要,只要加入下面的 css 代碼便可。

:target:before {
    content:"";
    display:block;
    height:50px; /* fixed header height*/
    margin:-50px 0 0; /* negative fixed header height */
}

Todo 列表

Todo 列表實(shí)際上就是 checkbox 的列表,完成的工作用選中的 checkbox 表示,未完成的工作用喂選中的列表表示,以下圖所示:

1般來講,會(huì)將下面情勢的 markdown 代碼解析為 todo 列表

- [x] 完成
- [ ] 未完成
- [ ] 未完成

為了實(shí)現(xiàn)這個(gè)功能,我們重寫 marked 中解析列表的方法,加入對 todo 列表的支持。

renderer.listitem = function (text) {
    if (/^\s*\[[x ]\]\s*/.test(text)) {
        text = text
            .replace(/^\s*\[ \]\s*/, '<input type="checkbox" class="task-list-item-checkbox" disabled> ')
            .replace(/^\s*\[x\]\s*/, '<input type="checkbox" class="task-list-item-checkbox" disabled checked> ');
        return '<li style="list-style: none">' + text + '</li>';
    } else {
        return '<li>' + text + '</li>';
    }
};

同時(shí)加入下面的樣式:

.task-list-item-checkbox {
    margin: 0 0.2em 0.25em -2.3em;
    vertical-align: middle;
}

[type="checkbox"], [type="radio"] {
    box-sizing: border-box;
    padding: 0;
}

緩存

現(xiàn)在的閱讀器都已支持 localStorage,可以方便的存儲(chǔ)數(shù)據(jù)。localStorage 就是1個(gè)對象。我們存儲(chǔ)數(shù)據(jù)就是直接給它添加1個(gè)屬性,可以通過 localStoage["a"]=1localStorage.a = 1 的方式來存儲(chǔ)數(shù)據(jù),但是看起來總覺的不太優(yōu)雅,由于1般使用下面的方式來操作 localStorage

localStorage.setItem(key, vlaue);
localStorage.getItem(key);
localStorage.removeItem(key);

另外 localStorage 也有1些局限,使用時(shí)需要注意:

  • 存儲(chǔ)空間有限制,1般是 5M 左右,和閱讀器有關(guān)
  • 用戶清除閱讀器緩存以后有可能丟失本地緩存的數(shù)據(jù)
  • 不能直接存對象,要先使用 JSON.stringfy 方法將對象進(jìn)行序列化處理以后再保存。使用時(shí)需要使用 JSON.parse 方法將字符串轉(zhuǎn)為對象。

導(dǎo)出文件

通過使用 FileSaver.js,我們可以方便的在閱讀器端生成文件,并提供給用戶下載。使用方法也很簡單:

var blob = new Blob([htmlContent], {type: "text/html;charset=utf⑻"});
saveAs(blob, name);

擴(kuò)大

我們提供了1些擴(kuò)大功能,用來更好的展現(xiàn) markdown 內(nèi)容。在現(xiàn)在的程序中我們可以很方便的添加擴(kuò)大功能,下面會(huì)具體介紹。

自定義擴(kuò)大

為了添加擴(kuò)大,我們首先需要肯定哪些內(nèi)容需要作為擴(kuò)大處理。由于在將 markdown 文件轉(zhuǎn)為 html 的進(jìn)程中,1般是不處理代碼塊中的內(nèi)容的,所以我們使用代碼塊來寄存擴(kuò)大內(nèi)容,通過代碼塊的語言來肯定是哪一種擴(kuò)大。以添加序列圖擴(kuò)大為例:

  • 肯定時(shí)序圖的代碼標(biāo)記

  • 修改 marked 中對代碼塊的解析函數(shù),添加對時(shí)序圖標(biāo)記的支持

var renderer = new marked.Renderer();
var originalCodeFun = function (code, lang) {
    if (Setting.highlight == Constants.highlight) {
        return "<pre><code class='" + lang + "'>" + code + "</code></pre>";
    }
    return "<pre><code class='language-" + lang + "'>" + code + "</code></pre>";
};
renderer.code = function (code, language) {
    if (language == "seq") {
        return "<div class='diagram' id='diagram'>" + code + "</div>"
    } else {
        return originalCodeFun.call(this, code, language);
    }
};
marked.setOptions({
    renderer: renderer
});
  • 引入 js-sequence-diagrams 相干文件
<link href="{{ bower directory }}/js-sequence-diagrams/dist/sequence-diagram-min.css" rel="stylesheet" />
<script src="{{ bower directory }}/bower-webfontloader/webfont.js" />
<script src="{{ bower directory }}/snap.svg/dist/snap.svg-min.js" />
<script src="{{ bower directory }}/underscore/underscore-min.js" />
<script src="{{ bower directory }}/js-sequence-diagrams/dist/sequence-diagram-min.js" />
  • 渲染 Markdown 文件時(shí),調(diào)用相干函數(shù)
$(".diagram").sequenceDiagram({theme: 'simple'});

添加擴(kuò)大會(huì)影響文件的渲染速度,如果不需要某個(gè)擴(kuò)大可以手動(dòng)關(guān)閉。

Mathjax

使用Mathjax 對數(shù)學(xué)公式進(jìn)行支持。關(guān)于Mathjax 語法,請參考這里。下面是添加擴(kuò)大的流程:

  • 引入文件并配置
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]},
    TeX: {
      equationNumbers: {
        autoNumber: ["AMS"],
        useLabelIds: true
      }
    },
    "HTML-CSS": {
      linebreaks: {
        automatic: true
      }
    },
    SVG: {
      linebreaks: {
        automatic: true
      }
    }
  });
</script>
<script type="text/javascript" src="http://cdn.bootcss.com/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
  • 將 markdown 文件轉(zhuǎn)為 html 以后,調(diào)用 Mathjax 中的方法將對應(yīng)標(biāo)記轉(zhuǎn)為數(shù)學(xué)公式。
// content 是需要處理的 html 標(biāo)簽的 id
MathJax.Hub.Queue(["Typeset", MathJax.Hub, "content"]);

Emoji

使用 emojify.js 來提供對 Emoji 標(biāo)簽的支持。Emoji表情參見 EMOJI CHEAT SHEET。下面是添加擴(kuò)大的流程

  • 援用文件并配置
<script src="http://cdn.bootcss.com/emojify.js/1.1.0/js/emojify.min.js"></script>
<script type="text/javascript">
    emojify.setConfig({
        emojify_tag_type: 'div',           // Only run emojify.js on this element
        only_crawl_id: null,            // Use to restrict where emojify.js applies
        img_dir: 'http://cdn.bootcss.com/emojify.js/1.0/images/basic',  // Directory for emoji images
        ignored_tags: {                // Ignore the following tags
            'SCRIPT': 1,
            'TEXTAREA': 1,
            'A': 1,
            'PRE': 1,
            'CODE': 1
        }
    });
</script>
  • 將 markdown 文件轉(zhuǎn)為 html 以后,調(diào)用 emojify 中的方法將對應(yīng)標(biāo)記轉(zhuǎn)換 emoji 表情。
 emojify.run(document.getElementById('content'))

圖表 (ECharts)

使用 ECharts 來提供對圖表的支持。ECharts 的語法可以參考 官網(wǎng)的示例。下面是使用方法:

  • 肯定 ECharts 在 markdown 中的語法標(biāo)簽

  • 在 code 方法解析中添加對 echarts 的支持

renderer.code = function (code, language) {
    switch (language) {
        case "echarts":
            if (Setting.echarts) {
                return loadEcharts(code);
            }
            return originalCodeFun.call(this, code, language);
    }
};
function loadEcharts(text) {
    var width = "100%";
    var height = "400px";
    try {
        var options = eval("(" + text + ")");
        if (options.hasOwnProperty("width")) {
            width = options["width"];
        }
        if (options.hasOwnProperty("height")) {
            height = options["height"];
        }
        echartIndex++;
        echartData.push({
            id: echartIndex,
            option: options,
            previousOption: text
        });
        return '<div id="echarts-' + echartIndex + '" style="width: ' + width + ';height:' + height + ';"></div>'
    } catch (e) {
        console.log(e);
        return "";
    }
}
  • 將 markdown 文件轉(zhuǎn)為 html 以后,調(diào)用 echarts 中的方法,將對應(yīng)的 div 轉(zhuǎn)為圖表:
var chart;
echartData.forEach(function (data) {
    if (data.option.theme) {
        chart = echarts.init(document.getElementById('echarts-' + data.id), data.option.theme);
    } else {
        chart = echarts.init(document.getElementById('echarts-' + data.id));
    }
    chart.setOption(data.option);
});

評(píng)論

在生成Github Page頁面時(shí),我們可以選擇添加 多說 或 Disqus 評(píng)論,其中多說就是在導(dǎo)出的頁面中加入下面的代碼

<div class="ds-thread" data-thread-key="" data-title="" data-url=""></div>
<script type="text/javascript">
    var duoshuoQuery = {
        short_name: ""
    };
    (function() {
        var ds = document.createElement("script");
        ds.type = "text/javascript";
        ds.async = true;
        ds.src = (document.location.protocol == "https:" ? "https:" : "http:") + "http://static.duoshuo.com/embed.js";
        ds.charset = "UTF⑻";
        (document.getElementsByTagName("head")[0] || document.getElementsByTagName("body")[0]).appendChild(ds);
    })();
</script>

其中 data-thread-key, data-title, data-urlshort_name 是需要我們自定義的東西。而Disqus 需要在導(dǎo)出時(shí)插入下面的代碼:

<div id="disqus_thread"></div>
<script type="text/javascript">
    var disqus_shortname = '';
    var prefix = document.location.protocol == "https:" ? "https:" : "http:"
    var disqus_config = function() {
        this.page.url = "";
        this.page.identifier = ""
    };
    (function() {
        var d = document,
                s = d.createElement('script');
        s.src = prefix + '//' + disqus_shortname + '.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    })();
</script>

其中 disqus_shortname, page.urlpage.indertifier 是需要我們自定義的東西。這里需要注意的是 page.url 要使用絕對路徑。

具體的插入邏輯可參考源碼的實(shí)現(xiàn),這里不再贅述。

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 亚洲视频在线看 | 亚洲日本1区2区3区二区 | 成人卡通精品卡通动漫第一页 | 久久久久久久久一次 | 大学生一级毛片高清版 | 亚洲高清成人欧美动作片 | 亚洲国产精品欧美综合 | 波多野野结衣1区二区 | 国产精品系列在线一区 | 国产免费a v吧在线观看不卡 | 免费又黄又爽又猛大片午夜 | 99久久精品国产麻豆 | 亚洲精品456在线观看 | 多人伦交性欧美精品欧 | 最新日本一级中文字幕 | 亚州免费视频 | 国产玖玖在线 | free13俄罗斯性xxxxhd | 国产成人精品一区二三区2022 | 国产精品第1页在线观看 | 欧美最猛黑人xxxx | 国产免费久久精品 | 99久久精品毛片免费播放 | xxnx日本免费护士 | 全网免费在线播放视频入口 | 国产一区欧美 | 亚洲免费观看视频 | 日本xxwwwxxxx18| 精品视频网站 | 天堂欧美 | 97久久影院 | 亚洲成人黄色片 | 亚洲天堂手机在线 | 欧美精品一国产成人性影视 | 黑人xxxx日本| 7777精品伊人久久久大香线蕉 | 国产精品60岁老女人 | 日韩高清免费观看 | 国产产一区二区三区久久毛片国语 | 日本午夜精品一本在线观看 | 国产91精品一区二区 |