জাভাস্ক্রিপ্ট পেস্ট ইভেন্টে ক্লিপবোর্ড ডেটা পান (ক্রস ব্রাউজার)


299

কোনও ওয়েব অ্যাপ্লিকেশন কীভাবে কোনও পেস্ট ইভেন্ট সনাক্ত করতে পারে এবং আটকানো ডেটা পুনরুদ্ধার করতে পারে?

আমি এইচটিএমএল বিষয়বস্তুটি একটি সমৃদ্ধ পাঠ্য সম্পাদকের কাছে আটকানোর আগে মুছে ফেলতে চাই।

পরে টেক্সট পরিষ্কার করার পরে কাজ করা কাজ করে তবে সমস্যাটি হ'ল পূর্ববর্তী সমস্ত বিন্যাসটি হারিয়ে গেছে। উদাহরণস্বরূপ, আমি সম্পাদকটিতে একটি বাক্য লিখতে এবং এটিকে সাহসী করতে পারি, তবে আমি যখন নতুন পাঠ্য পেস্ট করি তখন সমস্ত বিন্যাস নষ্ট হয়ে যায়। আমি কেবল আটকানো টেক্সটটি পরিষ্কার করতে চাই এবং পূর্বের কোনও বিন্যাসটি আউটচুড রেখে দিতে চাই।

আদর্শভাবে, সমাধানটি সমস্ত আধুনিক ব্রাউজারগুলিতে কাজ করা উচিত (উদাঃ, এমএসআইই, গেকো, ক্রোম এবং সাফারি)।

নোট করুন যে এমএসআইই রয়েছে clipboardData.getData(), তবে অন্যান্য ব্রাউজারগুলির জন্য আমি একই ধরণের কার্যকারিতা খুঁজে পাইনি।


এই সমস্ত উত্তরগুলি কীভাবে পাঠ্য সামগ্রী পাওয়া যায় তা ব্যাখ্যা করে। চিত্রের সামগ্রী বা ফাইল সামগ্রী পেতে আরও অনেক বেশি কাজের প্রয়োজন। হতে পারে আমরা শিরোনামটি "জাভাস্ক্রিপ্ট স্যানিটাইজড টেক্সট ক্লিপবোর্ড ডেটা পান ..."
গিগাওয়াট

1
নিকো যেমন বলেছেন: event.clipboardData.getData('Text')আমার পক্ষে কাজ করেছেন।
আন্দ্রে এলরিকো

document.addEventListener('paste'...আমার পক্ষে কাজ করেছে তবে কোনও ব্যবহারকারী পৃষ্ঠার অন্য কোথাও পেস্ট করতে সক্ষম হতে চাইলে বিরোধ সৃষ্টি হয়েছে caused তারপরে আমি চেষ্টা করেছি myCanvasElement.addEventListener('paste'..., কিন্তু কাজ হয়নি। অবশেষে আমি myCanvasElement.parentElement.addEventListener('paste'...কাজ খুঁজে পেয়েছি ।
রায়ান

উত্তর:


149

এই উত্তরটি লেখার পর থেকে পরিস্থিতি বদলে গেছে: এখন ফায়ারফক্স 22 তম সংস্করণে সমর্থন যোগ করেছে, সমস্ত বড় ব্রাউজার এখন একটি পেস্ট ইভেন্টে ক্লিপবোর্ড ডেটা অ্যাক্সেস সমর্থন করে। উদাহরণের জন্য নিকো বার্নসের উত্তর দেখুন ।

অতীতে সাধারণত ক্রস ব্রাউজার উপায়ে এটি সম্ভব ছিল না। আদর্শটি হ'লpaste ইভেন্টটির মাধ্যমে আটকানো সামগ্রী পেতে সক্ষম হবেন যা সাম্প্রতিক ব্রাউজারগুলিতে সম্ভব তবে কিছু পুরানো ব্রাউজারগুলিতে নয় (বিশেষত, ফায়ারফক্স <22)।

যখন আপনাকে পুরানো ব্রাউজারগুলি সমর্থন করতে হবে, আপনি যা করতে পারেন তা পুরোপুরি জড়িত এবং একটি হ্যাক যা ফায়ারফক্স 2+, আই 5.5+ এবং ওয়েবকিট ব্রাউজারগুলিতে যেমন সাফারি বা ক্রোমে কাজ করবে। TinyMCE এবং CKEditor উভয়ের সাম্প্রতিক সংস্করণগুলি এই কৌশলটি ব্যবহার করে:

  1. একটি কিপ্রেস ইভেন্ট হ্যান্ডলার ব্যবহার করে একটি সিটিআরএল-ভি / শিফট-ইন ইভেন্ট সনাক্ত করুন
  2. সেই হ্যান্ডলারে, বর্তমান ব্যবহারকারীর নির্বাচনটি সংরক্ষণ করুন, নথিতে একটি টেক্সারিয়া উপাদান অফ-স্ক্রিনে (বাম -1000px বলুন) যুক্ত করুন, designModeবন্ধ করুন এবং টেক্সারিয়ায় কল focus()করুন, এইভাবে ক্যারেটটি সরিয়ে এবং কার্যকরভাবে পেস্টটিকে পুনঃনির্দেশিত করুন
  3. পাঠ্যমূল্যের মান সংরক্ষণ করে, ডকুমেন্ট থেকে টেক্সটরিয়াকে সরিয়ে দেয়, আবার designModeফিরে আসে, ব্যবহারকারীর নির্বাচন পুনরুদ্ধার করে এবং পাঠ্যটি আটকায় এমন ইভেন্ট ফাংশনটিতে কল করার জন্য ইভেন্ট হ্যান্ডলারের একটি খুব সংক্ষিপ্ত টাইমার (1 মিলিসেকেন্ড বলুন) সেট করুন।

মনে রাখবেন এটি কেবল কীবোর্ডের পেস্ট ইভেন্টগুলির জন্য কাজ করবে এবং প্রসঙ্গ থেকে মেনুগুলি সম্পাদনা বা সম্পাদনা করবে না। পেস্ট ইভেন্টটি আগুন দেওয়ার সময়, কেরেটটি টেক্সারিয়ায় পুনর্নির্দেশ করতে খুব দেরি হয়েছে (কিছু ব্রাউজারে, কমপক্ষে)।

আপনার ফায়ারফক্স ২ সমর্থন করার সম্ভাব্য ঘটনাটিতে নোট করুন যে আপনাকে সেই ব্রাউজারে ডাব্লুওয়াইএসআইডাব্লুওয়াইজি সম্পাদক ইফ্রেমের ডকুমেন্টের পরিবর্তে প্যারেন্ট ডকুমেন্টে টেক্সটরিয়া স্থাপন করতে হবে।


1
বাহ, এর জন্য ধন্যবাদ! যদিও খুব পরিশীলিত হ্যাক বলে মনে হচ্ছে ;-) আপনি দয়া করে সেই ডিজাইনমড এবং নির্বাচনের জিনিসটিকে আরও কিছুটা বর্ণনা করতে পারেন, বিশেষত ৩ য় ধাপে? অনেক ধন্যবাদ!
অ্যালেক্স

5
আমার কাছে একটি ভয়াবহ অনুভূতি হয়েছিল যা আপনি এটি জিজ্ঞাসা করতে পারেন। আমি যেমন বলেছি, এটি বেশ জড়িত: আমি টিনিএমসিই বা সিকেইডিটারের উত্সটি দেখার পরামর্শ দিই, যেহেতু আমি জড়িত সমস্ত বিষয়গুলির রূপরেখার সময় পাইনি। সংক্ষেপে যদিও, designModeএটি একটি বুলিয়ান সম্পত্তি documentএবং যখন পুরো পৃষ্ঠাটি সম্পাদনযোগ্য করে তোলে true। WYSIWYG সম্পাদকরা সাধারণত designModeসম্পাদনাযোগ্য ফলক হিসাবে একটি আইফ্রেম ব্যবহার করেন। ব্যবহারকারীর নির্বাচন সংরক্ষণ এবং পুনরুদ্ধার আইইতে এবং অন্য ব্রাউজারগুলিতে অন্যভাবে করা হয়, যেমন সম্পাদকে সামগ্রীতে আটকানো হয়। আপনাকে TextRangeআইই এবং Rangeঅন্য ব্রাউজারগুলিতে একটি অর্জন করতে হবে ।
টিম ডাউন

6
@ সামুয়েল: আপনি pasteইভেন্টটি ব্যবহার করে এটি সনাক্ত করতে পারবেন তবে পেস্টটিকে অন্য উপাদানগুলিতে পুনর্নির্দেশ করতে খুব বেশি দেরি হয়ে গেছে, সুতরাং এই হ্যাকটি কার্যকর হবে না। বেশিরভাগ সম্পাদকের ফ্যালব্যাক হ'ল ব্যবহারকারীর এতে পেস্ট করার জন্য একটি ডায়ালগ দেখানো।
টিম ডাউন

6
এ সম্পর্কিত আরও কিছু তথ্য: ফায়ারফক্স আপনাকে pasteইভেন্টের অন্য উপাদানগুলির দিকে ফোকাস স্থানান্তর করতে দেয় না , তবে এটি আপনাকে উপাদানটির বিষয়বস্তু সাফ করার অনুমতি দেয় (এবং এটি একটি ভেরিয়েবলে সংরক্ষণ করে যাতে আপনি এটি পুনরুদ্ধার করতে পারেন)। যদি এই ধারকটি একটি হয় div(এটি সম্ভবত এটি iframeখুব কার্যকরভাবে কাজ করে) তবে আপনি তারপরে সাধারণ ডোম পদ্ধতি ব্যবহার করে আটকানো সামগ্রীটি সাইকেল চালাতে পারেন, বা এটি ব্যবহার করে স্ট্রিং হিসাবে পেতে পারেন innerHTML। এরপরে আপনি পূর্ববর্তী বিষয়বস্তুগুলি পুনরুদ্ধার করতে পারেন divএবং আপনার পছন্দসই সামগ্রী সন্নিবেশ করতে পারেন। ওহ, এবং আপনাকে উপরের মতো একই টাইমার হ্যাক ব্যবহার করতে হবে। আমি অবাক হয়েছি টিনিএমসিই এটি করে না ...
নিকো বার্নস

8
@ রিসিস্টডিজাইন: আমি একমত নই - এটি বোধগম্য এপিআইয়ের অভাব পূরণ করার একটি অবহেলা এবং জটিল উপায়। পেস্ট ইভেন্ট থেকে সরাসরি আটকানো সামগ্রী পেতে সক্ষম হওয়া আরও ভাল হবে, যা কিছু ব্রাউজারে সীমিত উপায়ে সম্ভব
টিম ডাউন

317

সমাধান # 1 (কেবলমাত্র সরল পাঠ্য এবং ফায়ারফক্স 22+ প্রয়োজন)

আইআই 6 +, এফএফ 22+, ক্রোম, সাফারি, এজ জন্য কাজ করে (কেবল আইই 9 + তে পরীক্ষা করা হয়েছে, তবে কম সংস্করণে কাজ করা উচিত)

এইচটিএমএল বা ফায়ারফক্স <= 22 পেস্ট করার জন্য আপনার যদি সমর্থন প্রয়োজন হয় তবে সমাধান # 2 দেখুন।

এইচটিএমএল

<div id='editableDiv' contenteditable='true'>Paste</div>

জাভাস্ক্রিপ্ট

function handlePaste (e) {
    var clipboardData, pastedData;

    // Stop data actually being pasted into div
    e.stopPropagation();
    e.preventDefault();

    // Get pasted data via clipboard API
    clipboardData = e.clipboardData || window.clipboardData;
    pastedData = clipboardData.getData('Text');

    // Do whatever with pasteddata
    alert(pastedData);
}

document.getElementById('editableDiv').addEventListener('paste', handlePaste);

জেএসফিডাল: https://jsfiddle.net/swL8ftLs/12/

নোট করুন যে এই সমাধানটি getDataফাংশনের জন্য 'পাঠ্য' পরামিতিটি ব্যবহার করে , যা অ-মানক। তবে এটি লেখার সময় সমস্ত ব্রাউজারে কাজ করে।


সমাধান # 2 (এইচটিএমএল এবং ফায়ারফক্সের জন্য কাজ <<22)

আইআই 6 +, এফএফ 3.5+, ক্রোম, সাফারি, এজতে পরীক্ষিত

এইচটিএমএল

<div id='div' contenteditable='true'>Paste</div>

জাভাস্ক্রিপ্ট

var editableDiv = document.getElementById('editableDiv');

function handlepaste (e) {
    var types, pastedData, savedContent;

    // Browsers that support the 'text/html' type in the Clipboard API (Chrome, Firefox 22+)
    if (e && e.clipboardData && e.clipboardData.types && e.clipboardData.getData) {

        // Check for 'text/html' in types list. See abligh's answer below for deatils on
        // why the DOMStringList bit is needed. We cannot fall back to 'text/plain' as
        // Safari/Edge don't advertise HTML data even if it is available
        types = e.clipboardData.types;
        if (((types instanceof DOMStringList) && types.contains("text/html")) || (types.indexOf && types.indexOf('text/html') !== -1)) {

            // Extract data and pass it to callback
            pastedData = e.clipboardData.getData('text/html');
            processPaste(editableDiv, pastedData);

            // Stop the data from actually being pasted
            e.stopPropagation();
            e.preventDefault();
            return false;
        }
    }

    // Everything else: Move existing element contents to a DocumentFragment for safekeeping
    savedContent = document.createDocumentFragment();
    while(editableDiv.childNodes.length > 0) {
        savedContent.appendChild(editableDiv.childNodes[0]);
    }

    // Then wait for browser to paste content into it and cleanup
    waitForPastedData(editableDiv, savedContent);
    return true;
}

function waitForPastedData (elem, savedContent) {

    // If data has been processes by browser, process it
    if (elem.childNodes && elem.childNodes.length > 0) {

        // Retrieve pasted content via innerHTML
        // (Alternatively loop through elem.childNodes or elem.getElementsByTagName here)
        var pastedData = elem.innerHTML;

        // Restore saved content
        elem.innerHTML = "";
        elem.appendChild(savedContent);

        // Call callback
        processPaste(elem, pastedData);
    }

    // Else wait 20ms and try again
    else {
        setTimeout(function () {
            waitForPastedData(elem, savedContent)
        }, 20);
    }
}

function processPaste (elem, pastedData) {
    // Do whatever with gathered data;
    alert(pastedData);
    elem.focus();
}

// Modern browsers. Note: 3rd argument is required for Firefox <= 6
if (editableDiv.addEventListener) {
    editableDiv.addEventListener('paste', handlepaste, false);
}
// IE <= 8
else {
    editableDiv.attachEvent('onpaste', handlepaste);
}

জেএসফিডাল: https://jsfiddle.net/nicoburns/wrqmuabo/23/

ব্যাখ্যা

onpasteঘটনা divহয়েছে handlePaste: ফাংশন থেকে সংযুক্ত ও একটি একক যুক্তি পাস eventপেস্ট ইভেন্টের জন্য বস্তু। আমাদের কাছে বিশেষ আগ্রহের বিষয় হ'ল clipboardDataএই ইভেন্টটির সম্পত্তি যা অ-ie ব্রাউজারগুলিতে ক্লিপবোর্ড অ্যাক্সেস সক্ষম করে। আইই তে সমতুল্য window.clipboardData, যদিও এর কিছুটা আলাদা আলাদা এপিআই রয়েছে।

নীচে সম্পদ বিভাগ দেখুন।


handlepasteফাংশন:

এই ফাংশন দুটি শাখা আছে।

অস্তিত্বের অস্তিত্বের জন্য প্রথম চেক করে event.clipboardDataএবং এটির typesসম্পত্তিটিতে 'টেক্সট / এইচটিএমএল' রয়েছে কিনা তা যাচাই করে ( পদ্ধতিটি ব্যবহার করে যাচাই করা হয় , অথবা পদ্ধতিটি ব্যবহার করে পরীক্ষা করা একটি স্ট্রিং typesহতে পারে )। যদি এই সমস্ত শর্ত পূরণ হয়, তবে আমরা 'টেক্সট / প্লেইন' এর পরিবর্তে 'টেক্সট / এইচটিএমএল' বাদ দিয়ে সমাধান # 1 হিসাবে এগিয়ে যাই। এটি বর্তমানে ক্রোম এবং ফায়ারফক্স 22+ এ কাজ করে।DOMStringListcontainsindexOf

যদি এই পদ্ধতিটি সমর্থিত না হয় (অন্য সমস্ত ব্রাউজার), তবে আমরা

  1. উপাদান উপাদানগুলি একটিতে সংরক্ষণ করুন DocumentFragment
  2. উপাদানটি খালি করুন
  3. waitForPastedDataফাংশন কল করুন

waitforpastedataফাংশন:

এই ফাংশনটি প্রথম পেস্ট করা তথ্যের জন্য পোলস (20 মেন একবারে), যা প্রয়োজনীয় কারণ এটি সরাসরি প্রদর্শিত হয় না। যখন ডেটা এটি প্রদর্শিত হবে:

  1. পরিবর্তনশীলগুলিতে সম্পাদনাযোগ্য ডিভের অভ্যন্তরীণ এইচটিএমএল (যা এখন আটকানো ডেটা) সংরক্ষণ করে
  2. ডকুমেন্টফ্রেগমেন্টে সংরক্ষিত সামগ্রী পুনরুদ্ধার করে
  3. পুনরুদ্ধার করা ডেটা সহ 'প্রসেসপাস্ট' ফাংশন কল করে

processpasteফাংশন:

আটকানো ডেটা দিয়ে নির্বিচারে জিনিসগুলি করে। এক্ষেত্রে আমরা কেবল তথ্য সতর্ক করি, আপনি যা খুশি তা করতে পারেন। আপনি সম্ভবত কোনও ধরণের ডেটা স্যানিটাইজিং প্রক্রিয়াটির মাধ্যমে আটকানো ডেটা চালাতে চান।


কার্সার অবস্থান সংরক্ষণ এবং পুনরুদ্ধার

সত্যিকারের পরিস্থিতিতে আপনি সম্ভবত নির্বাচনটি আগে সংরক্ষণ করতে এবং তারপরে পুনরুদ্ধার করতে চান ( বিষয়বস্তুতে কার্সারের অবস্থান নির্ধারণযোগ্য <ডিভি>> )। ব্যবহারকারী যখন পেস্ট ক্রিয়াটি শুরু করেছিলেন তখন আপনি কার্সারটি যে অবস্থানে রেখেছিলেন সে ক্ষেত্রে আপনি আটকানো ডেটা sertোকাতে পারেন।

সম্পদ:

একটি ডকুমেন্টফ্রেগমেন্ট ব্যবহারের পরামর্শ দেওয়ার জন্য টিম ডাউনকে ধন্যবাদ জানাই, এবং ক্লিপবোর্ডডেটা.প্রকারের স্ট্রিংয়ের পরিবর্তে ডিওএমএস স্ট্রিংলিস্ট ব্যবহারের কারণে ফায়ারফক্সে ত্রুটি ধরার জন্য প্রশস্ত


4
মজাদার. আমি ভেবেছিলাম আগে আমি এটি চেষ্টা করেছি এবং এটি কোনও ব্রাউজারে কাজ করে নি, তবে আমি নিশ্চিত যে আপনি ঠিক বলেছেন। আমি স্পষ্টতই বেশ কয়েকটি কারণে DocumentFragmentব্যবহার করার পরিবর্তে বিদ্যমান সামগ্রীতে স্থানান্তরিত করতে পছন্দ করব innerHTML: প্রথমত, আপনি কোনও বিদ্যমান ইভেন্ট হ্যান্ডলার রাখেন; দ্বিতীয়ত, সংরক্ষণ এবং পুনরুদ্ধার innerHTMLপূর্ববর্তী ডিওমের একটি অনুলিপি তৈরি করার গ্যারান্টিযুক্ত নয়; তৃতীয়, আপনি তারপরে Rangeমার্কার উপাদান যুক্ত করে বা পাঠ্য অফসেটগুলি গণনা করে (যা আপনি যদি ব্যবহার করেন তবে আপনাকে যা করতে হবে innerHTML) তার চেয়ে বেশি দোষ না দিয়ে নির্বাচনটিকে সংরক্ষণ করতে পারেন ।
টিম ডাউন

3
সত্যিই কোনও সামগ্রীর ঝলক নেই (FONC?), যা স্পষ্টভাবে আরও খারাপ হবে যদি পেস্ট করা সামগ্রীর প্রসেসিংয়ে কিছুটা সময় লাগে। বিটিডব্লিউ, DocumentFragmentআইই- তে কেন একটি ব্যথা সঞ্চার করছে? এটি অন্য ব্রাউজারগুলির মতোই, যদি না আপনি কোনও রেঞ্জ ব্যবহার করেন এবং extractContents()না করেন, যা কোনও ক্ষেত্রে বিকল্পের চেয়ে সংক্ষিপ্ত নয়। আমি আপনার কৌশলটির একটি উদাহরণ প্রয়োগ করেছি, ব্রাউজারগুলিতে জিনিসগুলি সুন্দর এবং অভিন্ন রাখতে রঙিন ব্যবহার করে: jsfiddle.net/bQeWC/4
টিম ডাউন

1
@ মার্টিন: আমি মন্তব্যগুলিতে পোস্ট করা জেএসফিডাল ডেমো সাহায্য করতে পারে।
টিম ডাউন

1
মনে হচ্ছে উইন্ডোজের জন্য ফায়ারফক্স 28 (কমপক্ষে) এ আর কাজ করে না। এটি waitforpastedataফাংশন থেকে কখনই বাইরে যায় না
অলিবয় 50

1
এফওয়াইআই: এজ এখন ডাব্লু text/html3 সি ক্লিপবোর্ড এপিআই ব্যবহার করে মাইম টাইপের সাহায্যে ডেটা পড়ার সমর্থন করে। অতীতে এই ধরনের একটি প্রচেষ্টা ব্যতিক্রম ছুঁড়ে মারবে। সুতরাং এজের জন্য এখন আর কারও পক্ষে এই কাজের / হ্যাকের প্রয়োজন নেই।
জেনি ও'রিলি

130

সাধারণ সংস্করণ:

document.querySelector('[contenteditable]').addEventListener('paste', (e) => {
    e.preventDefault();
    const text = (e.originalEvent || e).clipboardData.getData('text/plain');
    window.document.execCommand('insertText', false, text);
});

ব্যবহার clipboardData

ডেমো: http://jsbin.com/nozifexasu/edit?js , আউটপুট

এজ, ফায়ারফক্স, ক্রোম, সাফারি, অপেরা পরীক্ষা করা হয়েছে।

ডকুমেন্ট.এক্সেকমন্ড () এখন অপ্রচলিত


দ্রষ্টব্য: সার্ভার- সাইডেও ইনপুট / আউটপুট পরীক্ষা করতে ভুলবেন না (যেমন পিএইচপি স্ট্রিপ-ট্যাগগুলি )


4
এটি সত্যই ভাল কাজ করে তবে আইই এর কোনও সংস্করণই ইভেন্ট থেকে ক্লিপবোর্ডের ডেটা অ্যাক্সেসের অনুমতি দেয় না :( দুর্দান্ত সমাধান, যদিও এটি আরও বেশি হওয়া উচিত!
এরিক উড

1
দেখে মনে হচ্ছে আপনি IE তে অন্যভাবে ক্লিপবোর্ডের ডেটা পেতে পারেন, সুতরাং আপনি যদি আইটি সনাক্ত করেন তবে প্রম্পট ফ্যালব্যাকের
অ্যান্ড্রু

4
এখনও অবধি সেরা ক্রস ব্রাউজার উত্তর পাওয়া গেছে। শুধু আইই এবং এর নিখুঁত জন্য কোড যুক্ত করুন।
আর্টুরো

6
এটি IE এ কাজ করে (আহ, মিষ্টি, বিপরীতে আইই)window.clipboardData.getData('Text');
বেনজিনিয়ার

9
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); }
ইউকুলেলিক্স

26

সরাসরি নমুনা

Chrome / FF / IE11 এ পরীক্ষিত

একটি ক্রোম / আইই বিরক্তি রয়েছে যা হ'ল এই ব্রাউজারগুলি <div>প্রতিটি নতুন লাইনের জন্য উপাদান যুক্ত করে । এখানে এই সম্পর্কে একটি পোস্ট আছে এবং এটি বিতর্কযোগ্য উপাদান সেট করে স্থির করা যেতে পারেdisplay:inline-block

কিছু হাইলাইটেড এইচটিএমএল নির্বাচন করুন এবং এটি এখানে আটকান:

function onPaste(e){
  var content;
  e.preventDefault();

  if( e.clipboardData ){
    content = e.clipboardData.getData('text/plain');
    document.execCommand('insertText', false, content);
    return false;
  }
  else if( window.clipboardData ){
    content = window.clipboardData.getData('Text');
    if (window.getSelection)
      window.getSelection().getRangeAt(0).insertNode( document.createTextNode(content) );
  }
}


/////// EVENT BINDING /////////
document.querySelector('[contenteditable]').addEventListener('paste', onPaste);
[contenteditable]{ 
  /* chroem bug: https://stackoverflow.com/a/24689420/104380 */
  display:inline-block;
  width: calc(100% - 40px);
  min-height:120px; 
  margin:10px;
  padding:10px;
  border:1px dashed green;
}

/* 
 mark HTML inside the "contenteditable"  
 (Shouldn't be any OFC!)'
*/
[contenteditable] *{
  background-color:red;
}
<div contenteditable></div>


1
আমার সরল পাঠ্য বৈশিষ্ট্য হিসাবে একটি পেস্ট দরকার। IE9 এবং IE10 এ পরীক্ষা করা হয়েছে এবং দুর্দান্ত কাজ করে। বড় ব্রাউজারগুলিতেও এটি কাজ করে তা উল্লেখ করার দরকার নেই ... ধন্যবাদ।
সাভাস বেদোভা

2
আপনার কোডটিতে একটি বাগ রয়েছে: যদি (e.originalEvent.clipboardData) কোনও এনপিই সৃষ্টি করতে পারে কারণ আপনি জানেন না যে e.originalEvent সেই সময়ে উপস্থিত রয়েছে
সেবাস্তিয়ান

15

আমি টিম ডাউনস প্রস্তাবনাটির জন্য এখানে অফ-স্ক্রিন টেক্সারিয়া দিয়ে ধারণাটির সামান্য প্রমাণ লিখেছি। এবং কোডটি এখানে যায়:

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
<script language="JavaScript">
 $(document).ready(function()
{

var ctrlDown = false;
var ctrlKey = 17, vKey = 86, cKey = 67;

$(document).keydown(function(e)
{
    if (e.keyCode == ctrlKey) ctrlDown = true;
}).keyup(function(e)
{
    if (e.keyCode == ctrlKey) ctrlDown = false;
});

$(".capture-paste").keydown(function(e)
{
    if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){
        $("#area").css("display","block");
        $("#area").focus();         
    }
});

$(".capture-paste").keyup(function(e)
{
    if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){                      
        $("#area").blur();
        //do your sanitation check or whatever stuff here
        $("#paste-output").text($("#area").val());
        $("#area").val("");
        $("#area").css("display","none");
    }
});

});
</script>

</head>
<body class="capture-paste">

<div id="paste-output"></div>


    <div>
    <textarea id="area" style="display: none; position: absolute; left: -99em;"></textarea>
    </div>

</body>
</html>

কেবলমাত্র একটি এইচটিএমএল ফাইলে পুরো কোডটি অনুলিপি করুন এবং আটকান এবং নথির যে কোনও জায়গায় ক্লিপবোর্ড থেকে পাঠ্য (ctrl-v ব্যবহার করে) আটকে দেওয়ার চেষ্টা করুন।

আমি এটি IE9 এবং ফায়ারফক্স, ক্রোম এবং অপেরা এর নতুন সংস্করণে পরীক্ষা করেছি। বেশ ভাল কাজ করে। এছাড়াও এটি ভাল যে কেউ এই কার্যকারিতাটি ট্রিগার করতে তার পছন্দসই যে কী কী সংমিশ্রণটি ব্যবহার করতে পারেন। অবশ্যই jQuery উত্স অন্তর্ভুক্ত করতে ভুলবেন না।

এই কোডটি নির্দ্বিধায় ব্যবহার করুন এবং যদি আপনি কিছু উন্নতি বা সমস্যা নিয়ে আসেন তবে দয়া করে এগুলি আবার পোস্ট করুন। এছাড়াও নোট করুন যে আমি কোনও জাভাস্ক্রিপ্ট বিকাশকারী নই তাই আমি কিছু হারিয়ে ফেলতে পারি (=> নিজের টেস্টিগনটি করে)।


ম্যাকগুলি সিটিআরএল-ভি দিয়ে পেস্ট করে না, তারা সেমিডি-ভি ব্যবহার করে। সুতরাং 17
টির

2
অথবা হয়ত এটা সবসময় 91 নয়: stackoverflow.com/questions/3834175/... হোক না কেন, আমি প্রায় নিশ্চিত, jQuery হ্যান্ডলগুলি যে সব তোমার জন্য, শুধু পরীক্ষা e.ctrlKey বা e.metaKey আমি মনে করি আছি।
জেরেমি টি

3
e.ctrlKey বা e.metaKey জাভাস্ক্রিপ্ট DOM এর অংশ, jQuery নয়: developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
rvighne

2
আমি মনে করি না এটি ডান ক্লিক এবং পেস্ট করার জন্য কাজ করে। অনেক লোক এই পদ্ধতিকে গ্রহণ করে।
এরিক উড

10

L2aelba আনসার এর উপর ভিত্তি করে । এটি এফএফ, সাফারি, ক্রোম, আইই (8,9,10 এবং 11) এ পরীক্ষা করা হয়েছিল

    $("#editText").on("paste", function (e) {
        e.preventDefault();

        var text;
        var clp = (e.originalEvent || e).clipboardData;
        if (clp === undefined || clp === null) {
            text = window.clipboardData.getData("text") || "";
            if (text !== "") {
                if (window.getSelection) {
                    var newNode = document.createElement("span");
                    newNode.innerHTML = text;
                    window.getSelection().getRangeAt(0).insertNode(newNode);
                } else {
                    document.selection.createRange().pasteHTML(text);
                }
            }
        } else {
            text = clp.getData('text/plain') || "";
            if (text !== "") {
                document.execCommand('insertText', false, text);
            }
        }
    });

আইই-তে পেস্ট করার সময় নতুন লাইন সংরক্ষণের কোনও উপায় আছে?
থাকুন

10

এটি কোনও সেটটাইমআউট () ব্যবহার করে না।

আমি ক্রস ব্রাউজার সমর্থন অর্জন করতে এই দুর্দান্ত নিবন্ধটি ব্যবহার করেছি ।

$(document).on("focus", "input[type=text],textarea", function (e) {
    var t = e.target;
    if (!$(t).data("EventListenerSet")) {
        //get length of field before paste
        var keyup = function () {
            $(this).data("lastLength", $(this).val().length);
        };
        $(t).data("lastLength", $(t).val().length);
        //catch paste event
        var paste = function () {
            $(this).data("paste", 1);//Opera 11.11+
        };
        //process modified data, if paste occured
        var func = function () {
            if ($(this).data("paste")) {
                alert(this.value.substr($(this).data("lastLength")));
                $(this).data("paste", 0);
                this.value = this.value.substr(0, $(this).data("lastLength"));
                $(t).data("lastLength", $(t).val().length);
            }
        };
        if (window.addEventListener) {
            t.addEventListener('keyup', keyup, false);
            t.addEventListener('paste', paste, false);
            t.addEventListener('input', func, false);
        }
        else {//IE
            t.attachEvent('onkeyup', function () {
                keyup.call(t);
            });
            t.attachEvent('onpaste', function () {
                paste.call(t);
            });
            t.attachEvent('onpropertychange', function () {
                func.call(t);
            });
        }
        $(t).data("EventListenerSet", 1);
    }
}); 

এই কোডটি পেস্টের আগে নির্বাচনের হ্যান্ডেল দিয়ে প্রসারিত: ডেমো


+1 আমি নিকো বার্নসের চেয়ে এটিকে আরও ভাল পছন্দ করি, যদিও আমি মনে করি প্রত্যেকটির নিজস্ব জায়গা আছে।
n0nag0n

5

আটকানো পাঠ্য পরিষ্কার করার জন্য এবং বর্তমানে নির্বাচিত পাঠ্যটি পেস্ট করা পাঠ্যের সাথে প্রতিস্থাপন করা বিষয়টি খুব তুচ্ছ বিষয়:

<div id='div' contenteditable='true' onpaste='handlepaste(this, event)'>Paste</div>

জাতীয়:

function handlepaste(el, e) {
  document.execCommand('insertText', false, e.clipboardData.getData('text/plain'));
  e.preventDefault();
}

আপনি কাজ করতে পারেন এমন কোনও ডেমো পৃষ্ঠা সরবরাহ করতে পারেন? আমি চেষ্টা করেছি এবং এটি কাজ করে না
vsync

5

এটি সেই সমস্ত ব্রাউজারগুলিতে কাজ করা উচিত যা অনপেষ্ট ইভেন্ট এবং মিউটেশন পর্যবেক্ষককে সমর্থন করে।

এই সমাধানটি কেবলমাত্র পাঠ্য পাওয়ার বাইরে এক ধাপ এগিয়ে চলেছে, এটি আসলে আপনাকে কোনও উপাদানটিতে আটকানো হওয়ার আগে আটকানো সামগ্রী সম্পাদনা করার অনুমতি দেয়।

এটি কনটেনটেটেবল, অনপাস্ট ইভেন্ট (সমস্ত বড় ব্রাউজার দ্বারা সমর্থিত) এবং মিউটেশন পর্যবেক্ষক (ক্রোম, ফায়ারফক্স এবং আইআই 11 + দ্বারা সমর্থিত) ব্যবহার করে কাজ করে

ধাপ 1

তর্কযোগ্য একটি HTML- উপাদান তৈরি করুন

<div contenteditable="true" id="target_paste_element"></div>

ধাপ ২

আপনার জাভাস্ক্রিপ্ট কোডে নিম্নলিখিত ইভেন্টটি যুক্ত করুন

document.getElementById("target_paste_element").addEventListener("paste", pasteEventVerifierEditor.bind(window, pasteCallBack), false);

আমাদের পেস্টক্যালব্যাক বাঁধতে হবে, যেহেতু মিউটেশন পর্যবেক্ষককে অ্যাসিঙ্ক্রোনসিভ বলা হবে।

ধাপ 3

আপনার কোডে নিম্নলিখিত ফাংশন যুক্ত করুন

function pasteEventVerifierEditor(callback, e)
{
   //is fired on a paste event. 
    //pastes content into another contenteditable div, mutation observer observes this, content get pasted, dom tree is copied and can be referenced through call back.
    //create temp div
    //save the caret position.
    savedCaret = saveSelection(document.getElementById("target_paste_element"));

    var tempDiv = document.createElement("div");
    tempDiv.id = "id_tempDiv_paste_editor";
    //tempDiv.style.display = "none";
    document.body.appendChild(tempDiv);
    tempDiv.contentEditable = "true";

    tempDiv.focus();

    //we have to wait for the change to occur.
    //attach a mutation observer
    if (window['MutationObserver'])
    {
        //this is new functionality
        //observer is present in firefox/chrome and IE11
        // select the target node
        // create an observer instance
        tempDiv.observer = new MutationObserver(pasteMutationObserver.bind(window, callback));
        // configuration of the observer:
        var config = { attributes: false, childList: true, characterData: true, subtree: true };

        // pass in the target node, as well as the observer options
        tempDiv.observer.observe(tempDiv, config);

    }   

}



function pasteMutationObserver(callback)
{

    document.getElementById("id_tempDiv_paste_editor").observer.disconnect();
    delete document.getElementById("id_tempDiv_paste_editor").observer;

    if (callback)
    {
        //return the copied dom tree to the supplied callback.
        //copy to avoid closures.
        callback.apply(document.getElementById("id_tempDiv_paste_editor").cloneNode(true));
    }
    document.body.removeChild(document.getElementById("id_tempDiv_paste_editor"));

}

function pasteCallBack()
{
    //paste the content into the element.
    restoreSelection(document.getElementById("target_paste_element"), savedCaret);
    delete savedCaret;

    pasteHtmlAtCaret(this.innerHTML, false, true);
}   


saveSelection = function(containerEl) {
if (containerEl == document.activeElement)
{
    var range = window.getSelection().getRangeAt(0);
    var preSelectionRange = range.cloneRange();
    preSelectionRange.selectNodeContents(containerEl);
    preSelectionRange.setEnd(range.startContainer, range.startOffset);
    var start = preSelectionRange.toString().length;

    return {
        start: start,
        end: start + range.toString().length
    };
}
};

restoreSelection = function(containerEl, savedSel) {
    containerEl.focus();
    var charIndex = 0, range = document.createRange();
    range.setStart(containerEl, 0);
    range.collapse(true);
    var nodeStack = [containerEl], node, foundStart = false, stop = false;

    while (!stop && (node = nodeStack.pop())) {
        if (node.nodeType == 3) {
            var nextCharIndex = charIndex + node.length;
            if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
                range.setStart(node, savedSel.start - charIndex);
                foundStart = true;
            }
            if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
                range.setEnd(node, savedSel.end - charIndex);
                stop = true;
            }
            charIndex = nextCharIndex;
        } else {
            var i = node.childNodes.length;
            while (i--) {
                nodeStack.push(node.childNodes[i]);
            }
        }
    }

    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
}

function pasteHtmlAtCaret(html, returnInNode, selectPastedContent) {
//function written by Tim Down

var sel, range;
if (window.getSelection) {
    // IE9 and non-IE
    sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
        range = sel.getRangeAt(0);
        range.deleteContents();

        // Range.createContextualFragment() would be useful here but is
        // only relatively recently standardized and is not supported in
        // some browsers (IE9, for one)
        var el = document.createElement("div");
        el.innerHTML = html;
        var frag = document.createDocumentFragment(), node, lastNode;
        while ( (node = el.firstChild) ) {
            lastNode = frag.appendChild(node);
        }
        var firstNode = frag.firstChild;
        range.insertNode(frag);

        // Preserve the selection
        if (lastNode) {
            range = range.cloneRange();
            if (returnInNode)
            {
                range.setStart(lastNode, 0); //this part is edited, set caret inside pasted node.
            }
            else
            {
                range.setStartAfter(lastNode); 
            }
            if (selectPastedContent) {
                range.setStartBefore(firstNode);
            } else {
                range.collapse(true);
            }
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
} else if ( (sel = document.selection) && sel.type != "Control") {
    // IE < 9
    var originalRange = sel.createRange();
    originalRange.collapse(true);
    sel.createRange().pasteHTML(html);
    if (selectPastedContent) {
        range = sel.createRange();
        range.setEndPoint("StartToStart", originalRange);
        range.select();
    }
}
}

কোডটি কী করে:

  1. কেউ সিটিআরএল-ভি, প্রসঙ্গ এবং অন্য কোনও উপায়ে পেস্ট ইভেন্টটিকে আগুন ধরিয়ে দেয়
  2. পেস্ট ইভেন্টে তৃপ্তিযুক্ত একটি নতুন উপাদান তৈরি করা হয়েছে (সন্তুষ্ট সহ একটি উপাদান উচ্চতর সুযোগসুবিধা অর্জন করেছে)
  3. লক্ষ্য উপাদানটির ক্যারেট অবস্থানটি সংরক্ষণ করা হয়।
  4. ফোকাসটি নতুন উপাদানটিতে সেট করা আছে
  5. সামগ্রীটি নতুন উপাদানটিতে আটকানো হয়ে যায় এবং এটি ডিওএম-এ রেন্ডার হয়।
  6. মিউটেশন পর্যবেক্ষক এটি ধরেন (এটি ডোম গাছ এবং সামগ্রীতে সমস্ত পরিবর্তন নিবন্ধভুক্ত করে)। তারপরে মিউটেশন ইভেন্টে গুলি চালায়।
  7. আটকানো সামগ্রীর ডোমটি একটি ভেরিয়েবলের মধ্যে ক্লোন হয়ে যায় এবং কলব্যাকে ফিরে আসে। অস্থায়ী উপাদান ধ্বংস হয়।
  8. কলব্যাক ক্লোনড ডিওএম গ্রহণ করে। ক্যারেটটি পুনরুদ্ধার করা হয়েছে। আপনি আপনার টার্গেটে এটি যুক্ত করার আগে আপনি এটি সম্পাদনা করতে পারেন। উপাদান। এই উদাহরণে আমি ক্যারেট সংরক্ষণ / পুনরুদ্ধার করার জন্য এবং উপাদানটিতে এইচটিএমএল আটকানোর জন্য টিম ডাউনস ফাংশনগুলি ব্যবহার করছি।

উদাহরণ


টিম ডাউনকে অনেক ধন্যবাদ উত্তরের জন্য এই পোস্টটি দেখুন:

পেস্ট ইভেন্টে নথিটিতে আটকানো সামগ্রী পান


4

আমার পক্ষে কাজ করে এমন সমাধানটি যদি আপনি কোনও পাঠ্য ইনপুটটিতে আটকানো হয় তবে ইভেন্টটি শ্রোতার সাথে ইভেন্টটি আটকে দিচ্ছে। যেহেতু পেস্ট ইভেন্টটি ইনপুট পরিবর্তনে পাঠ্যের আগে ঘটে থাকে তাই আমার অন পেস্ট হ্যান্ডলারের অভ্যন্তরে আমি একটি মুলতুবি ফাংশন তৈরি করি যার মধ্যে আমি আমার ইনপুট বাক্সে পরিবর্তনগুলি পরীক্ষা করে যা পেস্টে ঘটেছিল:

onPaste: function() {
    var oThis = this;
    setTimeout(function() { // Defer until onPaste() is done
        console.log('paste', oThis.input.value);
        // Manipulate pasted input
    }, 1);
}

2
হরর, দুর্ভাগ্যবশত, আমাদের কাজের বিবরণের একটি অংশ;) তবে আমি সম্মত, এটি একটি হ্যাক এবং অন্যান্য সমস্ত বিকল্প শেষ হয়ে গেলে হ্যাকগুলি কেবলমাত্র ব্যবহার করা উচিত।
লেেক্স

4

নিকোর উত্তরের মন্তব্যের জন্য এটি খুব দীর্ঘ ছিল, যা আমি ফায়ারফক্সে আর (মন্তব্য অনুসারে) কাজ করে বলে মনে করি না, এবং সাফারিতে আমার পক্ষে কাজ করেনি।

প্রথমত, আপনি এখন ক্লিপবোর্ড থেকে সরাসরি পড়তে পারবেন বলে মনে হয়। কোডের মতো:

if (/text\/plain/.test(e.clipboardData.types)) {
    // shouldn't this be writing to elem.value for text/plain anyway?
    elem.innerHTML = e.clipboardData.getData('text/plain');
}

ব্যবহার করুন:

types = e.clipboardData.types;
if (((types instanceof DOMStringList) && types.contains("text/plain")) ||
    (/text\/plain/.test(types))) {
    // shouldn't this be writing to elem.value for text/plain anyway?
    elem.innerHTML = e.clipboardData.getData('text/plain');
}

কারণ ফায়ারফক্সের এমন একটি typesক্ষেত্র রয়েছে যা DOMStringListবাস্তবায়ন করে না test

contenteditable=trueক্ষেত্রের উপর দৃষ্টি নিবদ্ধ না করা হলে পরবর্তী ফায়ারফক্স পেস্টের অনুমতি দেয় না ।

অবশেষে, ফায়ারফক্স নির্ভরযোগ্যভাবে পেস্টের অনুমতি দেবে না যতক্ষণ না ফোকাস কেবল textarea(বা সম্ভবত ইনপুট) না থাকে যা কেবলমাত্র নয়contenteditable=true তবে:

  • না display:none
  • না visibility:hidden
  • শূন্য আকারের নয়

