javascript 你如何制作一个事件监听器来检测布尔变量是否为真?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6783876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:51:38  来源:igfitidea点击:

How do you make an event listener that detects if a boolean variable becomes true?

javascripteventsevent-handlingjquery

提问by trusktr

For example, I have var menu_ready = false;. I have an ajax function that sets menu_readyto true when the ajax stuff is done:

例如,我有var menu_ready = false;. 我有一个 ajax 函数,menu_ready当 ajax 完成时设置为 true:

//set up event listener here

$(...).load(..., function() {
    ...
    menu_ready = true;
}

How do I set up an event listener that waits for menu_readyto be true?

如何设置等待为menu_ready真的事件侦听器?

采纳答案by Jonathan M

One way is continual polling:

一种方法是持续轮询:

function checkMenu() {
    if (!menu_ready) {
        setTimeout("checkMenu();", 1000);
        return;
    } else {
        // menu_ready is true, so do what you need to do here.
    }
}

and...

和...

<body onload="checkMenu();">

回答by gilly3

You can't attach event listeners to JavaScript variables per se, but you can fake it. Instead of a boolean var, use an object with get, set, and listenmethods:

您不能将事件侦听器本身附加到 JavaScript 变量,但您可以伪造它。取而代之的是布尔变种,使用对象有getsetlisten方法:

function Bool(initialValue) {
    var bool = !!initialValue;
    var listeners = [];
    var returnVal = function(value) {
        if (arguments.length) {
            var oldValue = bool;
            bool = !!value;
            listeners.forEach(function (listener, i, list) {
                listener.call(returnVal, { oldValue: oldValue, newValue: bool });
            });
        }
        return bool
    };
    returnVal.addListener = function(fn) {
        if (typeof fn == "function") {
            listeners.push(fn);
        }
        else {
            throw "Not a function!";
        }
    };
    return returnVal;
}

You'd use it like this:

你会像这样使用它:

var menu_ready = Bool(false);
if (menu_ready()) {
    // this code won't get executed, because menu_ready() will currently return false;
}
menu_ready.addListener(function (e) {
    if (e.oldValue != e.newValue) {
        // value changed!
    }
});
menu_ready(true);  // listeners are called.

回答by jfriend00

Since this is a pretty old question and many of these answers are out of date, I thought I'd add a more current answer.

由于这是一个相当古老的问题,而且其中许多答案已经过时,我想我会添加一个更新的答案。

Background

背景

Javascript is an event driven language. So, any change that occurs in the environment at any time other than when the page is first loaded is caused by some sort of event. As such, the best way to communicate changes is to use events. You either listen for the same event that caused the change you want to watch or you create a new event to let people know when something specifically has changed.

Javascript 是一种事件驱动语言。因此,除了首次加载页面之外的任何时间,环境中发生的任何更改都是由某种事件引起的。因此,传达更改的最佳方式是使用事件。您要么监听导致您想要观看的更改的同一事件,要么创建一个新事件以让人们知道何时发生了具体的变化。

Node.js has an eventEmitter object that is very useful and is pure Javascript (no DOM involved). That same code can also be used in the browser if one wants a general purpose event mechanism that is independent of the DOM.

Node.js 有一个非常有用的 eventEmitter 对象,它是纯 Javascript(不涉及 DOM)。如果想要一种独立于 DOM 的通用事件机制,同样的代码也可以在浏览器中使用。

The browser DOM has it's own event notification system where you can create events, trigger events and listen for events.

浏览器 DOM 有它自己的事件通知系统,您可以在其中创建事件、触发事件和侦听事件。

Polling for changes (as the accepted answer here shows) is generally a "hack" that is inefficient, can miss changes, is not necessarily timely, wastes battery and CPU, etc... If you control the code, there is always a better way to design it than polling.

轮询更改(如此处接受的答案所示)通常是一种效率低下的“黑客”,可能会错过更改,不一定及时,浪费电池和 CPU 等......如果您控制代码,总会有更好的设计它的方式比轮询。

The OP's Actual Problem

OP的实际问题

There still is not efficient mechanism of monitoring a variable change, but the OP's problem was actually that someone wants to know when this code gets triggered:

仍然没有有效的机制来监控变量变化,但 OP 的问题实际上是有人想知道这段代码何时被触发:

$(...).load(..., function() {
    ...
    menu_ready = true;
}

Of course, one simple answer is that anyone who wants to know when that is ready could also just monitor the same thing this is with $(...).load(), but that would somewhat tie their notification to how this was specifically implemented.

当然,一个简单的答案是,任何想知道何时准备就绪的人也可以只监视与 相同的事情$(...).load(),但这会在某种程度上将他们的通知与具体实施方式联系起来。

Creating Our Own Event Notification That Anyone Can Listen For

创建我们自己的任何人都可以收听的事件通知

Instead, what would be better would be to create our own event and when we know the menu is ready, we trigger that event. Then anyone, anywhere in the code can listen for that same event.

相反,最好创建我们自己的事件,当我们知道菜单准备好时,我们触发该事件。然后代码中任何地方的任何人都可以侦听同一事件。

The browser already has an extensible event system built in as described here. So, we can use that here. You need to pick some well-known object to trigger the event on that exists at the time any listener would want to register to know about this. Since the OP didn't show any specific context, I'll just pick the windowobject.

浏览器已经建成描述一个可扩展的事件系统在这里。所以,我们可以在这里使用它。您需要选择一些众所周知的对象来触发在任何侦听器想要注册以了解此情况时存在的事件。由于 OP 没有显示任何特定的上下文,我将只选择window对象。

$(...).load(..., function() {
    ...
    menu_ready = true;

    // create new event
    var event = new Event('menu_ready');

    // Dispatch the event.
    window.dispatchEvent(event);        
 }

Note, you can use any DOM object as the source of the event (whatever makes the most sense for your application) as long as it exists at both the time someone wants to register for the event and the time at which the event occurs.

请注意,您可以使用任何 DOM 对象作为事件源(任何对您的应用程序最有意义的对象),只要它在有人想要注册事件的时间和事件发生的时间都存在。

Then, a listener anywhere in your code can listen for this event:

然后,代码中任何位置的侦听器都可以侦听此事件:

 window.addEventListener("menu_ready", function() {
     console.log("menu is now ready");
 });

Working Demo

工作演示

Here's an actual working implementation that triggers the event upon a button press.

这是一个实际的工作实现,它在按下按钮时触发事件。

let button = document.getElementById("pressme");

button.addEventListener("click", function() {
    // create new event
    var event = new Event('menu_ready');

    // Dispatch the event.
    window.dispatchEvent(event);        

});

function log(x) {
    var div = document.createElement("div");
    div.innerHTML = x;
    document.getElementById("log").appendChild(div);
}


// then create a listener
window.addEventListener("menu_ready", function() {
    log("Got menu_ready event");
});
#log {margin-top: 50px;}
<button id="pressme">
Press Me
</button>
<div id="log">

</div>



I crafted this answer to match the original problem illustrated in the question here. For reference, there are several other useful mechanisms of seeing changes, but they generally rely on properties of an object, not just a simple variable.

我精心制作了此答案以匹配此处问题中说明的原始问题。作为参考,还有其他几种有用的查看变化的机制,但它们通常依赖于对象的属性,而不仅仅是一个简单的变量。

See all the answers on this question: Listening for variable changes. But specifically make sure you read these two:

查看关于这个问题的所有答案:Listing for variable changes。但特别要确保你阅读这两个:

Using a proxy object to track changes

使用代理对象来跟踪更改

Using getters and setters to track changes

使用 getter 和 setter 来跟踪更改

回答by jAndy

There is no cross-browser (cross-platform) event which gets that job done. There are some pretty specific mechanisms to watchobjects propertys for instance, but nothing to watch out for booleans (imo).

没有完成这项工作的跨浏览器(跨平台)事件。例如,有一些非常具体的机制来观察对象属性,但没有什么需要注意布尔值 (imo)。

You want to execute a callback function aswell at the time you're setting that variable to true. You can also apply some jQuery sugar:

您还想在将该变量设置为 true 时执行回调函数。您还可以应用一些 jQuery 糖:

function myCallbackReference() {
    alert('yay');
}

$('#foobar').load('/some/code', function() {
    menu_ready = true;
}).done( myCallbackReference );

回答by ChristopheCVB

Why do not create a function menuReady that will be fired when you want ?

为什么不创建一个可以在需要时触发的函数 menuReady 呢?

menuReady();

回答by brokenindexfinger

function menuReady(){
  // Do whatever it is you need done when menu is ready
}    

$(...).load(..., function() {
  menuReady();// menuReady is called on callback    
});

回答by Avatar

Utils = {
    eventRegister_globalVariable : function(variableName,handlers){
        eventRegister_JsonVariable(this,variableName,handlers);
    },
    eventRegister_jsonVariable : function(jsonObj,variableName,handlers){
        if(jsonObj.eventRegisteredVariable === undefined) {
            jsonObj.eventRegisteredVariable={};//this Object is used for trigger event in javascript variable value changes ku
        }
        Object.defineProperty(jsonObj, variableName , {
                    get: function() { 
                        return jsonObj.eventRegisteredVariable[variableName] },
                    set: function(value) {
                        jsonObj.eventRegisteredVariable[variableName] = value; handlers(jsonObj.eventRegisteredVariable[variableName]);}
                    });
            }