简体   繁体   English

使用 JS 将链接插入所选文本(当用户专注于输入以输入 URL 时,丢失 window.getSelection() 值)

[英]Insert a link into selected text using JS (losing window.getSelection() value when user focuses on input to enter URL)

I am trying to insert a link into selected text, as is common with front-end editors.我正在尝试将链接插入到选定的文本中,这在前端编辑器中很常见。

I can add a link to the user's text selection like this:我可以像这样向用户的文本选择添加一个链接:

var sel = window.getSelection();
var e = document.createElement("a");
e.innerHTML = sel.toString();
e.type = "link";
e.href = "www.the_link_to_open.com"
e.target = "_blank";
var range = sel.getRangeAt(0);
range.deleteContents();
range.insertNode(e)

This successfully adds an <a> tag around the selected word, with the properties needed for the added link, like this:这成功地在所选单词周围添加了一个<a>标记,其中包含添加的链接所需的属性,如下所示:

<a type="link" href="www.the_link_to_open.com" target="_blank">highlighted text</a>

However, the flow a user would go through in the editor is to select the word/s, then open an input where they can add the link.但是,用户在编辑器中通过 go 的流程是 select 单词/s,然后打开一个输入,他们可以在其中添加链接。 But, as soon as the user clicks (focuses) on the input field the window.getSelection() registers the input as the selection, which obviously makes adding the link impossible (since the selected word needs to be the selection).但是,一旦用户在输入字段上单击(聚焦), window.getSelection()输入注册为选择,这显然使得添加链接成为不可能(因为选择的词需要是选择)。

I tried storing the result of window.getSelection() to use later, but this seems to dynamically change the stored value regardless.我尝试存储window.getSelection()的结果以供以后使用,但这似乎无论如何都会动态更改存储的值。 I even tried a hard(?) copy to try and store the window.getSelection() permanently using const selection = JSON.stringify(window.getSelection()) but this doesn't capture the output.我什至尝试使用const selection = JSON.stringify(window.getSelection()) window.getSelection() ) 但这并没有捕获 Z78E6221F6393D135686866

How can one keep the selection object stored when the user focuses away from the selected text?当用户将注意力从所选文本上移开时,如何保持选择 object 存储?

How about you do it the other way around?你反过来做怎么样? You create the new “a” element before you show the input to the user, but you add an id attribute.在向用户显示输入之前创建新的“a”元素,但添加了一个 id 属性。 This way you can later, after the user confirms the input prompt, find it by its id, change the href to the user input and remove the id again.这样你以后可以在用户确认输入提示后,通过它的id找到它,把href改成用户输入,再把id去掉。

 var sel = window.getSelection(); var e = document.createElement("a"); e.innerHTML = sel.toString(); e.type = "link"; e.href = "www.willBeOverwritten.com" e.target = "_blank"; e.id = "newLinkWaitingForUserInput" var range = sel.getRangeAt(0); range.deleteContents(); range.insertNode(e) //Show input popup //in the callback of the popup: var userInput = "www.userInput.com"; //Search for the newly created link var link = document.getElementById("newLinkWaitingForUserInput"); //Set the href to the userinput link.href = userInput; //remove the id link.removeAttribute("id");

Of course you also have to remove the “a” element if the user cancels the input prompt.当然,如果用户取消输入提示,您还必须删除“a”元素。

here you have a working solution with two function as described in my comment above.在这里,您有一个带有两个 function 的有效解决方案,如我上面的评论中所述。

 let selectedText, range; function getSelectedText() { const selectObj = window.getSelection(); selectedText = selectObj.toString(); range = selectObj.getRangeAt(0) } function createLink(e) { var a = document.createElement("a"); a.innerHTML = selectedText a.type = "link"; a.href = e.target.value a.target = "_blank"; range.deleteContents(); range.insertNode(a); } document.querySelector('.text').addEventListener('mouseup', getSelectedText) document.querySelector('.link').addEventListener('change', (e) => createLink(e))
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width. initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <div class="text"> Lorem ipsum dolor sit amet consectetur adipisicing elit, Minima illum, quod assumenda nisi illo hic quo minus excepturi quasi labore debitis nemo molestiae nesciunt. neque laboriosam repellendus necessitatibus vero corporis. </div> <br /> <div> <label>Add url</label> <input class="link" type="text" /> </div> </body> </html>

I recommend you to put a button called "Select text" so that when you click it, you can select the text you want.我建议您放置一个名为“选择文本”的按钮,这样当您单击它时,您可以 select 您想要的文本。 I made an app for you, if it solves the problem, you can use it freely:我为你做了一个应用程序,如果它解决了问题,你可以自由使用它:

 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1;0"> <title>Inserting Links</title> <script> "use strict" function Onload() { var CanSelect = false; var Link = ""; var sel = "". var LinkInput = document;getElementById("link"). LinkInput,addEventListener("change". () => { Link = LinkInput;value; }). var SelectButton = document;getElementById("button"). SelectButton,addEventListener("click"; () => { CanSelect = true; }). function Select() { if (CanSelect) { var selection = window;getSelection(); CanSelect = false; sel = selection. } } function Insert(selection) { var e = document;createElement("a"). e.innerHTML = selection;toString(). e;type = "link". e;href = Link. e;target = "_blank". var range = selection;getRangeAt(0). range;deleteContents(). range;insertNode(e). } window,addEventListener("pointerup"; () => { Select(); }). var InsertButton = document;getElementById("insert"). InsertButton,addEventListener("click"; () => { Insert(sel); }). } window,addEventListener("load"; Onload). </script> </head> <body> <input type="text" placeholder="Link " id="link"> <button id="button">Select Text </button> <button id="insert">Insert ✅</button> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse earum magnam ratione unde maiores illum minus accusantium iste. Accusamus sit quibusdam aut aperiam nemo. Soluta vitae ullam facilis illum tempora.</p> </body> </html>

