在onClick,javascript上取消流

时间:2017-04-04 17:32:13

标签: javascript html css node.js onclick

我想做的事情背后的想法是,一旦我再次运行相同的功能,但是使用不同的参数,打破/完成一个功能。

现在我有一个随机字符流被发送到端点。

类获取此端点并允许流填充内容视图。

我有一个标签,每次点击它都会调用此填充函数。

我希望这样当我单击另一个选项卡或相同的选项卡时,该功能结束,停止使用前面的参数,然后使用新参数再次运行该功能。如果点击相同的标签,它就什么都不做。

下面我有HTML主体,CSS,客户端的JS脚本以及发送流的node.js服务器端。你应该能够或多或少地复制粘贴它,它将运行。

不要忘记为节点安装npm。只需运行节点代码即可启动服务器。

HTML:

<div class="tab-bar">
        <button class="tab" onclick="getStreamNContentLocale('stream_1')">London</button>
        <button class="tab" onclick="getStreamNContentLocale('stream_2')">Paris</button>
        <button class="tab" onclick="getStreamNContentLocale('stream_3')">Tokyo</button>
    </div>
    <div class="content">
        <div id="stream_1">
        </div>
        <div id="stream_2">
        </div>
        <div id="stream_3">
        </div>
    </div>
    <script src="js/index.js"></script>

CSS:

.tab-bar {
    height: 40px;
    width: 100%;
    background-color: black;
}

.tab {
    color: white;
    font-size: 100%;
    float: left;
    padding: 9px 16px;
    vertical-align: middle;
    background-color: inherit;
}

.content {
    border: 1px solid #ccc;
    overflow: auto;
    height: 200px;
    width: 100%;
}

JS:

console.log((new Date()).toLocaleString());

function getStreamNContentLocale(contentID) {
    let xhr = new XMLHttpRequest(),
        streamArray = [],
        snapshotsSent = 0;

    xhr.open('GET', `/stream`);
    xhr.seenBytes = 0;
    xhr.onreadystatechange = () => {
        if (xhr.readyState > 2) {
            if (snapshotsSent < 30) {
                streamArray.push("Snapshot sent " + (new Date()).toLocaleString() + "\n" + xhr.responseText.substring(xhr.seenBytes, xhr.responseText.length));
                document.querySelector(`#${contentID}`).innerText = streamArray;
            } else if (snapshotsSent >= 30) {
                streamArray.shift();
                streamArray.push("Snapshot sent " + (new Date()).toLocaleString() + "\n" + xhr.responseText.substring(xhr.seenBytes, xhr.responseText.length));
                document.querySelector(`#${contentID}`).innerText = streamArray;
            }
            xhr.seenBytes = xhr.responseText.length;
        }
        snapshotsSent++;
        /**********************************************************************************************
         * xhr.responseText.substring(xhr.seenBytes, xhr.responseText.length) is each snapshot we GET *
         * snapshotsSent is the number of snapshots we have actually gotten so far in this session    *
         **********************************************************************************************/
    };
    xhr.send();
}

服务器

let express = require('express'),
    app = express(),
    bodyParser = require('body-parser'),
    path = require('path');

init(function() {
        callback(null);
    });

function init(callback) {
    app.use(bodyParser.json());

    app.use(bodyParser.urlencoded({
        extended: true
    }));

    app.use(express.static(path.join(__dirname, "../../views")));

    app.get('/', function(req, res) {
        res.sendFile(path.join(__dirname, "../../views/index.html"));
    });

    app.get('/stream', (req, res) => {
        console.log('sending stream to /stream');
        setInterval(() => {
            res.write(Math.random(16).toString(36).substring(2) + "\n");
        }, 200);
    });

    app.listen(8000, () => {
        console.log("Listening on port 8000");
    });

    callback();
}

1 个答案:

答案 0 :(得分:1)

您可以将XMLHttpRequest xhr存储在函数本身中,并在每次运行该函数时中止它。像这样(在你的JS文件中):

function getStreamNContentLocale(contentID) {

    if( getStreamNContentLocale.xhr !== undefined)
        getStreamNContentLocale.xhr.abort();

    getStreamNContentLocale.xhr = new XMLHttpRequest(),
        streamArray = [],
        snapshotsSent = 0;

    // the rest of your code goes here
}

请参阅abort()方法:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort

编辑:还在回调中添加getStreamNContentLocale.xhr = undefined;,否则在中止完成的请求时可能会返回错误。