এক্সপ্লোর্ট কম্যান্ডে 'সরল পাঠ্য হিসাবে পেস্ট করুন' এর জন্য জাভাস্ক্রিপ্ট ট্রিক


106

আমি execCommandএখানে উপস্থাপন নমুনা অনুসরণ উপর ভিত্তি করে আমার একটি বেসিক সম্পাদক আছে। এই execCommandঅঞ্চলে পাঠ্য আটকানোর জন্য তিনটি উপায় রয়েছে :

  • Ctrl+ +V
  • রাইট ক্লিক -> আটকান
  • রাইট ক্লিক -> সরল পাঠ্য হিসাবে আটকান

আমি কোনও HTML চিহ্নআপ ছাড়াই কেবল সরল পাঠ্য আটকানোর অনুমতি দিতে চাই। আমি কীভাবে প্রথম দুটি ক্রিয়াকে সাধারণ পাঠ্য আটকানোর জন্য বাধ্য করতে পারি?

সম্ভাব্য সমাধান: আমি যেভাবে ভাবতে পারি তা হ'ল ( Ctrl+ V) এর জন্য কীআপ ইভেন্টগুলির জন্য শ্রোতাদের সেট করা এবং পেস্টের আগে এইচটিএমএল ট্যাগগুলি স্ট্রিপ করা।

  1. এটি কি সেরা সমাধান?
  2. পেস্টে কোনও HTML মার্কআপ এড়াতে এটি কি বুলেটপ্রুফ?
  3. কীভাবে শ্রোতাদের রাইট ক্লিক -> পেস্ট করতে যুক্ত করবেন?

5
পার্শ্ব নোট হিসাবে, আপনি কি সম্পাদকে টেক্সট টেনে নিয়ে যাওয়ার যত্ন নিতে চান? এটি এইচটিএমএল সম্পাদকের মধ্যে ফাঁস হতে পারে way
pimvdb

1
@ পিমভিডিবি আপনার উত্তর আমার প্রয়োজনের জন্য যথেষ্ট ছিল। কৌতূহলের বাইরে, খুব সহজে টেনে নিয়ে যাওয়া ফাঁস এড়াতে কি কোনও সহজ পদ্ধতি আছে?
গুগলবট

2
আমি ভেবেছিলাম এটি কাজটি করবে: jsfiddle.net/HBEzc/2 । তবে Chrome এ অন্ততপক্ষে দুর্ভাগ্যক্রমে সম্পাদকের শুরুতে পাঠ্যটি সর্বদা sertedোকানো হয়।
pimvdb

আপনার এখানে ক্লিপবোর্ড এপিআই ব্যাখ্যার হিসাবে ব্যবহার করতে হবে। youtube.com/watch?v=Q81HH2Od5oo
দো

উত্তর:


247

এটি pasteইভেন্টটি বিরত করবে , বাতিল করবে pasteএবং ক্লিপবোর্ডের পাঠ্য উপস্থাপনাটিকে ম্যানুয়ালি সন্নিবেশ করবে:
http://jsfiddle.net/HBEzc/ । এটি সবচেয়ে নির্ভরযোগ্য হওয়া উচিত:

  • এটি সমস্ত ধরণের আটকানো ( Ctrl+ V, প্রসঙ্গ মেনু, ইত্যাদি) ধরে
  • এটি আপনাকে পাঠ্য হিসাবে সরাসরি ক্লিপবোর্ডের ডেটা পাওয়ার অনুমতি দেয়, তাই আপনাকে এইচটিএমএল প্রতিস্থাপন করতে কুৎসিত হ্যাকগুলি করতে হবে না।

যদিও আমি ক্রস ব্রাউজার সমর্থন সম্পর্কে নিশ্চিত নই।

editor.addEventListener("paste", function(e) {
    // cancel paste
    e.preventDefault();

    // get text representation of clipboard
    var text = (e.originalEvent || e).clipboardData.getData('text/plain');

    // insert text manually
    document.execCommand("insertHTML", false, text);
});

4
@ অলি: আমি স্পষ্ট কিছু মিস করেছি। যদি textএইচটিএমএল থাকে (যেমন আপনি যদি এইচটিএমএল কোডটি সরল পাঠ্য হিসাবে অনুলিপি করেন) তবে এটি আসলে এটি এইচটিএমএল হিসাবে আটকানো হবে। এটির একটি সমাধান এখানে। তবে এটি খুব সুন্দর নয়: jsfiddle.net/HBEzc/3
pimvdb

14
var text = (event.originalEvent || event).clipboardData.getData('text/plain');আরও কিছুটা ক্রস ব্রাউজারের সামঞ্জস্যতা সরবরাহ করে
ডানকান ওয়াকার

10
এটি পূর্বাবস্থায় ফাংশনটি ভেঙে দেয়। (Ctrl + Z)
রুডি

2
দুর্দান্ত সমাধান, তবে এটি ডিফল্ট আচরণ থেকে সরে যায়। যদি ব্যবহারকারী সেই জাতীয় কিছু অনুলিপি করে তবে সন্তোষজনক <div></div>উপাদানটির একটি শিশু উপাদান হিসাবে যুক্ত করা হবে। আমি এটি এর মতো স্থির করেছিলাম:document.execCommand("insertText", false, text);
জেসন নেওয়েল

5
আমি খুঁজে পেয়েছি insertHTMLএবং insertTextআইই 11 এ কাজ করি না, তবে document.execCommand('paste', false, text);ঠিক কাজ করে। যদিও এরপরে অন্য ব্রাউজারগুলি> _> এ কাজ করবে বলে মনে হয় না।
জ্যামি বার্কার

39

আইই তে কাজ করার জন্য আমি স্বীকৃত উত্তরটি এখানে পেতে পারি নি তাই আমি কিছু স্কাউটিং করেছি এবং এই উত্তরটি এসেছিল যা আইই ১১ এবং Chrome এবং ফায়ারফক্সের সর্বশেষতম সংস্করণগুলিতে কাজ করে।

$('[contenteditable]').on('paste', function(e) {
    e.preventDefault();
    var text = '';
    if (e.clipboardData || e.originalEvent.clipboardData) {
      text = (e.originalEvent || e).clipboardData.getData('text/plain');
    } else if (window.clipboardData) {
      text = window.clipboardData.getData('Text');
    }
    if (document.queryCommandSupported('insertText')) {
      document.execCommand('insertText', false, text);
    } else {
      document.execCommand('paste', false, text);
    }
});

1
আপনাকে ধন্যবাদ, আমি একই সমস্যা নিয়ে লড়াই করছিলাম ... ইনসার্টটেক্সট আইই 11 বা সর্বশেষ এফএফ নিয়ে কাজ করছিল না :)
হেবারএলজেড

1
এটি কি কিছু ক্ষেত্রে এটি ফায়ারফক্স এবং ক্রোম উভয় ক্ষেত্রে দু'বার পাঠ্য আটকানো সম্ভব? আমার কাছে মনে হচ্ছে ..
ফ্যানকি

1
@ ফ্যাঙ্কি যখন আমি এটি তৈরি করেছি তখন আমার সমস্যাটি ছিল না, তবে আমি এই কোডটি যে জায়গায় তৈরি করেছি সেখানে এখন আর কাজ করব না যাতে এটি এখনও কাজ করে কিনা আমি আপনাকে বলতে পারি না! আপনি কীভাবে এটি বর্ণনা করতে পারেন যে এটি কীভাবে দু'বার পেষ্ট হয়েছে?
জেমি বার্কার

2
@ ফ্যাঙ্কি দেখুন এখানে এটি নতুন করে তৈরি করতে পারেন কিনা: jsfiddle.net/v2qbp829
জ্যামি বার্কার

2
এখন মনে হচ্ছে যে সমস্যাটি আমার ছিল একটি ফাইল থেকে আপনার স্ক্রিপ্ট কল করার কারণে যা নিজেই কোনও স্ক্রিপ্ট দ্বারা লোড করা হয়েছিল। আমি এফএফ 47.0.1 এ আপনার পাঠ্যপুস্তকে টেক্সারিয়া বা ইনপুটগুলিতে আটকে দিতে পারি না (এটি ক্রোমেও করতে পারে), তবে এটি ডিভ কনটেন্টেটেটেবলের মধ্যে আটকে দিতে পারি, এটি আমার কাছে গুরুত্বপূর্ণ। ধন্যবাদ!
ফ্যানকি

21

পিমভডিবি হিসাবে একটি ঘনিষ্ঠ সমাধান। তবে এটি এফএফ, ক্রোম এবং আইই 9 এর কাজ করছে:

editor.addEventListener("paste", function(e) {
    e.preventDefault();

    if (e.clipboardData) {
        content = (e.originalEvent || e).clipboardData.getData('text/plain');

        document.execCommand('insertText', false, content);
    }
    else if (window.clipboardData) {
        content = window.clipboardData.getData('Text');

        document.selection.createRange().pasteHTML(content);
    }   
});

5
আমি শর্ট সার্কিট contentভেরিয়েবল অ্যাসাইনমেন্টটি পছন্দ করি। আমি খুঁজে পেয়েছি যে getData('Text')ক্রস ব্রাউজার ব্যবহার করে কাজ করে , তাই আপনি একবারে এই নিয়োগটি করতে পারেন: var content = ((e.originalEvent || e).clipboardData || window.clipboardData).getData('Text');তারপরে আপনাকে কেবল ক্রস ব্রাউজারের পেস্ট / সন্নিবেশ কমান্ডের জন্য যুক্তি ব্যবহার করতে হবে।
গুলফ্লাম

6
আমি মনে করি না আপনি লিখতে পারেন document.selection.createRange().pasteHTML(content)... কেবলমাত্র আইই 11 এ পরীক্ষা করা হয়েছে এবং এটি এর মতো কাজ করে না।
vsync

3
document.execCommand('insertText', false, content)আইই ১১ এবং এজ হিসাবে কাজ করে না। এছাড়াও, ক্রোমের সর্বশেষতম সংস্করণগুলি এখন সমর্থন করে document.execCommand('paste', false, content), যা সহজ। তারা হতাশ হতে পারে insertText
কনইহাইড

19

অবশ্যই প্রশ্নের উত্তর ইতিমধ্যে দেওয়া হয়েছে এবং বিষয়টি খুব পুরানো তবে এটি সহজ একটি পরিষ্কার হিসাবে আমি আমার সমাধান সরবরাহ করতে চাই:

এটি আমার সন্তোষজনক-ডিভির পেস্ট-ইভেন্টের অভ্যন্তরে।

var text = '';
var that = $(this);

if (e.clipboardData)
    text = e.clipboardData.getData('text/plain');
else if (window.clipboardData)
    text = window.clipboardData.getData('Text');
else if (e.originalEvent.clipboardData)
    text = $('<div></div>').text(e.originalEvent.clipboardData.getData('text'));

if (document.queryCommandSupported('insertText')) {
    document.execCommand('insertHTML', false, $(text).html());
    return false;
}
else { // IE > 7
    that.find('*').each(function () {
         $(this).addClass('within');
    });

    setTimeout(function () {
          // nochmal alle durchlaufen
          that.find('*').each(function () {
               // wenn das element keine klasse 'within' hat, dann unwrap
               // http://api.jquery.com/unwrap/
               $(this).not('.within').contents().unwrap();
          });
    }, 1);
}

অন্য অংশটি অন্য একটি এসও-পোস্টের, আমি আর খুঁজে পাইনি ...


আপডেট 19.11.2014: অন্য এসও পোস্ট


2
আমার মনে হয় আপনি এই পোস্টে উল্লেখ করা হয়: stackoverflow.com/questions/21257688/...
gfullam

1
সাফারিতে আমার পক্ষে কাজ করার কথা মনে হয়নি। হতে পারে কিছু ভুল হয়েছে
Cannicide

8

পোস্ট করা উত্তরগুলির কোনওটিই সত্যিই ক্রস ব্রাউজারে কাজ করছে বলে মনে হয় না বা সমাধান জটিল হয়ে যায়:

  • কমান্ডটি insertTextIE দ্বারা সমর্থিত নয়
  • ব্যবহার pasteIE11 মধ্যে স্ট্যাক ওভারফ্লো ভুলবশত কমান্ড ফলাফল

আমার জন্য কী কাজ করেছে (আইই 11, এজ, ক্রোম এবং এফএফ) নিম্নলিখিত:

$("div[contenteditable=true]").off('paste').on('paste', function(e) {
    e.preventDefault();
    var text = e.originalEvent.clipboardData ? e.originalEvent.clipboardData.getData('text/plain') : window.clipboardData.getData('Text');
    _insertText(text);
});

function _insertText(text) { 
    // use insertText command if supported
    if (document.queryCommandSupported('insertText')) {
        document.execCommand('insertText', false, text);
    }
    // or insert the text content at the caret's current position
    // replacing eventually selected content
    else {
        var range = document.getSelection().getRangeAt(0);
        range.deleteContents();
        var textNode = document.createTextNode(text);
        range.insertNode(textNode);
        range.selectNodeContents(textNode);
        range.collapse(false);

        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    }
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<textarea name="t1"></textarea>
<div style="border: 1px solid;" contenteditable="true">Edit me!</div>
<input />
</body>

নোট করুন যে কাস্টম পেস্ট হ্যান্ডলারটি কেবল contenteditableনোডের জন্য / কাজ করার প্রয়োজন । যেহেতু উভয় textareaএবং সমতল inputক্ষেত্রগুলি এইচটিএমএল সামগ্রীকে আটকানো সমর্থন করে না, তাই এখানে কিছুই করার দরকার নেই।


এটি কাজ করতে আমাকে .originalEventইভেন্ট হ্যান্ডলারের (লাইন 3) এড়িয়ে যেতে হয়েছিল। তাই সম্পূর্ণ লাইন সৌন্দর্য এটি পছন্দ: const text = ev.clipboardData ? ev.clipboardData.getData('text/plain') : window.clipboardData.getData('Text');। সর্বশেষতম ক্রোম, সাফারি, ফায়ারফক্সে কাজ করে।
Pwdr

3

ফায়ারফক্স আপনাকে ক্লিপবোর্ডের ডেটা অ্যাক্সেস করার অনুমতি দেয় না যাতে এটি কাজ করতে আপনাকে একটি 'হ্যাক' করতে হবে। আমি একটি সম্পূর্ণ সমাধান খুঁজে পেতে সক্ষম হইনি, তবে আপনি এটি একটি টেক্সারিয়া তৈরি করে এবং এর পরিবর্তে এতে পেস্ট করে ctrl + v পেস্টগুলির জন্য এটি ঠিক করতে পারেন:

//Test if browser has the clipboard object
if (!window.Clipboard)
{
    /*Create a text area element to hold your pasted text
    Textarea is a good choice as it will make anything added to it in to plain text*/           
    var paster = document.createElement("textarea");
    //Hide the textarea
    paster.style.display = "none";              
    document.body.appendChild(paster);
    //Add a new keydown event tou your editor
    editor.addEventListener("keydown", function(e){

        function handlePaste()
        {
            //Get the text from the textarea
            var pastedText = paster.value;
            //Move the cursor back to the editor
            editor.focus();
            //Check that there is a value. FF throws an error for insertHTML with an empty string
            if (pastedText !== "") document.execCommand("insertHTML", false, pastedText);
            //Reset the textarea
            paster.value = "";
        }

        if (e.which === 86 && e.ctrlKey)
        {
            //ctrl+v => paste
            //Set the focus on your textarea
            paster.focus();
            //We need to wait a bit, otherwise FF will still try to paste in the editor => settimeout
            window.setTimeout(handlePaste, 1);
        }

    }, false);
}
else //Pretty much the answer given by pimvdb above
{
    //Add listener for paster to force paste-as-plain-text
    editor.addEventListener("paste", function(e){

        //Get the plain text from the clipboard
        var plain = (!!e.clipboardData)? e.clipboardData.getData("text/plain") : window.clipboardData.getData("Text");
            //Stop default paste action
        e.preventDefault();
        //Paste plain text
        document.execCommand("insertHTML", false, plain);

    }, false);
}

2

আমি একটি সরল পাঠ্য পেস্টেও কাজ করছিলাম এবং আমি সমস্ত নির্বাহী কম্যান্ড এবং getData ত্রুটিগুলি ঘৃণা করতে শুরু করেছিলাম, তাই আমি এটিকে ক্লাসিক উপায়ে করার সিদ্ধান্ত নিয়েছি এবং এটি একটি কবজির মতো কাজ করে:

$('#editor').bind('paste', function(){
    var before = document.getElementById('editor').innerHTML;
    setTimeout(function(){
        var after = document.getElementById('editor').innerHTML;
        var pos1 = -1;
        var pos2 = -1;
        for (var i=0; i<after.length; i++) {
            if (pos1 == -1 && before.substr(i, 1) != after.substr(i, 1)) pos1 = i;
            if (pos2 == -1 && before.substr(before.length-i-1, 1) != after.substr(after.length-i-1, 1)) pos2 = i;
        }
        var pasted = after.substr(pos1, after.length-pos2-pos1);
        var replace = pasted.replace(/<[^>]+>/g, '');
        var replaced = after.substr(0, pos1)+replace+after.substr(pos1+pasted.length);
        document.getElementById('editor').innerHTML = replaced;
    }, 100);
});

আমার স্বীকৃতির সাথে কোডটি এখানে পাওয়া যাবে: http://www.albertmartin.de/blog/code.php/20/plain-text-paste-with- জাভাস্ক্রিপ্ট


1
function PasteString() {
    var editor = document.getElementById("TemplateSubPage");
    editor.focus();
  //  editor.select();
    document.execCommand('Paste');
}

function CopyString() {
    var input = document.getElementById("TemplateSubPage");
    input.focus();
   // input.select();
    document.execCommand('Copy');
    if (document.selection || document.textSelection) {
        document.selection.empty();
    } else if (window.getSelection) {
        window.getSelection().removeAllRanges();
    }
}

উপরের কোডটি আইই 10 এবং আইই 11 এ আমার জন্য কাজ করে এবং এখন ক্রোম এবং সাফারিতেও কাজ করে। ফায়ারফক্সে পরীক্ষা করা হয়নি।


1

আইই ১১-এ, এক্সিকিউন্ড ভাল কাজ করে না। আইআই 11 এর জন্য আমি নীচের কোডটি ব্যবহার করছি <div class="wmd-input" id="wmd-input-md" contenteditable=true> আমার ডিভ বাক্স।

আমি উইন্ডো.ক্লিপবোর্ডডেটা থেকে ক্লিপবোর্ডের ডেটা পড়ি এবং ডিভের টেক্সট কনটেন্টটি সংশোধন করে ক্যারেট দেব।

আমি ক্যারেট সেট করার জন্য টাইমআউট দিই, কারণ যদি আমি টাইমআউট না সেট করি তবে একটি ক্যারেট ডিভের শেষে চলে যায়।

এবং আপনার নীচের উপায়ে IE11 এ ক্লিপবোর্ডডাটা পড়া উচিত। আপনি যদি এটি না করেন তবে নিউলাইন কার্যাকারটি সঠিকভাবে পরিচালনা করা হয় না, তাই ক্যারেটটি ভুল হয়ে যায়।

var tempDiv = document.createElement("div");
tempDiv.textContent = window.clipboardData.getData("text");
var text = tempDiv.textContent;

আইই 11 এবং ক্রোমে পরীক্ষিত। এটি IE9 এ কাজ করতে পারে না

document.getElementById("wmd-input-md").addEventListener("paste", function (e) {
    if (!e.clipboardData) {
        //For IE11
        e.preventDefault();
        e.stopPropagation();
        var tempDiv = document.createElement("div");
        tempDiv.textContent = window.clipboardData.getData("text");
        var text = tempDiv.textContent;
        var selection = document.getSelection();
        var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset;
        var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset;                    
        selection.removeAllRanges();

        setTimeout(function () {    
            $(".wmd-input").text($(".wmd-input").text().substring(0, start)
              + text
              + $(".wmd-input").text().substring(end));
            var range = document.createRange();
            range.setStart(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length);
            range.setEnd(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length);

            selection.addRange(range);
        }, 1);
    } else {                
        //For Chrome
        e.preventDefault();
        var text = e.clipboardData.getData("text");

        var selection = document.getSelection();
        var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset;
        var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset;

        $(this).text($(this).text().substring(0, start)
          + text
          + $(this).text().substring(end));

        var range = document.createRange();
        range.setStart($(this)[0].firstChild, start + text.length);
        range.setEnd($(this)[0].firstChild, start + text.length);
        selection.removeAllRanges();
        selection.addRange(range);
    }
}, false);

0

অনুসন্ধান এবং চেষ্টা করার পরে আমি একরকম অনুকূল সমাধান খুঁজে পেয়েছি

কি মনে রাখা গুরুত্বপূর্ণ

// /\x0D/g return key ASCII
window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))


