gpt4 book ai didi

javascript - (模拟按键的缺点是什么?是否有更好的方法?

转载 作者:行者123 更新时间:2023-12-02 19:05:07 24 4
gpt4 key购买 nike

假设我有以下代码,它侦听输入元素,特别是在用户按下“ Enter”键时执行回调:

...

document.getElementById('human_input').onkeyup = (function (indicate) {
return function(e) {
var e = e || window.event; // for IE8
if (e.keyCode === 13) { // if user presses 'Enter' key*
indicate('User has submitted text');
}
}
})(indicate);


[* keyCode参考 here。]

...

indicate的作用实际上不是这里的重点,而是将一些代码应用于参数 'User has submitted text'以便将其显示在某处。

现在,如果我希望某些脚本以相同的方式侦听将要填充的“不可见输入”,而不是由人类而是由代码的单独部分来填充?

假设名为 fillHidden()的黑盒脚本函数在某些指定点填充了 hidden_input字段。

document.getElementById('hidden_input').value = 'All filled out.'; // for example


一个非常独立的侦听器脚本模块将如何找到该值。说这够了吗...

document.getElementById('hidden_input').onkeyup = (function (indicate) {
return function(e) {
var e = e || window.event; // for IE8
if (e.keyCode === 13) { // if user presses 'Enter' key
indicate('User has submitted text');
}
}
})(indicate);


并让 fillHidden()代码执行此操作:

document.getElementById('hidden_input').value = 'All filled out.'; // for example
document.getElementById('hidden_input').onkeyup({keyCode: 13}); // simulate keypress


还是那不好的做法?有人对 how甚至是 simulate keyboard shortcuts做到这一点有疑问,但是对于实际的优点或模拟按键,我什么也找不到。

是否有更好的方法,某种模式或回调的互锁系统,可以使这些模块在分离时进行交互?我看过尼古拉斯·扎卡斯(Nicholas Zakas)谈论这种“松散耦合”的架构的视频,还有一本我称为JavaScript Patterns(Stefanov,2010年)的书,暗示了订户/发布者模型的可能性。与模拟按键相比,这些优点是什么,特别是当模拟按键与事件的用户方具有某种对称性时?在模拟按键时可能会遇到什么样的不利条件/危险?

最佳答案

这都是非常...抽象。
一切都很好。

提出这样的抽象解决方案并不一定是SO的目标,因为有上百万种方法可以实现它们。

但是,有几点要点:


除非您以某种方式将模拟代码链接到用户生成的事件,否则浏览器可能会阻止您的模拟接替用户
(想象一下,让页面上的任何JS随时模拟任何按键或鼠标单击的浏览器)。
这通常意味着您紧密联系在一起,使用了一些非供消费者使用的库,使用了用户必须安装/运行或破坏的特定于浏览器的插件(即:FireFox / Chrome / IE)。选择一个(或多个)。
带有回调的自定义事件通常是允许您使程序保持独立但使它们一起运行的功能。
Zakas在Sandboxing上进行了一些精彩的演讲,但这些都是非常企业级的,最终游戏类型的事情。它们很棒,并且库构建者和系统工程师应该完全考虑它们,但是对于平均页面而言,最好用库来完成需要编写的100行,而不是构建一个完整的框架它既将每个模块包装在一个外壳中,又将自身注入该模块中。
这就是Pub-Sub(和观察者)/主持人(或中介者)发挥作用的地方。
根据库的不同,上述任何一种也可以称为“发射器”或“生成器”等。


上面的每一项都是以基本相同的方式创建的,并且执行相同的操作。
目的是将结果传递给想要听的听众。
演讲者选择何时通知听众,以及告诉他们什么。
观众选择随时收看,等待下一个广播(可能永远不会到来,但至少他们对此有所注意),或者他们可以选择收看并停止收听广播。

那么,它们之间的区别就是“说话者”如何知道正在发生的事情。

发布者-订阅者



publisher-subscriber中,说话者是使事情发生的对象。

看Twitter。
您注册一个Twitter帐户。拥有之后,您就可以关注任何人。
每当他们发推文时,您都会收到通知。
任何人都可以关注您,以便在您发送任何推文时都会收到通知。

执行该操作的人将该操作发布给任何想要收听该操作的订阅者。可能有3000个订阅者和一个发布者(新闻通讯),或者3000个发布者和一个订阅者...
可能有一些发布者不订阅,或者订阅者不发布...……但这就是范例。

观察者



observer中,您所谈论的是一个与完成工作的事物相关的对象。
可能会很紧。它可能很松。但是有一件事正在做某事,有一件事确切地知道它在做什么。然后,人们会向观察程序发出错误,以进行更新。

想想棒球时代,人们在广播中收听比赛。
观察者将是无线电评论员。
他不是那个击球或偷垒的人。他是展位中的一员,他看到了所有发生的事情,知道了这一切的含义,并将其转变为用户友好的信息,供所有在家听的人使用。

如今,玩家可以在制作过程中直接向其所有粉丝(pub-sub)发出推文,我相信FourSquare会找到一种方法来使他们的地理位置降低到每个基准的准确性,手动更新三垒手的王者身份(这一次,不是在狭窄的Z28中的杰夫)。

调解人/主持人



在这种情况下,我们谈论的是每个人都知道的对象,但没人知道彼此。

想象一下通话中的广播节目。

大家都知道表演。每个人都可以参加演出,并与主持人交谈。但是除了巧合,没有人对其他听众一无所知。

它与pub-sub有点不同,因为每个人都是发布者,但是您不必知道某人的Twitter句柄就可以收到他们的来信。您可以说Hey Twitter, any time anybody in the world mentions #browns, let me know. I'm starving.
它与observer有点不同,因为在主持人监视正在执行工作的人员时,任何人都可以随时进行工作。



哪一个是正确的?

这完全取决于您的需求以及您实际打算如何处理。

这是我们制作主持人的方法:

var Moderator = function () {
var events = {},

notify = function (evtName, data) {
var evt = events[evtName];
if (!evt) { return; }
evt.forEach(function (func) { func(data); });
},

listen = function (evtName, callback) {
events[evtName] = events[evtName] || [];
events[evtName].push(callback);
},

ignore = function (evtName, callback) {
var evt = events[evtName];
if (!evt) { return; }
evt.forEach(function (func, i, arr) {
if (func === callback) { arr.splice(i, 1); }
});
};

return { ignore : ignore,
listen : listen,
notify : notify };
};


很简单明了吧?
当然,这并没有特别的花哨,例如仅在下一次事件触发时,下一次发生3次时订阅,等等。

我们可以这样使用它:

var Game = function () {

var game_moderator = Moderator(),
scoreboard = Scoreboard(),
messages = MessageBoard(),
player_one = Player(),
player_two = Player();

function initialize () {

player_one.initialize(game_moderator);
player_two.initialize(game_moderator);

game_moderator.listen("player:death", scoreboard.update);
game_moderator.listen("player:death", messages.add_kill);
game_moderator.listen("chat:input", messages.add_msg );

}

function start() {}
/* update... draw... etc... */

return {
load : load,
initialize : initialize,
start : start
};
};


var game = Game(),
loading = game.load();

loading.done(function () {
var initializing = game.initialize();
initializing.done(game.start);
});


同时, Player可能看起来像这样:

var Player = function (name) {
var system,

health = 30,
damage = [],

attack = function () { /* ... */ },

hurt = function (amt, type, from) {
health -= amt;
damage.push({ amount : amt, type : type, from : from });
},

die = function () {
var killing_blow = damage[damage.length - 1];
killing_blow.player = name;

system.notify("player:death", killing_blow);
},

update = function () {
if (health <= 0) { die(); }
},

draw = function () {},

initialize = function (sys) { system = sys; };


return {
initialize : initialize,
update : update,
draw : draw,
hurt : hurt
/* ... */
};

};


因此,回顾 Game.initialize函数,我们可以看到我们有一个记分板和一个消息面板,它们都将与“ player:death”事件相关联。

由于调用和定义了播放器的方式,我在初始化过程中注入了对主持人的引用(这样我就可以将所有东西分开:依赖注入)。

但是 player_oneplayer_two一无所知, scoreboard对任何事情一无所知,只是偶尔会调用它的 .update方法并传递杀死信息,并且 messages会得到各种各样的爱,但这就是其中的一种每个人都是一个陌生人

回到您原来的问题:

如果通过按键来填写 hidden-input,为什么不构建观察者呢?

构建连接到 keyup事件侦听器和 keydown事件侦听器的观察器。
让观察者将这些事件转换成有用的信息(例如:当您按下某个键时, keydown事件每秒会触发数十次-您可能不希望这么做...因此在有新键时发出警报添加,或在释放按键时发出警报)。

hidden-input订阅它。

hidden-input已满时,或者您的要求正在运行... ...并且您要触发事件时,请使用全局主持人(或位于 是)的一部分。

从那里,触发一个名为 hidden-input的事件或任何有意义的事件。

关心事件发生的人可以通过主持人订阅该事件。

就是说,当然,如果您的程序以没有人知道隐藏输入的方式构建,但是有些人应该了解 "hidden-input-filled"的事件。

如果只有一组应该了解 hidden-input的事物,而这是唯一应了解其事件的事物,并且 hidden-input还应该能够了解它们的某些事物,则将其设为 hidden-input

或混合搭配您的联系方式:
这个想法是建立有意义的交流,并告诉人们他们需要知道什么,而不再需要更多。

因此,如果Twitter用户应该是子发布者,但是页面上的不同小部件(时间轴,搜索与近期图片等)对彼此的了解不多(当然也不能使每张图片都能与每次时间轴更新共享) ),然后创建一个全局主持人,整个小部件可以通过它与其他小部件进行通信(例如,当需要根据搜索结果更新时间线时),并且在每个小部件内部都具有一个主持人和/或pub-sub用于不同的连接,组件。

希望能有所帮助,并且我希望能解释为什么通过这样做而不是劫持真实事件,然后在线触发旨在针对程序不同区域的虚假事件,来设计一个松耦合的大型程序更容易。

老实说,如果您的整个网站及其所有程序都归结为:“我得到了执行此操作的输入,而另一个执行了另一操作的输入”,答案是,它实际上也没有关系许多。

当您到达以下位置时:“我有一个页面,其中有8个空格用于不同的小部件,并且有16种可能的小部件可以随时在这8个插槽中的任何一个中加载,并且某些小部件中应该包含一些主要操作引起其他小部件中的响应,并且每个小部件都需要内部控制很多事件,我们需要通过AJAX库和DOM / MVC(或MVVM)库来控制所有内部事件。每个小部件本身,只有我一个...”

那是个好主意,那就是敲定这些东西,敲定Promises / Deferreds / Futures,然后将您的大创意分解成较小的部分,并分散到正在运行的应用程序生命周期的不同阶段。

关于javascript - (模拟按键的缺点是什么?是否有更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14387645/

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