I hope this will help you!!!我希望这能帮到您!!!

@yochanan was very close, but not quite what I needed. @yochanan 非常接近,但不是我需要的。 His solution added the link to a random area on the page.他的解决方案将链接添加到页面上的随机区域。 Likely because I am using a dynamic modal for entering a link, where as he used a static one.可能是因为我使用动态模式输入链接,而他使用的是 static 模式。

For the solution to work as intended, I had to distinguish between mouseup and long-press , in addition to handling the window selection.为了使解决方案按预期工作,除了处理 window 选择之外,我还必须区分mouseuplong-press

HTML HTML

<div id="hold_text" contenteditable=false>This is some text. Select one or more words in here, by highlighting the word/s with your cursor.<br><br>Then click on the LINK button, add your link, and hit ENTER.</div>

<button id="butt">LINK</button>

<div id='modal'><a id='close'>X<a><input id="input" placeholder='paste url, then hit enter'></input></div>

CSS CSS

* {
    font-family: arial;
}

body {
  background: #218c74;
}

#hold_text {
  height: 200px;
  width: 500px;
  background: #f7f1e3;
  border-radius: 4px;
  padding: 10px;
  font-size: 18px; 
}

button {
  height : auto;
  width : auto;
  background : #ff5252;
  border-radius : 4px;
  padding: 8px;
  font-size: 18px;
  border: none;
  margin-top: 10px;
  cursor: pointer;
  color: white;
}

#modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: auto;
  width: auto;
  box-shadow: 2px 2px 30px black;
  display: none;
  border-radius: 4px;
  border : 2px solid #ffda79;
}

#close {
  cursor: pointer;
  color: white;
  margin: 5px;
}

input {
  width: 300px;
  height: 30px;
  font-size: 18px;
  border: none;
  outline: 0;
}

JS JS

text = document.getElementById("hold_text");
button = document.getElementById("butt");
modal = document.getElementById("modal");
close = document.getElementById("close");
input = document.getElementById("input");

button.addEventListener("click", function() {
    modal.style.display = "block";
    input.focus();
    close.addEventListener("click", function(e) {
        modal.style.display = "none";
    });
    input.addEventListener("keypress", function(e) {
        if(e.key === "Enter") {
            createLink(e);
            modal.style.display = "none";
            input.value = "";
        }
    })
});

cnt = 0;

text.addEventListener("mouseup", function() {
    cnt++;
    if(cnt === 2) {
        getSelectedText();
    }
    setTimeout(function() {
        cnt = 0;
    }, 200)
    if(long_press) {
        getSelectedText();
        long_press = false;
    }
})

call_on_longpress();

long_press = false;

function call_on_longpress() {
    var delay;
    var longpress = 400;
    text.addEventListener('mousedown', function(e) {
        var _this = this;
        delay = setTimeout(check, longpress);

        function check() {
            long_press = true;
        }
    }, true);
    text.addEventListener('mouseup', function(e) {
        clearTimeout(delay);
    });
    text.addEventListener('mouseout', function(e) {
        clearTimeout(delay);
    });
}

let selectedText, range;

function getSelectedText() {
    const selectObj = window.getSelection();
    selectedText = selectObj.toString();
    range = selectObj.getRangeAt(0)
}

function createLink(e) {
    var a = document.createElement("a");
    a.innerHTML = selectedText
    a.type = "link";
    a.href = e.target.value
    a.target = "_blank";
    range.deleteContents();
    range.insertNode(a);
}

RESULT结果

在此处输入图像描述

CodePen代码笔

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在从Z4C4C4AD5FCA2E7A3F74DBB1CED00381AA4Z段落中选择文本上,使用Z05B8C74CBD96FBD96FBF2DE4C1A352702FBF4Z.getSelection() - On selecting text from HTML paragraph using window.getSelection(), the range index value is giving 0 when text from different/child tag is selected 使用 Window.getSelection() 的粗体/非粗体选定文本 - Bold/unbold selected text using Window.getSelection() window.getSelection() 给了我选定的文本,但我想要 HTML - window.getSelection() gives me the selected text, but I want the HTML 当文本由换行时,window.getSelection()。getRange(0)不起作用<mark> - window.getSelection().getRange(0) does not work when text is wrapped by <mark> 使用window.getSelection()检查文本是否突出显示 - Check whether text is highlighted using window.getSelection() window.getSelection()的值在回调期间更改 - Value of window.getSelection() changes during callback 使用window.getSelection获取字符串 - Using window.getSelection to get a string 我如何为window.getSelection值分配文本方向RTL,我试过但是如何从文本区域的现有值中删除getSelection - how to i assign text direction RTL for window.getSelection value, I tried but how to remove getSelection from existing value of text area 与window.getSelection()相反 - The opposite to window.getSelection() 使用window.getSelection从textarea中获得选中或光标所在的文本行 - use window.getSelection get selected or cursor located text line from textarea
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM