首页  编辑  

简单方法给页面 contenteditable 的内容扩展功能

Tags: /计算机文档/网页制作/   Date Created:
假如你在写一个HTML所见即所得的编辑页面,一般考虑使用 Wang's Editor 或者 FCK Editor等第三方的编辑器,如果你实在不想用第三方的编辑器,又想扩展默认编辑器的表格编辑、IMG设置宽度高度等功能,请使用下面的代码:
在你的html head中,添加以下代码:
 <script src="cm.js"></script>
把下面代码保存为一个 cm.js 文件,该脚本实现以下功能:
  • 右击表格弹出菜单,可以在上方、下发插入行,或者在左边、右边插入列,设置表格列宽,删除行、删除列,设置表格自适应宽度等
  • 双击img,可以弹出设置图片高度、宽度的对话框。用户输入像素,宽度百分比,或者输入(0~10)的浮点数可以自动按原图比例设置,例如 0.5 表示缩小一半,2表示原图两倍大小。
  • 你可以扩展其他功能
document.addEventListener('contextmenu', function(event) {
	// 检查触发事件的元素是否为表格
	if (!(event.target.tagName === 'TD' && event.target.closest('table'))) return;
	event.preventDefault();

	// 创建菜单
	var contextMenu = document.createElement('div');
	contextMenu.className = 'context-menu';
	contextMenu.style.top = event.clientY + 'px';
	contextMenu.style.left = event.clientX + 'px';

	// 定义菜单项
	var menuItems = [
		{ label: 'Insert Row Above', action: insertRowAbove},
		{ label: 'Insert Row Below', action: insertRowBelow },
		{ label: 'Insert Column Left', action: insertColumnLeft },
		{ label: 'Insert Column Right', action: insertColumnRight },
		{ label: 'Delete Current Row', action: deleteCurrentRow },
		{ label: 'Delete Current Column', action: deleteCurrentColumn },
		{ label: 'Set column width', action: setColumnWidth },
		{ label: 'Set table auto size', action: setTableProperties }
	];

	// 创建菜单项并添加到菜单中
	menuItems.forEach(function(item) {
	var menuItem = document.createElement('div');
	menuItem.className = 'context-menu-item';
	menuItem.innerText = item.label;
	menuItem.addEventListener('click', function(e) {
		item.action(e, menuItem, event.target.closest('table'), event.target.closest('td'));
	});
	contextMenu.appendChild(menuItem);
	});

	// 将菜单添加到页面
	document.body.appendChild(contextMenu);

	// 点击页面其他地方时关闭菜单
	document.addEventListener('click', function() {
	if (document.body.contains(contextMenu))
		document.body.removeChild(contextMenu);
	});
});

function insertRow(table, index) {
	var len = table.rows[index >= table.rows.length ? 0 : index].cells.length;
	var row = index >= table.rows.length ? table.insertRow() : table.insertRow(index);
	for (var i=0; i< len; i++) {
		row.insertCell().innerHTML = "<br/>";
	}
}

function insertRowAbove(e, mi, table, cell) {
	insertRow(table, cell.closest('tr').rowIndex);
}

function insertRowBelow(e, mi, table, cell) {
	insertRow(table, cell.closest('tr').rowIndex + 1);
}

function insertColumn(table, index) {
	for (var i=0; i<table.rows.length; i++) {
		table.rows[i].insertCell(index).innerHTML = "<br/>";
	}
}

function insertColumnLeft(e, mi, table, cell) {
	insertColumn(table, cell.cellIndex);
}

function insertColumnRight(e, mi, table, cell) {
	insertColumn(table, cell.cellIndex + 1);
}

function deleteCurrentRow(e, mi, table, cell) {
	table.deleteRow(cell.closest('tr').rowIndex);
}

function setColumnWidth(e, mi, table, cell) {
	var width = prompt("请输入列宽,例如 auto 或者 20% 或者 100px: ", cell.style.width)
	for (var i = 0; i < table.rows.length; i++) {
        table.rows[i].cells[cell.cellIndex].style.width = width;
    }
}

function setTableProperties(e, mi, table, cell) {
	table.style.width = table.style.width == "auto" ? "100%" : "auto"
}

function deleteCurrentColumn(e, mi, table, cell) {
	var index = cell.cellIndex;
	for (var i = 0; i < table.rows.length; i++) {
		table.rows[i].deleteCell(index);
	}
}

function isNumeric(str) {
    var numberRegex = /^\d*\.?\d+$/;
    return numberRegex.test(str);
}

document.addEventListener('dblclick', function(event) {
    // 检查触发事件的元素是否为图片
    if (!(event.target.tagName === 'IMG')) return;
	event.preventDefault();

	var dialog = document.createElement('div');
	dialog.className = 'image-dialog';

	var widthInput = document.createElement('input');
	widthInput.type = 'text';
	widthInput.value = event.target.style.width;
	widthInput.placeholder = '图像宽度,例如: 50px, 20%,0.5';
	dialog.appendChild(widthInput);

	var heightInput = document.createElement('input');
	heightInput.type = 'text';
	heightInput.value = event.target.style.height;
	heightInput.placeholder = '图像宽度,例如: 50px, 20%,0.5';
	dialog.appendChild(heightInput);

	var okButton = document.createElement('button');
	okButton.innerText = 'OK';
	okButton.addEventListener('click', function() {
		document.body.removeChild(dialog);
		var sw = widthInput.value.trim();
		event.target.style.width = isNumeric(sw) ? parseFloat(sw) * event.target.naturalWidth + 'px' : sw;

		var sh = heightInput.value.trim();
		event.target.style.height = isNumeric(sh) ? parseFloat(sh) * event.target.naturalHeight + 'px' : sh;
	});
	dialog.appendChild(okButton);

	var cancelButton = document.createElement('button');
	cancelButton.innerText = 'Cancel';
	cancelButton.addEventListener('click', function() {
		document.body.removeChild(dialog);
	});
	dialog.appendChild(cancelButton);

	// 将对话框添加到页面
	document.body.appendChild(dialog);
});
css 如下:
.context-menu {
  position: absolute;
  background: #fff;
  border: 1px solid #ccc;
  box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
  z-index: 1000;
}

.context-menu-item {
  padding: 8px;
  cursor: pointer;
}

.context-menu-item:hover {
  background: #f0f0f0;
}

.image-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: white;
    padding: 20px;
    border: 1px solid #ccc;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    z-index: 1000;
}

.image-dialog input {
    width: 100%;
    padding: 10px;
    margin-bottom: 10px;
    box-sizing: border-box;
}

.image-dialog button {
    display: block;
    width: 100%;
	margin-top: 5px;
    padding: 10px;
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
}

.image-dialog button:hover {
    background-color: #0056b3;
}