Mirror site is read only www.netnr.com
netnr/ barrage.js 2019-06-06 00:10
弹幕,斗鱼弹幕临时解决方案
/*
 *  barrage 弹幕
 *  
 *  2019-06
 *  netnr
 */

(function (window) {

    var bar = function (obj) {
        return new bar.fn.init(obj);
    }

    bar.fn = bar.prototype = {
        init: function (obj) {
            //覆盖默认配置
            for (var k in obj) {
                this.config[k] = obj[k];
            }
            //容器ID兼容
            if (typeof this.config.element == "string") {
                this.config.element = document.getElementById(this.config.element)
            }
            this.ready();
            return this;
        },
        //默认配置
        config: {
            //弹幕容器
            element: null,
            //弹幕框,自动创建
            bbox: null,
            //弹幕宽度,默认自动获取
            width: null,
            //弹幕高度,默认自动获取
            height: null,
            //弹幕大小
            size: "2.5rem",
            //一行弹幕高度,像素
            rowheight: 50,
            //不透明度,0-1
            opacity: .7,
            //弹幕显示时长,秒
            time: 10,
            //Z轴高度
            zindex: 1
        },
        //准备
        ready: function () {
            var bbox = this.config.bbox = document.createElement("div");
            bbox.style.position = "absolute";
            bbox.style.color = "white";
            bbox.style.fontSize = this.config.size;
            bbox.style.width = (this.config.width || this.config.element.offsetWidth) + "px";
            bbox.style.height = (this.config.height || (this.config.element.offsetHeight - 250)) + "px";
            bbox.style.opacity = this.config.opacity;
            bbox.style.zIndex = this.config.zindex;
            this.config.element.appendChild(bbox);
        },
        //添加弹幕
        add: function (msg, css) {
            var bnode = document.createElement('span');
            bnode.innerText = msg;
            bnode.style.cssText = css;
            this.config.bbox.appendChild(bnode);
            return bnode;
        }
    }

    bar.fn.init.prototype = bar.fn;

    window.barrage = bar;
})(window);

/**
 * 斗鱼
 * */
barrage.douyu = function () {
    var ba = barrage({
        //弹幕容器
        element: "douyu_room_normal_player_proxy_box"
    });
    //已发送的消息id
    var arrid = [],
        //间隔时间获取弹幕,毫秒
        gettime = 300,
        //弹幕最大行数
        bmaxrow = Math.floor(ba.config.bbox.style.height.replace("px", "") / ba.config.rowheight),
        //当前行数
        crow = 0;

    ba.si = setInterval(function () {
        //根据行数取最新消息数量,忽略多余的弹幕
        var lis = document.getElementById('js-barrage-list').children, len = lis.length, si = Math.max(0, len - bmaxrow);
        for (var i = si; i < len; i++) {
            var li = lis[i];
            //新消息
            if (arrid.indexOf(li.id) == -1) {
                //清理已发送超出的记录
                if (arrid.length > 200) {
                    arrid.splice(arrid.length - 1, 1);
                }
                arrid.push(li.id);
                ba.arrid = arrid;
                //读取弹幕内容
                var sps = li.getElementsByTagName('span');
                var msg = sps[sps.length - 1].innerText;
                //添加弹幕
                var bnode = ba.add(msg, "position:absolute;left:" + ba.config.bbox.style.width + ";transition:left " + ba.config.time + "s linear;top:" + (crow * ba.config.rowheight) + "px;white-space:nowrap;");
                crow++ >= bmaxrow && (crow = 0);
                bnode.style.left = -1 * bnode.offsetWidth + "px";
                //记录滚动开始时间
                bnode.start = new Date().valueOf();
            }
        }
        //清理滚动结束的弹幕
        var clis = ba.config.bbox.children;
        for (var i = 0; i < clis.length; i++) {
            var li = clis[i];
            if (new Date().valueOf() - li.start > ba.config.time * 1000) {
                ba.config.bbox.removeChild(li);
            }
        }
    }, gettime)

    //弹幕容器自适应
    document.body.onresize = function () {
        ba.config.element.removeChild(ba.config.bbox);
        ba.ready();
    };

    return ba;
}
var douyu = barrage.douyu();