gpt4 book ai didi

mithril.js - 如何在 Mithril 中集成自定义上下文菜单

转载 作者:行者123 更新时间:2023-12-01 06:24:23 24 4
gpt4 key购买 nike

我正在尝试向页面中的某些元素添加自定义上下文菜单
它在包含表格的 View 中是这样的。上下文菜单附加到
名称为“S”的表头:

list.view = function(ctrl, args) {

var contextMenuSelection =
m("div", {
id : "context-menu-bkg-01",
class : ctrl.isContextMenuVisible() === ctrl.contextMenuId ? "context-menu" : "hide",
style : ctrl.contextMenuPosition(),
}, [ m("#select.menu-item.allow-hover", {
onclick : function(e) {
args.model.callMenu({
cmdName : this.id
})
}
}, "Select all"), m("#deselect.menu-item.allow-hover", {
onclick : function(e) {
args.model.callMenu({
cmdName : this.id
})
}
}, "Deselect all"), m("#invertSel.menu-item.allow-hover", {
onclick : function(e) {
args.model.callMenu({
cmdName : this.id
})
}
}, "Invert selection") ]);

var table = m("table", [
m("tr", [ m("th", {
id : ctrl.contextMenuId,
config : ctrl.configContextMenu(),
oncontextmenu : function(e) {
console.log("2021 contextMenuShow")
e.preventDefault()
var coords = utils.getCoords(e)
var pos = {}
pos.left = coords[0] + "px"
pos.top = coords[1] + "px"
ctrl.contextMenuPosition(pos)
var id = e.currentTarget.id
ctrl.isContextMenuVisible(id)
}
}, "S"),
m("th[data-sort-by=pName]", "Name"),
m("th[data-sort-by=pSize]", "Size"),
m("th[data-sort-by=pPath]", "Path"),
m("th[data-sort-by=pMedia]", "Media") ]),
ctrl.items().map(
function(item, idx) {
return m("tr", ctrl.initRow(item, idx), {
key : item.guid
}, [ m("input[type=checkbox]", {
id : item.guid,
checked : ctrl.isSelected(item.guid)
}),
m("td", item.pName),
m("td", utils.numberWithDots(item.pSize)),
m("td", item.pPath), m("td", item.pMedia) ])
}) ])

return m("div", [contextMenuSelection, table])
}

在按下转义键或用户单击后关闭上下文菜单
用鼠标在页面中的某处,此功能附加到
元素通过 config 属性:

ctrl.configContextMenu = function() { 
return function(element, isInitialized, context) {
console.log("1220 isInitialized=" + isInitialized)
if(!isInitialized) {
console.log("1225")
document.addEventListener('click', function() {
m.startComputation()
ctrl.contextMenuVisibility(0)
m.endComputation()
}, false);
document.addEventListener('keydown', function() {
console.log("1235")
m.startComputation()
ctrl.contextMenuVisibility(0)
m.endComputation()
}, false)
}
};
};

行为是不可预测的:
如果表为空,自定义上下文菜单会显示并按预期隐藏。
如果表格已填充,则会显示默认上下文菜单。

使用调试器和一些断点并没有给我一些信息
除了有时逐步运行调试器会导致
自定义上下文菜单。所以我认为它与竞争条件有关
eventListener 和 Mithrils 绘制系统之间。

有没有人使用自定义上下文菜单的经验,可以为我提供一些
例子?

非常感谢,
斯特凡

编辑:
至于 Barneys 关于 m.startComputation() 的评论,我将代码更改为以下内容:

var table = m("table", ctrl.sorts(ctrl.items()), [
m("tr", [ m("th", {
oncontextmenu : ctrl.onContextMenu(ctrl.contextMenuId, "context-menu context-menu-bkg", "hide" )
}, "S"), m("th[data-sort-by=pName]", "Name"),
m("th[data-sort-by=pSize]", "Size"),
m("th[data-sort-by=pPath]", "Path"),
m("th[data-sort-by=pMedia]", "Media") ]),
ctrl.items().map(function(item, idx) {
return m("tr", ctrl.initRow(item, idx), {
key : item.guid
}, [ m("input[type=checkbox]", {
id : item.guid,
checked : ctrl.isSelected(item.guid),
onclick : function(e) {
console.log("1000")
ctrl.setSelected(this.id);
}
}), m("td", item.pName), m("td", utils.numberWithDots(item.pSize)),
m("td", item.pPath), m("td", item.pMedia) ])
}) ])

以及 onContextMenu 的实现函数:

// open a context menu
// @elementId the id of the element which resembles the context menu.
// Usually this is a div.
// @classShow the name of the css class for showing the menu
// @classHide the name of the css class for hiding the menu
vmc.onContextMenu = function(elementId, classShow, classHide) {
var callback = function(e) {
console.log("3010" + this)
var contextmenudiv = document.getElementById(elementId);
contextmenudiv.className = classHide;
document.removeEventListener("click", callback, false);
document.removeEventListener("keydown", callback, false);
}
return function(e) {
console.log("3000" + this)
var contextmenudiv = document.getElementById(elementId);
// Prevent the browser from opening the default context menu
e.preventDefault();
var coords = utils.getCoords(e);
contextmenudiv.style.left = coords[0] + "px";
contextmenudiv.style.top = coords[1] + "px";
// Display it
contextmenudiv.className = classShow;
// When you click somewhere else, hide it
document.addEventListener("click", callback, false);
document.addEventListener("keydown", callback, false);
}
};

现在这没有问题。
巴尼,如果您能确认这是一种可行的方式,我会将其发布为答案。

谢谢,斯蒂芬

最佳答案

这是一个有效的解决方案:

var table = m("table", ctrl.sorts(ctrl.items()), [
m("tr", [ m("th", {
oncontextmenu : ctrl.onContextMenu(ctrl.contextMenuId, "context-menu context-menu-bkg", "hide" )
}, "S"), m("th[data-sort-by=pName]", "Name"),
m("th[data-sort-by=pSize]", "Size"),
m("th[data-sort-by=pPath]", "Path"),
m("th[data-sort-by=pMedia]", "Media") ]),
ctrl.items().map(function(item, idx) {
return m("tr", ctrl.initRow(item, idx), {
key : item.guid
}, [ m("input[type=checkbox]", {
id : item.guid,
checked : ctrl.isSelected(item.guid),
onclick : function(e) {
console.log("1000")
ctrl.setSelected(this.id);
}
}), m("td", item.pName), m("td", utils.numberWithDots(item.pSize)),
m("td", item.pPath), m("td", item.pMedia) ])
}) ])

以及 onContextMenu 的实现函数:

// open a context menu
// @elementId the id of the element which resembles the context menu.
// Usually this is a div.
// @classShow the name of the css class for showing the menu
// @classHide the name of the css class for hiding the menu
vmc.onContextMenu = function(elementId, classShow, classHide) {
var callback = function(e) {
console.log("3010" + this)
var contextmenudiv = document.getElementById(elementId);
contextmenudiv.className = classHide;
document.removeEventListener("click", callback, false);
document.removeEventListener("keydown", callback, false);
}
return function(e) {
console.log("3000" + this)
var contextmenudiv = document.getElementById(elementId);
// Prevent the browser from opening the default context menu
e.preventDefault();
var coords = utils.getCoords(e);
contextmenudiv.style.left = coords[0] + "px";
contextmenudiv.style.top = coords[1] + "px";
// Display it
contextmenudiv.className = classShow;
// When you click somewhere else, hide it
document.addEventListener("click", callback, false);
document.addEventListener("keydown", callback, false);
}
};

现在上下文菜单在 mithrils 渲染周期之外,不再有竞争条件。此外,隐藏菜单的单击事件附加到文档,并且不会与 mithril 附加的单击处理程序发生冲突。

用 Firefox 38.01 测试

关于mithril.js - 如何在 Mithril 中集成自定义上下文菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30216586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com