আমি পাঠ্য ক্ষেত্রটি আড়াল করার চেষ্টা করছিলাম যাতে আমি জেএস ভিএনসি এমুলেটরের উপর পেস্টের কাজটি করতে পারি (যেমন এটি কোনও দূরবর্তী ক্লায়েন্টের কাছে গিয়েছিল এবং এতে textareaআটকানোর জন্য আসলে কিছুই ছিল না )। আমি উপরের পাঠ্য ক্ষেত্রটি লুকানোর চেষ্টা করলাম যেখানে এটি কখনও কখনও লক্ষণ দেখা দেয় তবে সাধারণত দ্বিতীয় পেস্টে ব্যর্থ হয় (বা ক্ষেত্রটি যখন একই তথ্য দু'বার প্যাস্ট করা রোধ করতে পরিষ্কার করা হয়) ক্ষেত্রের ফোকাসটি হারাতে থাকে এবং সঠিকভাবে পুনরায় ফিরে পাওয়া যায় না এটা সত্ত্বেও focus()। আমি যে সমাধানটি নিয়ে এসেছি তা হ'ল এটি রাখা z-order: -1000, তৈরি করা display:none, এটি 1px দ্বারা 1px হিসাবে করা এবং সমস্ত রঙ স্বচ্ছতে সেট করা। ইশ।

সাফারি, আপনি উপরের দ্বিতীয় অংশ প্রযোজ্য, অর্থাত আপনি যদি একটি থাকতে হবে textareaযা নয় display:none


ব্রাউজার রেন্ডারিং ইঞ্জিনগুলিতে কাজ করে এমন বিকাশকারীদের ডকুমেন্টেশন সাইটগুলিতে একটি পৃষ্ঠা বা স্থান থাকতে হবে যা তারা কাজ করে এমন বৈশিষ্ট্যগুলি সম্পর্কে নোটে লেখার জন্য ব্যবহার করতে পারে। উদাহরণস্বরূপ, যদি তারা পেস্ট ফাংশনে কাজ করে তবে তারা যুক্ত করবে, "প্রদর্শন কোনওটি না থাকলে আটকানো কাজ করবে না, দৃশ্যমানতা লুকানো আছে বা আকার শূন্য হবে"।
1.21 গিগাওয়াট

3

প্রথম যে মনে আসে liberal এর সংক্ষিপ্ত রূপ গুগলের শেষ হওযার pastehandler হয় http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/pastehandler.html


এইটিকে নিরাপদে কোনও পেস্ট ইভেন্ট সনাক্ত করা হয়েছে বলে মনে হচ্ছে, তবে এটি আটকানো সামগ্রীটি ধরা / ফিরিয়ে দিতে সক্ষম হবে না বলে মনে হচ্ছে?
অ্যালেক্স

@ অ্যালেক্স: আপনি সঠিক, এবং এটি কেবল টেক্সারিয়াসের সাথেই কাজ করে, সমৃদ্ধ পাঠ্য সম্পাদক নয়।
টিম ডাউন

3

সহজ সমাধান:

document.onpaste = function(e) {
    var pasted = e.clipboardData.getData('Text');
    console.log(pasted)
}

2

এটি আমার পক্ষে কাজ করেছে:

function onPasteMe(currentData, maxLen) {
    // validate max length of pasted text
    var totalCharacterCount = window.clipboardData.getData('Text').length;
}

<input type="text" onPaste="return onPasteMe(this, 50);" />

2
function myFunct( e ){
    e.preventDefault();

    var pastedText = undefined;
    if( window.clipboardData && window.clipboardData.getData ){
    pastedText = window.clipboardData.getData('Text');
} 
else if( e.clipboardData && e.clipboardData.getData ){
    pastedText = e.clipboardData.getData('text/plain');
}

//work with text

}
document.onpaste = myFunct;

1

আপনি এইভাবে এটি করতে পারেন:

প্রাক & পোস্ট পেস্ট ইভেন্টগুলির জন্য এই jQuery প্লাগইনটি ব্যবহার করুন:

$.fn.pasteEvents = function( delay ) {
    if (delay == undefined) delay = 20;
    return $(this).each(function() {
        var $el = $(this);
        $el.on("paste", function() {
            $el.trigger("prepaste");
            setTimeout(function() { $el.trigger("postpaste"); }, delay);
        });
    });
};

এখন আপনি এই প্লাগইন ব্যবহার করতে পারেন ;:

$('#txt').on("prepaste", function() { 

    $(this).find("*").each(function(){

        var tmp=new Date.getTime();
        $(this).data("uid",tmp);
    });


}).pasteEvents();

$('#txt').on("postpaste", function() { 


  $(this).find("*").each(function(){

     if(!$(this).data("uid")){
        $(this).removeClass();
          $(this).removeAttr("style id");
      }
    });
}).pasteEvents();

Explaination

প্রথমে বিদ্যমান বৈশিষ্ট্যগুলির জন্য ডেটা অ্যাট্রিবিউট হিসাবে একটি ইউড সেট করুন।

তারপরে সমস্ত নোডের POST PASTE ইভেন্টের তুলনা করুন। সুতরাং তুলনা করে আপনি সদ্য সন্নিবেশিতটিকে শনাক্ত করতে পারেন কারণ তাদের একটি ইউআইডি থাকবে, তবে কেবল নতুন তৈরি উপাদান থেকে স্টাইল / শ্রেণি / আইডি বৈশিষ্ট্যটি সরিয়ে ফেলুন, যাতে আপনি আপনার পুরানো বিন্যাসটি রাখতে পারেন।



1

ব্রাউজারটিকে কেবল তার সামগ্রী সম্পাদনাযোগ্য ডিভিতে যথারীতি পেস্ট করতে দিন এবং তারপরে পেস্টের পরে টেক্সটটির সাহায্যে কাস্টম পাঠ্য শৈলীর জন্য ব্যবহৃত স্প্যান উপাদানগুলি অদলবদল করুন। এটি ইন্টারনেট এক্সপ্লোরার এবং অন্য ব্রাউজারগুলিতে চেষ্টা করেছি বলে ঠিক মনে হচ্ছে ...

$('[contenteditable]').on('paste', function (e) {
    setTimeout(function () {
        $(e.target).children('span').each(function () {
            $(this).replaceWith($(this).text());
        });
    }, 0);
});

এই সমাধানটি ধরে নিয়েছে যে আপনি jQuery চালাচ্ছেন এবং আপনার কোনও সামগ্রী সম্পাদনাযোগ্য ডিভগুলিতে পাঠ্য বিন্যাস চান না

প্লাস দিকটি এটি অত্যন্ত সহজ super


spanট্যাগ কেন ? আমি কল্পনা করব প্রশ্নটি সমস্ত ট্যাগ সম্পর্কে ছিল।
অ্যালেক্সিস উইল্ক

1

এই সমাধানটি এইচটিএমএল ট্যাগকে প্রতিস্থাপন করবে, এটি সহজ এবং ক্রস ব্রাউজার; এই jsfiddle দেখুন: http://jsfiddle.net/tomwan/cbp1u2cx/1/ , মূল কোড:

var $plainText = $("#plainText");
var $linkOnly = $("#linkOnly");
var $html = $("#html");

$plainText.on('paste', function (e) {
    window.setTimeout(function () {
        $plainText.html(removeAllTags(replaceStyleAttr($plainText.html())));
    }, 0);
});

$linkOnly.on('paste', function (e) {
    window.setTimeout(function () {
        $linkOnly.html(removeTagsExcludeA(replaceStyleAttr($linkOnly.html())));
    }, 0);
});

function replaceStyleAttr (str) {
    return str.replace(/(<[\w\W]*?)(style)([\w\W]*?>)/g, function (a, b, c, d) {
        return b + 'style_replace' + d;
    });
}

function removeTagsExcludeA (str) {
    return str.replace(/<\/?((?!a)(\w+))\s*[\w\W]*?>/g, '');
}

function removeAllTags (str) {
    return str.replace(/<\/?(\w+)\s*[\w\W]*?>/g, '');
}

বিজ্ঞপ্তি: আপনার পিছনের দিকে xss ফিল্টার সম্পর্কে কিছু কাজ করা উচিত কারণ এই দ্রবণটি '<< >>' এর মতো স্ট্রিংগুলি ফিল্টার করতে পারে না


আপনার জাভাস্ক্রিপ্ট ফিল্টার একটি ভাল কাজ করে কিনা তা নিয়ে সার্ভারে এক্সএসএস ফাইলিংয়ের কোনও সম্পর্ক নেই। হ্যাকাররা যাইহোক আপনার জেএস ফিল্টারিংয়ের 100% বাইপাস করে।
অ্যালেক্সিস উইলক

HTML কে পার্স / ট্রান্সফর্ম করতে কখনই রেজেক্স ব্যবহার করবেন না!
সাব্লাইমসিয়েম

0

এটি উপরে পোস্ট করা একটি বিদ্যমান কোড তবে আমি এটির জন্য এটি আপডেট করেছি, বিদ্যমান পাঠ্যটি নির্বাচিত হয়ে পেস্ট করার সময় বাগটি নির্বাচিত সামগ্রী মুছবে না। এটি নীচের কোড দ্বারা স্থির করা হয়েছে

selRange.deleteContents(); 

নীচে সম্পূর্ণ কোড দেখুন

$('[contenteditable]').on('paste', function (e) {
    e.preventDefault();

    if (window.clipboardData) {
        content = window.clipboardData.getData('Text');        
        if (window.getSelection) {
            var selObj = window.getSelection();
            var selRange = selObj.getRangeAt(0);
            selRange.deleteContents();                
            selRange.insertNode(document.createTextNode(content));
        }
    } else if (e.originalEvent.clipboardData) {
        content = (e.originalEvent || e).clipboardData.getData('text/plain');
        document.execCommand('insertText', false, content);
    }        
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.