Vue-chat-scroll不适用于加载程序

时间:2018-05-21 19:54:11

标签: javascript vue.js scroll vuejs2 vue-chat-scroll

我有一个带v-chat-scroll指令的聊天框,效果很好。每次添加新消息时,聊天框都会滚动到底部。

我的问题是我在v-chat-scroll无法识别的每条消息之间都有一个加载程序,并且当它“出现”时从不将滚动条推到底部

<div class="message" v-chat-scroll>
  <div>
    <div v-for="message in messages" class="msg-box">
      {{ message }}
    </div>
    <!-- Loader don't scroll to bottom -->
    <div v-show="loader" class="msg-box">
      >>super loader>>
    </div>
  </div>
</div>
  • 我试图将消息+加载器包装在一个div元素中 (就像在摘录中一样)
  • 我试图将加载器div放在v-for内(仅在最后一条消息之后显示条件)
  • 我尝试在主div上使用scrollTopscrollHeight强制滚动底部(使用refloader}并观察 select nextval ('ignar.hibernate_sequence') Hibernate: select nextval ('ignar.samples_id_seq') Hibernate: insert into ignar.samplings (available_for_test, build_date, color_id, dimension_id, machine_id, print, product_id, reception_date, remark, special_try, test_done, to_print, delay_before_doing_test, press, quantity_received, dtype, id, year) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'TraditionalSamplings', ?, ?) Hibernate: insert into ignar.samples (created_at, updated_at, absorption_printed, aen_remarque, certificat_include, cube, durability_printed, fresh_density, fresh_weigth, gen_remarque, label, position, sample_letter, sampling_id, sampling_year, absorption, absorption_number, coloration, coloration_number, compression, compression_number, density, draw_down, draw_down_number, durability, durability_number, granulometry, granulometry_number, organic_material, organic_material_number, scaling, scaling_number, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 2018-05-21 15:38:21.214 WARN 2973 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 22021 2018-05-21 15:38:21.215 ERROR 2973 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: invalid byte sequence for encoding "UTF8": 0x00 2018-05-21 15:38:21.215 ERROR 2973 --- [io-8080-exec-10] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.DataException: could not execute statement] 属性(true / false)

但这些解决方案都不起作用...... 如果某人有解决此问题的方法,那就太棒了!

我在这里制作了一个简约版的聊天框:https://jsfiddle.net/StpFlp_DDK/6s0kbtkr/

3 个答案:

答案 0 :(得分:2)

查看v-chat-scroll的源代码,滚动到第#=第27行,您会看到if (pause || e[e.length - 1].addedNodes.length != 1) return;

当loader = true(v-if="loader")时,您会看到e.length=2e[e.length - 1].addedNodes.length = 0与预期不符。

所以我使用一个reduce来对每个MutationRecord的addedNodes长度求和,然后工作。

Vue.config.productionTip = false

// Below codes (scrollToBottom and vChatScroll) is copied from v-chat-scroll at github:
// https://github.com/theomessin/vue-chat-scroll/blob/master/src/directives/v-chat-scroll.js
const scrollToBottom = el => {
    el.scrollTop = el.scrollHeight;
};

const vChatScroll = {
    bind: (el, binding) => {
        let timeout;
        let scrolled = false;

        el.addEventListener('scroll', e => {
            if (timeout) window.clearTimeout(timeout);
            timeout = window.setTimeout(function() {
                scrolled = el.scrollTop + el.clientHeight + 1 < el.scrollHeight;
            }, 200);
        });

        (new MutationObserver(e => {
            let config = binding.value || {};
            let pause = config.always === false && scrolled;
            if (pause 
            || 
            e.reduce((pre, cur) => { // sum the length of each addedNodes
              return pre+cur.addedNodes.length
            }, 0) < 1 // if sum(addedNodes.length) === 0, do nothing.
            ) return;
            scrollToBottom(el);
        })).observe(el, {childList: true, subtree: true});
    },
    inserted: scrollToBottom
};

Vue.directive('chat-scroll', vChatScroll)

const str = [
	"Lorem ipsum dolor sit amet, consectetur adipisicing elit, similique sequi perspiciatis praesentium iure debitis explicabo animi reiciendis!",
	"Error ipsa eaque officia tempore optio laborum porro illo, veritatis atque pariatur, vero voluptatem quos",
  "At doloremque eveniet labore, eligendi dicta beatae earum aperiam et, recusandae perspiciatis perferendis corporis dolorum quidem dolores esse labore."
]

new Vue({
  el: "#app",
  data: {
    messages: [],
    loader: false
  },
  methods: {
    addMessage() {
      this.loader = true

      setTimeout(() => {
        this.loader = false
        let randMsg = str[Math.floor(Math.random()*str.length)]
        this.messages.push(randMsg)
      }, 2000)
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Montserrat;
}

#app {
  background: #D3F3F1;
  position: relative;
  border-radius: 4px;
  height: 300px;
  width: 350px;
}
.messages-container {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

.message {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  flex-shrink: 1;
  box-sizing: border-box;
  overflow-x: hidden;
  position: relative;
  width: 100%;
}

.msg-box {
  margin: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 8px;
}

.input-message {
  position: relative;
  bottom: 0;
  background-color: white;
  width: 100%;
  height: 50px;
  text-align: center;
  flex-shrink: 0;
}

button {
  margin-top: 10px;
  border-radius: 4px;
  background: #D3F3F1;
  padding: 8px 15px;
  border: none;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
  <div class="messages-container">
    <div class="message" v-chat-scroll>
      <div>
        <div v-for="message in messages" class="msg-box">
          {{ message }}
        </div>
        <!-- Loader don't scroll to bottom -->
        <div v-if="loader" :class="loader ? 'msg-box' : ''">
          >>super loader>>
        </div>
      </div>

    </div>

    <div class="input-message">
      <button @click="addMessage">Add message</button>
    </div>
  </div>
</div>

答案 1 :(得分:0)

我知道问题已经回答。但这可能是更好的方法, 每当消息属性被更新时,您都选择引用作为消息容器,其中 您已经定义了$request->session();属性并按如下所示进行更新:

overflow-y: auto;

答案 2 :(得分:0)

代替添加div

<div v-show="loader" class="msg-box">
      >>super loader>>
    </div>

在消息div的内部,您可以将加载程序添加为背景图像,并在数据加载完成后删除背景图像。 我该如何解决问题!