简体   繁体   English

如何仅允许在输入中粘贴 URL?

[英]How to allow paste only for URLS in input?

What I want is to allow paste in an input only for urls that contain http and https, if the paste does not contain http or https then I do not want to paste anything.我想要的是只允许粘贴包含 http 和 https 的 url 的输入,如果粘贴不包含 http 或 https,那么我不想粘贴任何内容。

Any recommendation please?请问有什么推荐吗?

Try this:尝试这个:

element.addEventListener('paste', (e) => {
    e.preventDefault();
    const text = (e.originalEvent || e).clipboardData.getData('text/plain');
    if(/^http/.test(text)) {
      window.document.execCommand('insertText', false, text);
    }   
});

Codesandbox example: https://codesandbox.io/s/brave-thompson-wtvvo?file=/src/index.js:59-75 Codesandbox 示例: https ://codesandbox.io/s/brave-thompson-wtvvo ? file =/ src/index.js:59-75

What you want to do is check if the contents of the paste matches what you want, and prevent the paste if it does not match.您要做的是检查粘贴的内容是否与您想要的内容匹配,如果不匹配则阻止粘贴。

You will want to attach an event listener to your URL field(s) and, when the paste event occurs, test the clipboard contents.您需要将事件侦听器附加到您的 URL 字段,并在发生粘贴事件时测试剪贴板内容。

You can get the text of the clipboard contents from the paste event by calling clipboardData.您可以通过调用 clipboardData 从 粘贴事件中获取剪贴板内容的文本。 getData("text/plain") on the event object that your event listener is handling, which will look something like事件侦听器正在处理的事件对象上的getData("text/plain")看起来像
let data = e.clipboardData.getData("text/plain");

To test if this data matches what you want you can use the regular expression /^https?:\\/\\/.*$/要测试此数据是否与您想要的匹配,您可以使用正则表达式/^https?:\\/\\/.*$/

^ matches the start of the text — the paste data must begin with "http" ^匹配文本的开头——粘贴数据必须以“http”开头
http match exactly "http" http完全匹配“http”
s? match (optionally) an s - so https?匹配(可选)一个s - 所以https? matches "http" with an optional "s" after it匹配“http”,后面有一个可选的“s”
:\\/\\/ match the colon-slash-slash :// , but / means something in the regex, so you must escape it with a backslash \\ :\\/\\/匹配冒号-斜杠-斜杠:// ,但/表示正则表达式中的某些内容,因此您必须使用反斜杠\\对其进行转义
.*$ match anything else, up until the end of the text $ .*$匹配任何其他内容,直到文本$的结尾

If the clipboard data matches that you want to allow the paste;如果剪贴板数据匹配您要允许粘贴; if it doesn't match you want to prevent the event's default behavior of pasting by callingevent.preventDefault()如果它匹配,您希望通过调用event.preventDefault()来阻止事件的默认粘贴行为

So here you get the URL field document.getElementById('url-field') (assuming the field has an id of url-field ) and you attach the event listener, listening for a paste event.所以在这里你得到了 URL 字段document.getElementById('url-field') (假设该字段的idurl-field )并且你附加了事件侦听器,监听了一个paste事件。

I have made the input field a type="url" field, although this would also work with type="text" you get some benefits by making it specifically expect a url .我已将输入字段type="url"字段,尽管这也适用于type="text"您可以通过使其特别期待url 来获得一些好处。
A url field would also accept something like ftp://example.com/path/filename.txt so you still want your paste-prevention code anyway.一个 url 字段也会接受像ftp://example.com/path/filename.txt这样的东西,所以你仍然需要你的防粘贴代码。

I also add a validation pattern pattern="^https?://.*$" on the field itself, so that if you type (not paste) something without http(s) it's also counted as being invalid.还在字段本身上添加了一个验证模式pattern="^https?://.*$" ,这样如果您输入(而不是粘贴)没有 http(s) 的内容,它也被视为无效。

 document.getElementById('url-field') .addEventListener('paste', e => { let data = e.clipboardData.getData("text/plain"); let matched = /^https?:\\/\\/.*$/.test(data); //console.log('data:', data); //console.log('matched =', matched); if (! matched) { e.preventDefault(); } // -or- putting everything inline, without extra variables /* if (!/^https?:\\/\\/.*$/.test( e.clipboardData.getData("text/plain"))) { e.preventDefault(); } */ });
 input:invalid { border-color: red; } div.field { margin-bottom: 0.5em; }
 <form> <div class="field"> <label>Paste the URL: <input type="url" id="url-field" pattern="^https?://.*$"> </label> </div> <div class="field"> <label>Something else: <input type="text" id="notTheUrl"> </label> </div> </form>

Now, if you have more than one URL field and you want to put this "paste rule" on all of them, you can use querySelectorAll(...) in place of getElementById(...) , then attach paste-handlers to each of the fields (using .forEach ) (we'll get into event delegation some other time)现在,如果您有多个 URL 字段并且您想将这个“粘贴规则”放在所有这些字段上,您可以使用querySelectorAll(...)代替getElementById(...) ,然后将粘贴处理程序附加到每个字段(使用.forEach )(我们将在其他时间进入事件委托)

 document.querySelectorAll('input[type=url]') .forEach(element => { element.addEventListener('paste', e => { if (!/^https?:\\/\\/.*$/.test( e.clipboardData.getData("text/plain"))) { e.preventDefault(); } }); });
 input:invalid { border-color: red; } div.field { margin-bottom: 0.5em; }
 <form> <div class="field"> <label>Paste the URL <input type="url" pattern="^https?://.*$"> </label> </div> <div class="field"> <label>Something else <input type="text" id="notTheUrl"> </label> </div> <div class="field"> <label>Another URL <input type="url" id="do-not-need-an-id" pattern="^https?://.*$"> </label> </div> </form>

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

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