1 回答
TA贡献1799条经验 获得超8个赞
如果我可以建议使用HTML元素可编辑API的替代方案。
$("[data-cid]").prop({tabindex: 1, contenteditable: true}).on({
focusin() {
this.__html = $(this).html(); // Store current HTML content
},
focusout() {
const data = {
cid: this.dataset.cid,
html: this.innerHTML,
};
if (this.__html === data.html) return; // Nothing has changed.
console.log(data); // Something changed, send data to server.
}
})
<div data-cid="4">Test #4</div>
<div data-cid="5">Test #5</div>
<div data-cid="6">Test #6</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
创建自己的库
下面是一个示例,说明如何简单地创建自己的可重用函数:
// Editable
function Editable(sel, options) {
if (!(this instanceof Editable)) return new Editable(...arguments);
const attr = (EL, obj) => Object.entries(obj).forEach(([prop, val]) => EL.setAttribute(prop, val));
Object.assign(this, {
onStart() {},
onInput() {},
onEnd() {},
classEditing: "is-editing", // added onStart
classModified: "is-modified", // added onEnd if content changed
}, options || {}, {
elements: document.querySelectorAll(sel),
element: null, // the latest edited Element
isModified: false, // true if onEnd the HTML content has changed
});
const start = (ev) => {
this.isModified = false;
this.element = ev.currentTarget;
this.element.classList.add(this.classEditing);
this.text_before = ev.currentTarget.textContent;
this.html_before = ev.currentTarget.innerHTML;
this.onStart.call(this.element, ev, this);
};
const input = (ev) => {
this.text = this.element.textContent;
this.html = this.element.innerHTML;
this.isModified = this.html !== this.html_before;
this.element.classList.toggle(this.classModified, this.isModified);
this.onInput.call(this.element, ev, this);
}
const end = (ev) => {
this.element.classList.remove(this.classEditing);
this.onEnd.call(this.element, ev, this);
}
this.elements.forEach(el => {
attr(el, {tabindex: 1, contenteditable: true});
el.addEventListener("focusin", start);
el.addEventListener("input", input);
el.addEventListener("focusout", end);
});
return this;
}
// Use like:
Editable(".editable", {
onEnd(ev, UI) { // ev=Event UI=Editable this=HTMLElement
if (!UI.isModified) return; // No change in content. Abort here.
const data = {
cid: this.dataset.cid,
text: this.textContent, // or you can also use UI.text
}
console.log(data); // Submit your data to server
}
});
/* Your styles */
.editable {
padding: 10px;
background: #eee;
display: inline-block;
}
/* this class is handled by Editable */
.is-modified {
background: #bff;
}
/* this class is handled by Editable */
.is-editing {
background: #bfb;
outline: none;
}
<div class="editable" data-cid="4">Test #4</div>
<div class="editable" data-cid="5">Test #5</div>
<div class="editable" data-cid="6">Test #6</div>
<div class="editable" data-cid="7">Test #7</div>
可编辑功能:
Editable("selector", options);
返回:可编辑实例
选项对象:
性能:
classEditing:
字符串 - 要在焦点上添加的类(默认值:"is-editing"
)
classModified:
字符串 - 如果内容已更改,则要在焦点上添加的类(默认值:"is-modified"
)方法:
onStart(event, UI)
函数 - 事件
参数上的触发器:触发回
调参数的事件:可编辑实例对象
绑定:绑定到关联的 HTML 元素"focusin"
event
UI
this
onInput(event, UI)
函数 - 事件
参数上的触发器:触发回
调参数的事件:可编辑实例对象
绑定:绑定到关联的 HTML 元素"input"
event
UI
this
onEnd(event, UI)
函数 - 事件
参数上的触发器:触发回
调参数的事件:可编辑实例对象
绑定:绑定到关联的 HTML 元素"focusout"
event
UI
this
参数(可编辑实例)属性:
UI
text
字符串 - 当前编辑的元素的文本内容
字符串 - 当前编辑的元素的内HTML
字符串 - 元素的文本在编辑
之前的内容 字符串 - 元素的内HTML 在编辑
布尔值之前 - 如果 innerHTML 不等于原始
- 静态(非实时) 元素
的节点列表 - 最新编辑的 HTML 元素html
text_before
html_before
isModified
true
elements
element
添加回答
举报