защо _.delay превръща моя e.type от mouseenter в mouseover

Когато задействам това събитие с backbone.js и се опитвам да забавя извикването на функцията, event.type се променя от mouseenter на mouseover, регистрационният файл на конзолата изстрелва "mouseenter", а вторият журнал е "mouseover" защо преобразуването???

app.newsroomPageElementView = Backbone.View.extend({
 events: {
    'mouseenter .featured-image': 'imageHover',
    'mouseleave .featured-image': 'imageHover'
 },
imageHover: function (e)  {
         Y.log(e.type); // this outputs out mouseenter
        _.delay(function(){ 
         Y.log(e.type); // this outputs mouseover
        }, 500);
    },    
});

защото 500 милисекунди по-късно мишката ми вече е "влязла", така че всъщност е преминаване на мишката, защото мишката ми е над събитието, когато се задейства?


person Zuriel    schedule 10.02.2013    source източник
comment
Опитайте изрично да предадете обекта e: _.delay(function (e) { ... }, 500, e);   -  person Šime Vidas    schedule 11.02.2013
comment
Освен това опитайте setTimeout вместо _.delay, за да проверите дали това поведение е причинено от _.delay (въпреки че не виждам как би могло да бъде).   -  person Šime Vidas    schedule 11.02.2013


Отговори (1)


Това се случва, защото Backbone ви предава препратка към обект, който след това използва повторно.

Както вероятно знаете, събитието mouseenter е последвано от събитие mouseover. Нямате манипулатор за mouseover, така че обикновено няма да ви пука.

Когато възникне събитие mouseenter, вашият манипулатор се извиква с този обект e. Това е препратка към някакъв обект в Backbone; регистрирате неговия type, но след това запазвате препратка към този обект във вашия delay манипулатор.

След това вашият манипулатор на събития се връща и контролът се връща обратно на Javascript нишката. Събитието mouseover се задейства. Вашият код може да го игнорира, но Backbone продължава напред и използва повторно обекта, който ви е предоставил, и поставя информацията за събитието mouseover в него.

След това вашето забавяне изтича и вие използвате e, за да разберете типа на събитието... сега има всички данни за mouseover събитие в него, така че това е, което виждате.

Това трябва да бъде полезен урок за всички ни. Първо, имайте предвид, че JS работи с препратки към обекти и ако съхраните обект, който е създаден от нещо различно от вашия код, и след това прекъснете нишката, този обект може да се промени под вас. По същия начин, ако имате методи, които връщат масиви или обекти, знайте, че връщате препратка към този масив или обект... по този начин, ако извикващият код промени съдържанието на въпросния масив или обект, това може да ви обърка; това е особено опасно, когато имате частно поле с публичен гетер. Ако не сте внимателни, можете да предадете препратка, която позволява на кода да променя вътрешността на вашите обекти, без да искате да го правите!

person Dancrumb    schedule 11.02.2013
comment
Събитието mouseenter JavaScript е собственост на Internet Explorer. Поради общата полезност на събитието, jQuery симулира това събитие, така че да може да се използва независимо от браузъра.. Подозирам, че това повторно използване на един обект на събитие е специфично за симулираните mouseenter и mouseleave събития. Маркирането на e с допълнително свойство предлага някои съвети: jsfiddle.net/ambiguous/J2MFd - person mu is too short; 11.02.2013
comment
И така, каква е окончателната присъда? тази функция ще има ли проблеми, за които трябва да се тревожа? Искам да кажа, че примерите от сайта на Microsoft показват, че някои mouseenter събития са много по-малко от mouseovers, но тъй като тази функция няма да бъде извикана от опорната мрежа, докато mouseenter технически, ако събитието се промени, това не би трябвало да има значение, нали? все още трябва да се задейства само на този първоначален mouseenter и забавянето ще се случи само след успешно mouseenter, което изисква от мен да имам mouseleave, преди да се задейства отново.?? - person Zuriel; 11.02.2013
comment
@ZurielAndrusyshyn: Винаги можете да клонирате e, за да избегнете референтния проблем. - person mu is too short; 11.02.2013
comment
@ZurielAndrusyshyn: прав си, че забавянето ще се случи само след mouseenter (или mouseleave). Както казва mu, ако имате нужда от достъп до данните за събитието, можете да клонирате e, когато влезе за първи път. Backbone и Loadash обаче не правят нищо странно със събития тук, така че сте ОК. - person Dancrumb; 11.02.2013
comment
jsfiddle.net/Zuriel/HRPDB актуализира цигулката с двата примера от mu и от api jquery уебсайт - person Zuriel; 11.02.2013