简体   繁体   中英

“Function factory” doesn't seem to work, JavaScript

I'm displaying a series of images in a loop, and I'm trying to implement some sort of nudity filter so I'm using nude.js , a library that can somewhat detect nudity. Here's the code:

// we're inside a loop
$(".images").prepend($("<img>").attr({src: whatever, id: uniqueid}).load(function(e) {
    nude.load(e.target.id);
    nude.scan(function(result) { if (!result) $(e.target).detach(); });
});

However, it detaches all of the wrong images because nude.js is slow and it completes after the loop has gone on to the later iterations, detaching those images instead of the one it was working on.

I've tried using a function factory:

function generateCallback(arg) {
    return function(result) { if (!result) $(arg).detach(); };
}

and

nude.scan( generateCallback(e.target) )

but the same thing happens.

What I want is a load event that will remove the image if it seems to contain nudity. How can I do this properly?

EDIT: nude.js works like this:

nude.load(imageid);
nude.scan(callback); // it'll pass true or false into the callback

another edit: accidentally omitted the id setting from the code I posted, but it was there in my real code, so I added it here.

I suspect the case here is that this kind of sequential processing won't work with nude.js.

Looking at the nude.js code , I think your problem is occurring in the call to nude.scan . nude.js has a variable that stores the function to invoke after the scan has completed. When calling nude.scan(callback) , this variable is set to be callback .

From your PasteBin , it seems as though the callback gets assigned as expected on the first call, but on the second and subsequent calls, it gets replaced, hence why the second image is detached and not the first.

What happends to your script, is that the e var is global to the function and so after each loop it gets replaced with the new one. So when the first image is scanned, e already became the event of the second image, which get detached.

To solve your problem, use closures. If you want to know more about closures, have a look here . Otherway, here's the solution to your problem :

$(".images").prepend($("<img>").attr({src: whatever, id: uniqueid}).load(function(e) {
    (function(e) {
        nude.load(e.target.id);
        nude.scan(function(result) { if (!result) $(e.target).detach(); });
    }) (e);
});

EDIT: AS nick_w said, there is var that contains the callback and probably gets replaced each time so this is why it isn't the right picture getting detached. You will probably have to modify the script yourself

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM