Определить, какой элемент был изменен, когда тело документа является редактируемым по контенту javascript [duplicate]

Я получил решение для меня:

Откройте «Менеджер конфигурации SQL Server»

Теперь нажмите «Конфигурация сети SQL Server» и нажмите «Протоколы для ] Имя "

Щелкните правой кнопкой мыши на« TCP / IP »(убедитесь, что оно включено) Нажмите« Свойства »

Теперь выберите вкладку« IP-адреса »- и-Go к последней записи «IP All»

Введите «TCP-порт» 1433.

Теперь перезапустите «SQL Server .Name». используя «services.msc» (winKey + r)

Он будет работать ...

298
задан danwellman 13 February 2017 в 22:37
поделиться

18 ответов

Я предлагаю подключить слушателей к ключевым событиям, запускаемым редактируемым элементом, хотя вам нужно знать, что события keydown и keypress запускаются до изменения самого содержимого. Это не будет охватывать все возможные способы изменения контента: пользователь может также использовать вырезание, копирование и вставку из меню «Редактировать» или контекстного браузера, поэтому вы можете обрабатывать события cut copy и paste , Кроме того, пользователь может отбрасывать текст или другой контент, поэтому есть больше событий (например, mouseup). Вы можете захотеть опросить содержимое элемента как резерв.

UPDATE 29 October 2014

Событие HTML5 input - это ответ в долгосрочной перспективе , На момент написания он поддерживается для contenteditable элементов в текущих браузерах Mozilla (из Firefox 14) и WebKit / Blink, но не в IE.

Демо:

document.getElementById("editor").addEventListener("input", function() {
    console.log("input event fired");
}, false);
<div contenteditable="true" id="editor">Please type something in here</div>

Демонстрация: http://jsfiddle.net/ch6yn/2691/

233
ответ дан Tim Down 18 August 2018 в 19:22
поделиться
  • 1
    Я также должен добавить, что можно изменить редактируемый элемент, используя меню редактирования или контекстное меню браузера, чтобы вырезать, копировать или вставлять контент, поэтому вам нужно обрабатывать события cut, copy и paste в браузерах которые поддерживают их (IE 5+, Firefox 3.0+, Safari 3+, Chrome) – Tim Down 25 March 2010 в 19:33
  • 2
    Вы можете использовать keyup, и у вас не будет проблемы с синхронизацией. – Blowsie 8 April 2011 в 16:18
  • 3
    @Blowsie: Да, но вы, возможно, в конечном итоге столкнетесь с множеством изменений, происходящих от автоматического повторного нажатия клавиши до того, как произойдет пожар. Существуют также другие способы изменения редактируемого текста, который не рассматривается в этом ответе, например, перетаскивание и редактирование с помощью меню редактирования и контекстного меню. Долгосрочный, все это должно охватываться событием HTML5 input. – Tim Down 8 April 2011 в 16:32
  • 4
    Я делаю keyup с debounce. – Aen Tan 29 May 2013 в 05:08
  • 5
    @NadavB: Что-то изменилось в jsFiddle, что сделало его больше не работающим. Я заменил скрипт фрагментом кода, и теперь он отлично работает. – Tim Down 18 June 2018 в 11:14

Вот более эффективная версия, которая использует on для всех contenteditables. Это основано на верхних ответах здесь.

$('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

171
ответ дан balupton 18 August 2018 в 19:22
поделиться
  • 1
    Работала идеально для меня, спасибо как для CoffeeScript, так и для Javascript – jwilcox09 18 December 2012 в 17:47
  • 2
    Есть некоторые изменения, которые не будут улавливаться этим кодом до тех пор, пока контент не будет размытым. Например: dragging & amp; удаление, вырезание из контекстного меню и вставка из окна браузера. Я установил страницу примера, которая использует этот код, который вы можете взаимодействовать с здесь . – jrullmann 26 December 2012 в 18:52
  • 3
    @jrullmann Да, у меня были проблемы с этим кодом, когда drag & amp; dropping images, потому что он не прослушивает загрузку изображения (это было проблемой для обработки операции изменения размера в моем случае) – Sebastien Lorber 26 February 2014 в 13:17
  • 4
    @jrullmann Очень приятно, это работает даже после изменения значения с помощью javascript, попробуйте консоль: document.getElementById('editor_input').innerHTML = 'ssss'. Недостатком является то, что он требует IE11 – user 21 August 2014 в 11:56
  • 5
    @NadavB это не должно, так как это то, что "if ($ this.data ('before')! == $ this.html ()) {& quot; для – balupton 16 August 2018 в 04:12

Две опции:

1) Для современных (вечнозеленых) браузеров: событие «вход» будет действовать как альтернативное событие «change».

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 });
0
ответ дан bit-less 18 August 2018 в 19:22
поделиться

Событие onchange не срабатывает, когда изменяется элемент с атрибутом contentEditable, предлагаемым подходом может быть добавление кнопки, чтобы «сохранить» издание.

Проверьте этот плагин, который обрабатывает проблему таким образом:

0
ответ дан CMS 18 August 2018 в 19:22
поделиться

Я так изменил ответ закона, и это работает для меня. Я использую событие keyup вместо 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')});
45
ответ дан Community 18 August 2018 в 19:22
поделиться
  • 1
    Это не совсем то же самое, что и событие HTML5 input (которое поддерживается для contenteditable во всех браузерах WebKit и Mozilla, поддерживающих наблюдатели за мутациями), поскольку мутация DOM может происходить как с помощью сценария, так и с пользовательского ввода, но это жизнеспособный решение для этих браузеров. Я предполагаю, что это может повредить производительности больше, чем событие input, но у меня нет веских доказательств этого. – Tim Down 29 December 2012 в 20:10
  • 2
    +1, но знаете ли вы, что события Mutation не сообщают о влиянии линейного фида на контент? Нажмите ввод в своем фрагменте. – citykid 3 September 2013 в 14:36
  • 3
    @citykid: Это потому, что фрагмент наблюдает только за изменениями в символьных данных. Можно также наблюдать структурные изменения DOM. Например, см. jsfiddle.net/4n2Gz/1 . – Tim Down 24 September 2013 в 11:44
  • 4
    Internet Explorer 11+ поддерживает Наблюдатели мутаций . – Sampson 10 March 2014 в 22:32
  • 5
    Я смог проверить (по крайней мере, в Chrome 43.0.2357.130), что событие HTML5 input срабатывает в каждой из этих ситуаций (в частности, drag & amp; drop, italicizing, copy / cut / paste через контекстное меню). Я также тестировал bolding w / cmd / ctrl + b и получил ожидаемые результаты. Я также проверил и смог проверить, что событие input не срабатывает при программных изменениях (что кажется очевидным, но, возможно, противоречит некоторому запутанному языку на соответствующей странице MDN, см. Нижнюю часть страницу здесь, чтобы увидеть, что я имею в виду: developer.mozilla.org/en-US/docs/Web/Events/input ) – mikermcneil 23 July 2015 в 12:56

Я построил плагин 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();

Вы также можете удалить / добавить события, если вы хотите

0
ответ дан czerasz 18 August 2018 в 19:22
поделиться
  • 1
    Это будет медленным и медленным, поскольку доступный для редактирования контент будет длиннее (innerHTML стоит дорого). Я бы порекомендовал использовать событие input, где он существует, и вернуться к чему-то подобному, но с каким-то debouncing. – Tim Down 5 June 2013 в 09:52

быстрый и грязный ответ 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);
});
20
ответ дан Developia 18 August 2018 в 19:22
поделиться

Ответ на не-JQuery ...

function makeEditable(elem){
    elem.setAttribute('contenteditable', 'true');
    elem.addEventListener('blur', function (evt) {
        elem.removeAttribute('contenteditable');
        elem.removeEventListener('blur', evt.target);
    });
    elem.focus();
}

Чтобы использовать его, вызовите (скажем) элемент заголовка с id = "myHeader"

makeEditable(document.getElementById('myHeader'))

Этот элемент будет теперь можно редактировать до тех пор, пока он не потеряет фокус.

-2
ответ дан DrMcCleod 18 August 2018 в 19:22
поделиться
  • 1
    Фу, почему ниспровержение без объяснений? Это оказывает плохую услугу как для человека, написавшего ответ, так и для всех, кто читает ответ позже. – Mike Willis 7 November 2017 в 16:02

Вот что сработало для меня:

   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);
            }
   });
3
ответ дан George Bailey 18 August 2018 в 19:22
поделиться

Использование DOMCharacterDataModified под MutationEvents приведет к тому же. Тайм-аут настроен для предотвращения отправки неправильных значений (например, в 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());
})

Пример JSFIDDLE

0
ответ дан janfabian 18 August 2018 в 19:22
поделиться
  • 1
    +1 - DOMCharacterDataModified не срабатывает, когда пользователь изменяет существующий текст, например, применяя полужирный или курсив. DOMSubtreeModified является более подходящим в этом случае. Кроме того, люди должны помнить, что устаревшие браузеры не поддерживают эти события. – Andy E 16 March 2012 в 17:34
  • 2
    Просто обратите внимание, что события мутации обесцениваются w3c из-за проблем с производительностью. Более подробно можно найти в этот вопрос переполнения стека . – jrullmann 26 December 2012 в 18:58

Чтобы избежать таймеров и кнопок «сохранить», вы можете использовать событие размытия, которое срабатывает, когда элемент теряет фокус. но чтобы убедиться, что элемент был фактически изменен (а не просто сфокусирован и расфокусирован), его контент следует сравнить с его последней версией. или используйте событие keydown для установки некоторого «грязного» флага на этот элемент.

0
ответ дан joox 18 August 2018 в 19:22
поделиться

Проверьте эту идею. http://pastie.org/1096892

Я думаю, что это близко. HTML 5 действительно нужно добавить событие изменения в спецификацию. Единственная проблема заключается в том, что функция обратного вызова вычисляет if (до == $ (this) .html ()) до фактического обновления содержимого в $ (this) .html (). setTimeout не работает, и это печально. Дайте мне знать, что вы думаете.

-1
ответ дан Lawrence Whiteside 18 August 2018 в 19:22
поделиться
  • 1
    Попробуйте использовать клавиатуру вместо нажатия клавиши. – Aen Tan 29 May 2013 в 05:09

Основываясь на ответе @ balupton:

$(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>

-2
ответ дан Phillip Senn 18 August 2018 в 19:22
поделиться

Простой ответ в 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
        }           
    });
0
ответ дан sarath 18 August 2018 в 19:22
поделиться
  • 1
    Обратите внимание, что $("div [contenteditable=true]") выберет все дочерние элементы div, прямо или косвенно, которые являются доступными для контента. – Bruno Ferreira 10 November 2016 в 21:35

Эта тема была очень полезна, когда я изучал этот вопрос.

Я изменил часть кода, доступного здесь, в плагин jQuery, поэтому он находится в повторно используемой форме, в первую очередь для удовлетворения моих потребностей, но другие могут оценить более простой интерфейс для перехода с использованием контентных тегов.

https://gist.github.com/3410122

Обновление:

Из-за его растущей популярности плагин был принятый Makesites.org

Разработка будет продолжена здесь:

https://github.com/makesites/jquery-contenteditable

3
ответ дан tracend 18 August 2018 в 19:22
поделиться

Вот решение, которое я использовал, и работает сказочно. Я использую $ (this) .text () вместо этого, потому что я просто использую один div строки, который доступен для редактирования. Но вы также можете использовать .html () таким образом, вам не нужно беспокоиться об объеме глобальной / неглобальной переменной, а перед этим привязывается к редактору div.

$('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!');
    }
});
2
ответ дан user740433 18 August 2018 в 19:22
поделиться
46
ответ дан Community 7 September 2018 в 03:39
поделиться
47
ответ дан Community 30 October 2018 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: