जवाबों:
मैं अटैच कर श्रोताओं के लिए महत्वपूर्ण घटनाओं संपादन योग्य तत्व द्वारा चलाई हालांकि आपको लगता है कि पता होना चाहिए सुझाव देंगे, keydownऔर keypressसामग्री अपने आप बदल जाता है से पहले की घटनाओं निकाल दिया जाता है। यह सामग्री को बदलने के हर संभव साधन को कवर नहीं करेगा: उपयोगकर्ता संपादन या संदर्भ ब्राउज़र मेनू से कट, कॉपी और पेस्ट का उपयोग भी कर सकता है, इसलिए आप घटनाओं cut copyऔर pasteघटनाओं को भी संभालना चाह सकते हैं । साथ ही, उपयोगकर्ता पाठ या अन्य सामग्री को छोड़ सकता है, इसलिए वहां अधिक घटनाएं होती हैं ( mouseupउदाहरण के लिए)। आप तत्व की सामग्री को कमबैक के रूप में प्रदूषित करना चाह सकते हैं।
अद्यतन 29 अक्टूबर 2014
एचटीएमएल 5 inputघटना लंबे समय में जवाब है। लेखन के समय, यह contenteditableवर्तमान मोज़िला (फ़ायरफ़ॉक्स 14 से) और वेबिट / ब्लिंक ब्राउज़र में तत्वों के लिए समर्थित है, लेकिन आईई नहीं।
डेमो:
document.getElementById("editor").addEventListener("input", function() {
console.log("input event fired");
}, false);
<div contenteditable="true" id="editor">Please type something in here</div>
cut, copyऔर paste(आईई 5 +, फ़ायरफ़ॉक्स है कि उन्हें समर्थन ब्राउज़रों में घटनाओं 3.0+, सफारी 3+, क्रोम)
inputइवेंट द्वारा कवर किया जाना चाहिए ।
यहां एक अधिक कुशल संस्करण है जो onसभी सामग्री के लिए उपयोग करता है । यह यहाँ शीर्ष उत्तरों पर आधारित है।
$('body').on('focus', '[contenteditable]', function() {
const $this = $(this);
$this.data('before', $this.html());
}).on('blur keyup paste input', '[contenteditable]', function() {
const $this = $(this);
if ($this.data('before') !== $this.html()) {
$this.data('before', $this.html());
$this.trigger('change');
}
});
परियोजना यहाँ है: https://github.com/balupton/html5edit
document.getElementById('editor_input').innerHTML = 'ssss':।
MutationObserver का उपयोग करने पर विचार करें । इन पर्यवेक्षकों को DOM में परिवर्तन के लिए प्रतिक्रिया करने के लिए, और उत्परिवर्तन घटनाओं के लिए एक प्रतिस्थापन के रूप में डिज़ाइन किया गया है ।
पेशेवरों:
विपक्ष:
और अधिक जानें:
inputईवेंट (जो कि contenteditableसभी WebKit और मोज़िला ब्राउज़रों के लिए समर्थित है, जो उत्परिवर्तन पर्यवेक्षकों का समर्थन करता है) के समान नहीं है, क्योंकि DOM म्यूटेशन स्क्रिप्ट के साथ-साथ उपयोगकर्ता इनपुट के माध्यम से भी हो सकता है, लेकिन यह उन ब्राउज़रों के लिए एक व्यवहार्य समाधान है। मुझे लगता है कि यह inputघटना से भी अधिक प्रदर्शन को नुकसान पहुंचा सकता है, लेकिन मेरे पास इसके लिए कोई कठिन सबूत नहीं है।
inputघटना इन स्थितियों में से प्रत्येक में (विशेष रूप से ड्रैग एंड ड्रॉप, इटैलिकाइजिंग, संदर्भ मेनू के माध्यम से कॉपी / कट / पेस्ट) होती है। मैंने bolding w / cmd / ctrl + b का भी परीक्षण किया और अपेक्षित परिणाम प्राप्त किए। मैंने जाँच भी की और यह सत्यापित करने में सक्षम था कि यह inputकार्यक्रम प्रोग्रामेटिक परिवर्तनों (जो स्पष्ट प्रतीत होता है, पर आग नहीं करता है), लेकिन यकीनन संबंधित एमडीएन पृष्ठ पर कुछ भ्रामक भाषा के विपरीत है, पृष्ठ का निचला भाग यहां देखें कि मेरा क्या मतलब है: डेवलपर; .mozilla.org / en-US / डॉक्स / वेब / इवेंट्स / इनपुट )
मैंने लॉविन्सटिन के उत्तर को संशोधित किया है, इसलिए यह मेरे लिए काम करता है। मैं keypress के बजाय कीअप इवेंट का उपयोग करता हूं जो बहुत अच्छा काम करता है।
$('#editor').on('focus', function() {
before = $(this).html();
}).on('blur keyup paste', function() {
if (before != $(this).html()) { $(this).trigger('change'); }
});
$('#editor').on('change', function() {alert('changed')});
गैर jQuery त्वरित और गंदा जवाब:
function setChangeListener (div, listener) {
div.addEventListener("blur", listener);
div.addEventListener("keyup", listener);
div.addEventListener("paste", listener);
div.addEventListener("copy", listener);
div.addEventListener("cut", listener);
div.addEventListener("delete", listener);
div.addEventListener("mouseup", listener);
}
var div = document.querySelector("someDiv");
setChangeListener(div, function(event){
console.log(event);
});
दो विकल्प:
1) आधुनिक (सदाबहार) ब्राउज़रों के लिए: "इनपुट" ईवेंट वैकल्पिक "परिवर्तन" ईवेंट के रूप में कार्य करेगा।
https://developer.mozilla.org/en-US/docs/Web/Events/input
document.querySelector('div').addEventListener('input', (e) => {
// Do something with the "change"-like event
});
या
<div oninput="someFunc(event)"></div>
या (jQuery के साथ)
$('div').on('click', function(e) {
// Do something with the "change"-like event
});
2) IE11 और आधुनिक (सदाबहार) ब्राउज़रों के लिए खाते में: यह तत्व परिवर्तन और div के अंदर उनकी सामग्री के लिए देखता है।
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
var div = document.querySelector('div');
var divMO = new window.MutationObserver(function(e) {
// Do something on change
});
divMO.observe(div, { childList: true, subtree: true, characterData: true });
const p = document.querySelector('p')
const result = document.querySelector('div')
const observer = new MutationObserver((mutationRecords) => {
result.textContent = mutationRecords[0].target.data
// result.textContent = p.textContent
})
observer.observe(p, {
characterData: true,
subtree: true,
})
<p contenteditable>abc</p>
<div />
यहाँ मेरे लिए क्या काम किया गया है:
var clicked = {}
$("[contenteditable='true']").each(function(){
var id = $(this).attr("id");
$(this).bind('focus', function() {
// store the original value of element first time it gets focus
if(!(id in clicked)){
clicked[id] = $(this).html()
}
});
});
// then once the user clicks on save
$("#save").click(function(){
for(var id in clicked){
var original = clicked[id];
var current = $("#"+id).html();
// check if value changed
if(original != current) save(id,current);
}
});
जब मैं इस विषय की जाँच कर रहा था तो यह सूत्र बहुत मददगार था।
मैंने यहाँ उपलब्ध कोड में से कुछ को एक jQuery प्लगइन में संशोधित किया है, इसलिए यह मुख्य रूप से मेरी जरूरतों को पूरा करने के लिए एक पुन: प्रयोज्य रूप में है, लेकिन अन्य लोग संतोषप्रद टैग का उपयोग करके जम्पस्टार्ट के लिए एक सरल इंटरफ़ेस की सराहना कर सकते हैं।
https://gist.github.com/3410122
इसकी बढ़ती लोकप्रियता के कारण प्लगइन Makesites.org द्वारा अपनाया गया है
यहां से विकास जारी रहेगा:
यहाँ मैं समाधान का उपयोग कर समाप्त हो गया है और fabulously काम करता है। मैं इसके बजाय $ (यह) .text () का उपयोग करता हूं क्योंकि मैं केवल एक पंक्ति div का उपयोग कर रहा हूं जो सामग्री संपादन योग्य है। लेकिन आप .html () का भी उपयोग कर सकते हैं, इस तरह से आपको वैश्विक / गैर-वैश्विक चर के दायरे के बारे में चिंता करने की ज़रूरत नहीं है और इससे पहले वास्तव में संपादक डिव से जुड़ा हुआ है।
$('body').delegate('#editor', 'focus', function(){
$(this).data('before', $(this).html());
});
$('#client_tasks').delegate('.task_text', 'blur', function(){
if($(this).data('before') != $(this).html()){
/* do your stuff here - like ajax save */
alert('I promise, I have changed!');
}
});
टाइमर और "सेव" बटन से बचने के लिए, आप ब्लर ईवेंट विच फायर का उपयोग कर सकते हैं जब तत्व फोकस खो देता है। लेकिन यह सुनिश्चित करने के लिए कि तत्व वास्तव में बदल गया था (न कि केवल ध्यान केंद्रित और विरूपित), इसकी सामग्री की तुलना इसके अंतिम संस्करण से की जानी चाहिए। या इस तत्व पर कुछ "गंदे" ध्वज सेट करने के लिए कीडाउन इवेंट का उपयोग करें।
JQuery में एक सरल जवाब, मैंने अभी यह कोड बनाया है और सोचा है कि यह दूसरों के लिए भी उपयोगी होगा
var cont;
$("div [contenteditable=true]").focus(function() {
cont=$(this).html();
});
$("div [contenteditable=true]").blur(function() {
if ($(this).html()!=cont) {
//Here you can write the code to run when the content change
}
});
$("div [contenteditable=true]")प्रत्यक्ष या अप्रत्यक्ष रूप से एक दिव्यांग के सभी बच्चों का चयन करेंगे, जो कि संतोषप्रद हैं।
गैर JQuery का जवाब ...
function makeEditable(elem){
elem.setAttribute('contenteditable', 'true');
elem.addEventListener('blur', function (evt) {
elem.removeAttribute('contenteditable');
elem.removeEventListener('blur', evt.target);
});
elem.focus();
}
इसका उपयोग करने के लिए, आईडी ("माई हैडर") के साथ एक हेडर तत्व पर कॉल करें।
makeEditable(document.getElementById('myHeader'))
वह तत्व अब उपयोगकर्ता द्वारा संपादन योग्य होगा जब तक कि वह ध्यान केंद्रित नहीं करता।
ऑन्चेंज इवेंट में आग नहीं लगती है जब contentEditable विशेषता वाला एक तत्व बदल जाता है, एक सुझाया दृष्टिकोण एक बटन जोड़ने के लिए हो सकता है, संस्करण को "बचाने" के लिए।
इस प्लगइन की जाँच करें जो इस तरह से समस्या को हल करता है:
MutationEvents के तहत DOMCharacterDataModified का उपयोग करने से उसी को बढ़ावा मिलेगा। टाइमआउट सेटअप गलत मान भेजने से रोकने के लिए किया गया है (जैसे Chrome में मेरे पास स्पेस की के साथ कुछ समस्याएँ थीं)
var timeoutID;
$('[contenteditable]').bind('DOMCharacterDataModified', function() {
clearTimeout(timeoutID);
$that = $(this);
timeoutID = setTimeout(function() {
$that.trigger('change')
}, 50)
});
$('[contentEditable]').bind('change', function() {
console.log($(this).text());
})
DOMCharacterDataModifiedजब उपयोगकर्ता मौजूदा पाठ को संशोधित करता है, उदाहरण के लिए बोल्ड या इटैलिक्स लागू करने पर फायर नहीं करेगा। DOMSubtreeModifiedइस मामले में अधिक उपयुक्त है। साथ ही, लोगों को यह याद रखना चाहिए कि विरासत ब्राउज़र इन घटनाओं का समर्थन नहीं करते हैं।
मैंने ऐसा करने के लिए एक jQuery प्लगइन बनाया।
(function ($) {
$.fn.wysiwygEvt = function () {
return this.each(function () {
var $this = $(this);
var htmlold = $this.html();
$this.bind('blur keyup paste copy cut mouseup', function () {
var htmlnew = $this.html();
if (htmlold !== htmlnew) {
$this.trigger('change')
}
})
})
}
})(jQuery);
आप बस कॉल कर सकते हैं $('.wysiwyg').wysiwygEvt();
आप चाहें तो ईवेंट को हटा / जोड़ भी सकते हैं
innerHTMLमहंगी होती है)। मैं इस inputघटना का उपयोग करने की सलाह दूंगा जहां यह मौजूद है और कुछ इस तरह की बहस के साथ वापस आ रही है।
कोणीय 2+ में
<div contentEditable (input)="type($event)">
Value
</div>
@Component({
...
})
export class ContentEditableComponent {
...
type(event) {
console.log(event.data) // <-- The pressed key
console.log(event.path[0].innerHTML) // <-- The content of the div
}
}
कृपया निम्नलिखित सरल समाधान का पालन करें
Ints:
getContent(innerText){
this.content = innerText;
}
.html:
<div (blur)="getContent($event.target.innerHTML)" contenteditable [innerHTML]="content"></div>
इस विचार की जाँच करें। http://pastie.org/1096892
मुझे लगता है कि यह करीब है। HTML 5 को वास्तव में चेंज ईवेंट को कल्पना में जोड़ना है। एकमात्र समस्या यह है कि कॉलबैक फ़ंक्शन मूल्यांकन करता है कि क्या (= = $ (यह) .html ()) सामग्री से पहले वास्तव में $ (इस) .html () में अपडेट किया गया है। सेटटाइमआउट काम नहीं करता है, और यह दुखद है। आप क्या सोचते हैं मुझे बताओ।
@ बालूप्टन के उत्तर के आधार पर:
$(document).on('focus', '[contenteditable]', e => {
const self = $(e.target)
self.data('before', self.html())
})
$(document).on('blur', '[contenteditable]', e => {
const self = $(e.target)
if (self.data('before') !== self.html()) {
self.trigger('change')
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
document.getElementById("editor").oninput = function() { ...}:।