繁体   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)

我正在尝试将链接插入到选定的文本中,这在前端编辑器中很常见。

我可以像这样向用户的文本选择添加一个链接:

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)

这成功地在所选单词周围添加了一个<a>标记,其中包含添加的链接所需的属性,如下所示:

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

但是,用户在编辑器中通过 go 的流程是 select 单词/s,然后打开一个输入,他们可以在其中添加链接。 但是,一旦用户在输入字段上单击(聚焦), window.getSelection()输入注册为选择,这显然使得添加链接成为不可能(因为选择的词需要是选择)。

我尝试存储window.getSelection()的结果以供以后使用,但这似乎无论如何都会动态更改存储的值。 我什至尝试使用const selection = JSON.stringify(window.getSelection()) window.getSelection() ) 但这并没有捕获 Z78E6221F6393D135686866

当用户将注意力从所选文本上移开时,如何保持选择 object 存储?

你反过来做怎么样? 在向用户显示输入之前创建新的“a”元素,但添加了一个 id 属性。 这样你以后可以在用户确认输入提示后,通过它的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");

当然,如果用户取消输入提示,您还必须删除“a”元素。

在这里,您有一个带有两个 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>

我建议您放置一个名为“选择文本”的按钮,这样当您单击它时,您可以 select 您想要的文本。 我为你做了一个应用程序,如果它解决了问题,你可以自由使用它:

 <,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>

我希望这能帮到您!!!

@yochanan 非常接近,但不是我需要的。 他的解决方案将链接添加到页面上的随机区域。 可能是因为我使用动态模式输入链接,而他使用的是 static 模式。

为了使解决方案按预期工作,除了处理 window 选择之外,我还必须区分mouseuplong-press

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

* {
    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

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);
}

结果

在此处输入图像描述

代码笔

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM