js的WebSocket的onmessage方法遇到jquery的奇怪现象

目的是不断读取后台tomcat的日志,为了性能,jquery对象提早用全局变量记录好了。
但是发觉在onmessage方法里,操作该对象,F12调试里看到div的html内容都正常,但是界面没有实际效果。
非要直接写jquery对象才可以,用不了全局的定义。

请大伙直接看注释部分↓

<div id="app">
    <div id="log-container" style="height: 650px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;">
        <div>
        </div>
    </div>
</div>
<script>
    let a=1;
    let $div = $("#log-container div").eq(0);
    let $container = $("#log-container");
    let vm = new Vue({
        el: '#app',
        data: {
            ws: null,
            webHost: window.location.host
        },
        created() {
            this.ws = new WebSocket('ws://' + this.webHost + '/log');
            $div.append('1'); // 成功
            this.ws.onmessage = function (event) {
                ++a; // 成功
                $div.html(a); // 无效果
                $container.scrollTop($div.height() - $container.height()); // 成功
            };

            this.ws.onerror = function (evt) {
                alert("出错啦");
            };
        },
        methods: {}
    });
</script>
阅读 5.9k
3 个回答

次序是这样的。先获取了$div,$container
然后new Vue->$app.html('') 然后$div和$containner就变成了已经销毁或者说游离的dom元素了。你再去设置就已经不在body里面了。
所以你需要重新获取。这个时机当然就是在新的dom被挂在在$app的时候。

是不是因为vue重写了#app里面的dom元素。你之前取的div和之后的不是一个div。写个mounted方法试试就知道了
看样子是没听懂。代码给你改下

<div id="app">
    <div id="log-container" style="height: 650px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;">
        <div>
        </div>
    </div>
</div>
<script>
    let a=1;
    let $div = $("#log-container div").eq(0);
    let $container = $("#log-container");
    $div[0].x = 1
    $container[0].x = 1
    console.log($div[0].x, $container[0].x);
    /*
        挂载前后dom不相同
    */
    let vm = new Vue({
        el: '#app',
        data: {
            ws: null,
            webHost: window.location.host
        },
        mounted() {
            $div = $("#log-container div").eq(0);
            $container = $("#log-container");
            console.log($div[0].x, $container[0].x);
            this.ws = new WebSocket('ws://' + this.webHost + '/log');
            $div.append('1'); // 成功
            this.ws.onmessage = function (event) {
                ++a; // 成功
                $div.html(a); // 无效果
                $container.scrollTop($div.height() - $container.height()); // 成功
            };

            this.ws.onerror = function (evt) {
                alert("出错啦");
            };
        },
        created() {
        },
        methods: {}
    });
</script>

能用vue的就不用直接操作dom了

<div id="log-container" style="height: 650px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;">
{{a}}
        <div>

vue使用的是虚拟dom,你给div赋值的时候,真实dom是生效的,到没有作用到vue的虚拟dom上,然后虚拟dom重绘dom的时候自然就没了

你可以使用this.$nextTick(),原理自己百度下

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题