Epub PC阅读器找了一圈,发现最舒服的是微信读书

Calibre Viewer,SumatraPDF,还有国产的几个阅读器,
github 上 star 上千的也看了一遍,基本都是 electron,qt,
还有基于 epub.js 搞的纯网页阅读器,试了一圈都不太满意
最后想起来微信读书似乎可以自己传书了,就试了一下,发现真不错

不过欲扬先抑,先来说说缺点吧:

  • 有网才能用
  • 登录需要扫码
  • 隐私没有保障
  • 排版样式丢失,会变成微信阅读的样式

再来说说优点:

  • 常见的电子书格式都支持,txt,epub,pdf,mobi。。。
  • 可以加书签,高亮,做笔记,搜索全书
  • 云同步,电脑、平板、手机无缝衔接(这个是真的爽 :laughing:
  • 纯网页,无需安装,还能用css,油猴脚本增强阅读体验
  • 自带丰富的电子书资源
  • 免费(当然如果看里面的付费书还是得充钱的

最后分享一下我自己用的油猴脚本:

// ==UserScript==
// @name         微信读书优化整合
// @version      0.3
// @namespace    whatever
// @description  修改字体,更改背景颜色,增减页面宽度,上划隐藏头部侧栏,代码复制与图片下载
// @contributor  SimonDW;Li_MIxdown;hubzy;xvusrmqj;LossJ;JackieZheng;das2m;harmonyLife
// @author       greasy-su
// @match        https://weread.qq.com/web/reader/*
// @icon         https://weread.qq.com/favicon.ico
// @grant        GM_addStyle
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_setClipboard
// ==/UserScript==

// 参考:https://greasyfork.org/zh-CN/scripts/421994-%E5%BE%AE%E4%BF%A1%E8%AF%BB%E4%B9%A6%E7%BD%91%E9%A1%B5%E7%89%88%E5%8A%9F%E8%83%BD%E7%BB%BC%E5%90%88
// 移除 jquery 依赖与一些个人不需要的功能

'use strict';
// 自动隐藏标题栏
const autoHideTopbar = false;
// 字体
const font = "微软雅黑";
// 字体大小
const fontSize = "15px";
// 字体粗细
const fontWeight = "400"
// 字体颜色
const fontColor = "#233";
// 代码字体
const codeFont = "consolas";
// 代码字体大小
const codeFontSize = "14px";
// 代码字体颜色
const codeFontColor = "#233";
// 网页背景
const bodyBg = "#e0d9c6";
// 标题栏背景
const topBarBg = "#d0c9b6";
// 正文背景
const contentBg = "#faf0e4";

const maxWaitTime = 3000;

const $ = s=>document.querySelector(s);
const $$ = s=>document.querySelectorAll(s);

const style = `
    *{
        font-family: "${font}" !important;
        font-size: ${fontSize} !important;
        font-weight: ${fontWeight} !important;
    }
    pre,
    code{
        font-family: "${codeFont}", "${font}" !important;
        font-size: ${codeFontSize}!important;
        color: ${codeFontColor}!important;
    }
    .readerCatalog,
    .readerNotePanel{
        right: 0 !important;
        left: unset !important;
    }
    .readerTopBar{
        height: unset !important;
    }
    .readerTopBar,
    .bookInfo_title,
    .readerTopBar_title_link,
    .readerTopBar_title_chapter{
        font-family: SourceHanSerifCN-Bold !important;
    }
    .readerTopBar_title_link{
        font-weight:bold !important;
    }
    body.wr_whiteTheme{
        background-color: ${bodyBg} !important;
    }
    .wr_whiteTheme .readerTopBar{
        background-color: ${topBarBg} !important;
    }
    .wr_whiteTheme .renderTargetContainer .renderTargetContent .wr_readerImage_opacity,
    .wr_whiteTheme .renderTargetContainer .renderTargetContent .wr_readerBackground_opacity,
    .wr_whiteTheme .readerContent .app_content {
        background-color:  ${contentBg}!important;
    }
    .wr_whiteTheme .app_content{
        box-shadow: 0 0 3px 1px #8888;
    }
    .readerChapterContent{
        color:  ${fontColor}!important;
    }
    .readerControls{
        margin-left: 25% !important;
        padding-left: 20%;
        margin-bottom: -28px !important;
    }
    .readerControls{
        opacity: 0;
        transition-delay: 1s;
    }
    .readerControls:hover{
        opacity: 1;
        transition-delay: 0s;
    }
    button.readerControls_item,
    div.readerControls_fontSize{
        cursor: pointer!important;
        box-shadow: 0 0 5px 1px #8888!important;
    }
    .readerControls_item.download{
        display: none;
    }
`;

GM_addStyle(style);

window.onload = function(){
    function getElmAync(selector){
        return new Promise(resolve=>{
            let t = maxWaitTime;
            const gap = 100;
            const itv = setInterval(()=>{
                t -= gap;
                let elm = $$(selector);
                if(elm.length > 0){
                    clearInterval(itv);
                    resolve(elm);
                }
                if(t <= 0){
                    clearInterval(itv);
                    resolve(null);
                }
            }, gap);
        });
    }

    // add btn to pre
    async function addCopyBtn(){
        let preCollection = await getElmAync('pre');
        let hasBtn = $('.copy-btn') ? true : false;
        let btnHtml = `<button class="copy-code" style="position: absolute;right: 0;top: 0;color:white;cursor:pointer;z-index:99999;">📋</button>`;

        if(preCollection !== null && !hasBtn){
            for(let pre of preCollection){
                pre.innerHTML += btnHtml;
            }
        }
    }
  
    addCopyBtn();
    const observer = new MutationObserver(addCopyBtn);
    const appContent = $('.app_content');
    observer.observe(appContent, {childList: true});

    document.body.addEventListener('click', ev=>{
        console.log(ev.target);
        if(ev.target.classList.contains('copy-code')){
            let code = ev.target.parentElement.textContent.replace('📋', '');
            GM_setClipboard(code);
            alert('code copied.');
        }
    });

// change page width
    function getCurrentMaxWidth(element) {
        let currentValue = window.getComputedStyle(element).maxWidth;
        currentValue = currentValue.substring(0, currentValue.indexOf('px'));
        currentValue = parseInt(currentValue);
        return currentValue;
    }

    function setWidth(width) {
        const item1 = $(".readerContent .app_content");
        const item2 = $('.readerTopBar');
        item1.style['max-width'] = width + 'px';
        item2.style['max-width'] = width + 'px';
        const myEvent = new Event('resize');
        window.dispatchEvent(myEvent);
        // fix: btn disappear after resizing
        setTimeout(addCopyBtn, 3000);
    }
  
    function addWidth(increment){
        const width = getCurrentMaxWidth($('.readerContent .app_content')) + increment;
        setWidth(width);
        GM_setValue('width', width);
    }
    
    let btnHTML = `
        <button class="readerControls_item widthIncrease" style="color:#6a6c6c;cursor:pointer;">宽</button>
        <button class="readerControls_item widthDecrease" style="color:#6a6c6c;cursor:pointer;">窄</button>
    `;
    let btnContainer = document.createElement('div');
    btnContainer.innerHTML = btnHTML;
    $('.readerControls').append(btnContainer.children[0], btnContainer.children[1]);
    $('.widthIncrease').addEventListener('click', () => addWidth(100));
    $('.widthDecrease').addEventListener('click', () => addWidth(-100));
  
    let width = GM_getValue('width', -1);
    if(width !== -1){
        setWidth(width);
    }


// auto hide topbar
    if(autoHideTopbar){
        let prevPos = 0;
        let topBar = $('.readerTopBar');
        let timer = -1;
        window.addEventListener('scroll', ev=>{
            if(timer !== -1) return;
            timer = setTimeout(()=>{
                let pos = document.documentElement.scrollTop || document.body.scrollTop;
                topBar.style.opacity = pos > prevPos ? '0' : '1';
                prevPos = pos;
                timer = -1;
            }, 300);
        });
    }

}
2 Likes

阅读不好用?

楼主可有试过Neat Reader
除了支持格式没那么多,书源要自己解决,其他应该不比微信读书差吧。

pc用不了,同步麻烦

试过,免费版限制太多了

微信读书确实好用,有些书走路时看我就会导入到微信读书,全平台同步是真的香,导入书籍在手机版就可以离线阅读,唯一槽点就是导出批注不好用,只支持复制到剪贴板

当时也是找了一圈,体验比较好的是neatreader,但是免费版限制太多。后来用过一段时间开源的koodoo reader,这个阅读器功能不少,但是目前而言使用体验不太好,bug挺多,后入了电纸书就放弃电脑阅读epub了

1 Like

epub…本来就是网页套壳, 用浏览器看, 也算是回归本心了…
epub的友好程度, 仅次于cbz了(就我用过的而言).
但还是没有什么好用的阅读器, 反正我是有过直接解压出来用浏览器/Word看.
Calibre的书籍管理+Sigil的编辑+Adobe Reader的阅读注释, 应该就几乎足够用了, 可惜没有.
鉴于docx之类也几乎是网页套壳了, 或许可以指望各种Office套件开发者良心爆棚支持epub?

电脑端还是习惯用Calibre很多年了,手机端自从有了kindle就再也不在手机上看书了,有些费眼。

@Landius @Sepaer 其实个人觉得在订阅制盛行的当下,Neat Reader有终身版还算良心。相比年费,终身版不觉得太贵,反倒是不知道它能做多久了。

前段时间有人推荐justread嘛,除了大,挺好的。

windows的话,我有用京东读书。这玩意有windows版本就离谱,可以导入本地文件,不过我就偶尔拿来看看轻小说,不是重度用户。

还没发现哪个脚本能实现首行缩进的。