and give the css style white-space: pre-line //for displaying

var contenteditable = document.querySelector('[contenteditable]')
            contenteditable.addEventListener('paste', function(e){
                let text = ''
                contenteditable.classList.remove('empty')                
                e.preventDefault()
                text = (e.originalEvent || e).clipboardData.getData('text/plain')
                e.clipboardData.setData('text/plain', '')                 
                window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))// /\x0D/g return ASCII
        })
#input{
  width: 100%;
  height: 100px;
  border: 1px solid black;
  white-space: pre-line; 
}
<div id="input"contenteditable="true">
        <p>
        </p>
</div>   


0

ঠিক আছে যেহেতু প্রত্যেকে ক্লিপবোর্ডের ডেটা, কিপ্রেস ইভেন্টটি পরীক্ষা করে এবং এক্সিকিউমন্ড ব্যবহার করে কাজ করার চেষ্টা করছে।

আমি এই ভেবেছিলাম

কোড

handlePastEvent=()=>{
    document.querySelector("#new-task-content-1").addEventListener("paste",function(e)
    {
        
        setTimeout(function(){
            document.querySelector("#new-task-content-1").innerHTML=document.querySelector("#new-task-content-1").innerText.trim();
        },1);
    });

}
handlePastEvent();
<div contenteditable="true" id="new-task-content-1">You cann't paste HTML here</div>

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.