Trying to display comments near appropriate doc range in Vue component

点点圈 提交于 2020-04-30 06:27:39

问题


I am attempting to emulate Medium style comments in an html document.

This answer has gotten me nearly there: How to implement Medium-style commenting interface in VueJS

With that method, I can highlight text and make comments, but I want to display the coments on the same line as the range the commenter selected. The code as I have treats every paragraph it seems as a separate document, such that I don't know how to return to the correct paragraph to find the original range being commented on.

Here is the commenting component:

<template>
  <div class="popup" :style="{top: offsetTop, left: offsetLeft}" ref="popup">
    <span @click="AlertSelectedText">Comment</span>
  </div>
</template>
<script>
export default {
  data() {
    return {
      popupInitialTopOffset: 0,
      popupInitialLeftOffset: 0,
      offsetTop: 0,
      offsetLeft: "-999em",
      selectedText: undefined
    };
  },
  methods: {
    ListenToDocumentSelection() {
      let sel = window.getSelection();
      console.log('sel is: ', sel)
      setTimeout(_ => {
        if (sel && !sel.isCollapsed) {
          this.selectedText = sel.toString();
          if (sel.rangeCount) {
            let range = sel.getRangeAt(0).cloneRange();
            console.log('range is: ', range)
            if (range.getBoundingClientRect) {
              var rect = range.getBoundingClientRect();
              console.log('boundingrect is: ', rect)
              let left = rect.left + (rect.right - rect.left) / 2;
              let top = rect.top;

              this.offsetTop = top - this.popupInitialTopOffset - 30 + "px";

              this.offsetLeft = left - this.popupInitialLeftOffset / 2 + "px";
            }
          }
        } else {
          this.offsetLeft = "-999em";
        }
      }, 0);
    },
    AlertSelectedText() {
      alert(`"${this.selectedText}" posted as comment`);
    }
  },
  mounted() {
    this.popupInitialTopOffset = this.$refs.popup.offsetHeight;
    this.popupInitialLeftOffset = this.$refs.popup.offsetWidth;
    console.log('this is the positions of the popup', this.popupInitialTopOffset, this.popupInitialLeftOffset);
    window.addEventListener("mouseup", this.ListenToDocumentSelection);
  },
  destroyed() {
    window.removeEventListener("mouseup", this.ListenToDocumentSelection);
  }
};
</script>
<style scoped>
.popup {
  position: absolute;
  color: #FFF;
  background-color: #000;
  padding: 10px;
  border-radius: 5px;
  transform-origin: center, center;
  cursor: pointer;
}
.popup:after {
  content: "";
  border-bottom: 5px solid #000;
  border-right: 5px solid #000;
  border-top: 5px solid transparent;
  border-left: 5px solid transparent;
  position: absolute;
  top: calc(100% - 5px);
  transform: rotate(45deg);
  left: calc(50% - 3px);
}
</style>

if I could know how to add coordinates for returning to the commented range, I think I could manage the rest.


回答1:


Wherever you want to enable commenting, try giving those elements a class and a unique ID.

A class would help you identify that it has commenting enabled whereas an ID would help you uniquely identify it.

In your logic, you can access the list of classes on that element as

sel.anchorNode.parentElement.classList

and ID as

sel.anchorNode.parentElement.id

With the help of this combination, you can surely associate a comment to your elements.



来源:https://stackoverflow.com/questions/61149760/trying-to-display-comments-near-appropriate-doc-range-in-vue-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!