jQuery event 源码注释

本文详细解析了jQuery中的事件处理机制,包括事件绑定、解除绑定、触发等核心功能,并介绍了jQuery如何处理不同浏览器间的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. /*
  2.  * author:prk
  3.  * date:2008-08-17
  4.  * comment:analyse of jquery event
  5.  * 
  6.  */
  7. jQuery.event = {
  8.     // add 事件到一个元素上。
  9.     add : function(elem, types, handler, data) {
  10.         if (elem.nodeType == 3 || elem.nodeType == 8)// 空白节点或注释
  11.             return;
  12.         // IE不能传入window,先复制一下。
  13.         if (jQuery.browser.msie && elem.setInterval)
  14.             elem = window;
  15.         // 为handler分配一个全局唯一的Id
  16.         if (!handler.guid)
  17.             handler.guid = this.guid++;
  18.         // 把data附到handler.data中
  19.         if (data != undefined) {
  20.             var fn = handler;
  21.             handler = this.proxy(fn, function() {// 唯一Id,wrap原始handler Fn
  22.                         return fn.apply(this, arguments);
  23.                     });
  24.             handler.data = data;
  25.         }
  26.         // 初始化元素的events。如果没有取到events中值,就初始化data: {}
  27.         var events = jQuery.data(elem, "events")
  28.                 || jQuery.data(elem, "events", {}),
  29.         // 如果没有取到handle中值,就初始化data: function() {....}
  30.         handle = jQuery.data(elem, "handle")
  31.                 || jQuery.data(elem, "handle"function() {
  32.                     // 处理一个触发器的第二个事件和当page已经unload之后调用一个事件。
  33.                         if (typeof jQuery != "undefined"
  34.                                 && !jQuery.event.triggered)
  35.                             return jQuery.event.handle.apply(// arguments.callee.elem=handle.elem
  36.                                     arguments.callee.elem, arguments);
  37.                     });
  38.         // 增加elem做为handle属性,防止IE由于没有本地Event而内存泄露。
  39.         handle.elem = elem;
  40.         // 处理采用空格分隔多个事件名,如jQuery(...).bind("mouseover mouseout", fn);
  41.         jQuery.each(types.split(//s+/), function(index, type) {
  42.             // 命名空间的事件,一般不会用到。
  43.                 var parts = type.split(".");
  44.                 type = parts[0];
  45.                 handler.type = parts[1];
  46.                 // 捆绑到本元素type事件的所有处理函数
  47.                 var handlers = events[type];
  48.                 if (!handlers) {// 没有找到处理函数列表就初始化事件队列
  49.                     handlers = events[type] = {};
  50.                     // 如果type不是ready,或ready的setup执行返回false
  51.                     if (!jQuery.event.special[type]
  52.                             || jQuery.event.special[type].setup
  53.                                     .call(elem, data) === false) {
  54.                         // 调用系统的事件函数来注册事件
  55.                         if (elem.addEventListener)// FF
  56.                             elem.addEventListener(type, handle, false);
  57.                         else if (elem.attachEvent)// IE
  58.                             elem.attachEvent("on" + type, handle);
  59.                     }
  60.                 }
  61.                 // 把处理器的id和handler形式属性对的形式保存在handlers列表中,
  62.                 // 也存在events[type][handler.guid]中。
  63.                 handlers[handler.guid] = handler;
  64.                 // 全局缓存这个事件的使用标识
  65.                 jQuery.event.global[type] = true;
  66.             });
  67.         // 防止IE内存泄露。
  68.         elem = null;
  69.     },
  70.     guid : 1,
  71.     global : {},
  72.     // 从元素中remove一个事件
  73.     remove : function(elem, types, handler) {
  74.         if (elem.nodeType == 3 || elem.nodeType == 8)
  75.             return;
  76.         // 取出元素的events中Fn列表
  77.         var events = jQuery.data(elem, "events"), ret, index;
  78.         if (events) {
  79.             // remove所有的该元素的事件 .是命名空间的处理
  80.             if (types == undefined
  81.                     || (typeof types == "string" && types.charAt(0) == "."))
  82.                 for (var type in events)
  83.                     this.remove(elem, type + (types || ""));
  84.             else {
  85.                 // types, handler参数采用{type:xxx,handler:yyy}形式
  86.                 if (types.type) {
  87.                     handler = types.handler;
  88.                     types = types.type;
  89.                 }
  90.                 // 处理采用空格分隔多个事件名 jQuery(...).unbind("mouseover mouseout", fn);
  91.                 jQuery
  92.                         .each(types.split(//s+/), function(index, type) {
  93.                             // 命名空间的事件,一般不会用到。
  94.                                 var parts = type.split(".");
  95.                                 type = parts[0];
  96.                                 if (events[type]) {// 事件名找到
  97.                                     if (handler)// handler传入,就remove事件名的这个处理函数
  98.                                         delete events[type][handler.guid];//guid的作用
  99.                                     else    // remove这个事件的所有处理函数,带有命名空间的处理
  100.                                         for (handler in events[type])
  101.                                             if (!parts[1]
  102.                                                     || events[type][handler].type == parts[1])
  103.                                                 delete events[type][handler];
  104.                                     // 如果没有该事件的处理函数存在,就remove事件名
  105.                                     for (ret in events[type])// 看看有没有?
  106.                                         break;
  107.                                     if (!ret) {// 没有
  108.                                         if (!jQuery.event.special[type]//不是ready
  109.                                                 || jQuery.event.special[type].teardown
  110.                                                         .call(elem) === false) {// type不等于ready
  111.                                             if (elem.removeEventListener)// 在浏览器中remove事件名
  112.                                                 elem.removeEventListener(type,
  113.                                                         jQuery.data(elem,
  114.                                                                 "handle"),
  115.                                                         false);
  116.                                             else if (elem.detachEvent)
  117.                                                 elem.detachEvent("on" + type,
  118.                                                         jQuery.data(elem,
  119.                                                                 "handle"));
  120.                                         }
  121.                                         ret = null;
  122.                                         delete events[type];// 在缓存中除去。
  123.                                     }
  124.                                 }
  125.                             });
  126.             }
  127.             // 不再使用,除去expando
  128.             for (ret in events)
  129.                 break;
  130.             if (!ret) {
  131.                 var handle = jQuery.data(elem, "handle");
  132.                 if (handle)
  133.                     handle.elem = null;
  134.                 jQuery.removeData(elem, "events");
  135.                 jQuery.removeData(elem, "handle");
  136.             }
  137.         }
  138.     },
  139.     trigger : function(type, data, elem, donative, extra) {
  140.         data = jQuery.makeArray(data);
  141.         if (type.indexOf("!") >= 0) {// 支持!的not的操作如!click,除click之后的所有
  142.             type = type.slice(0, -1);// 除最后一个字符?
  143.             var exclusive = true;
  144.         }
  145.         if (!elem) {// 处理全局的fire事件
  146.             if (this.global[type])
  147.                 jQuery.each(jQuery.cache, function() {
  148.                     // 从cache中找到所有注册该事件的元素,触发改事件的处理函数
  149.                         if (this.events && this.events[type])
  150.                             jQuery.event.trigger(type, data, this.handle.elem);
  151.                     });
  152.         } else {// 处理单个元素事件的fire事件
  153.             if (elem.nodeType == 3 || elem.nodeType == 8)
  154.                 return undefined;
  155.             var val, ret, fn = jQuery.isFunction(elem[type] || null),
  156.             // 我们是否要提交一个伪造的事件?
  157.             event = !data[0] || !data[0].preventDefault;
  158.             // 构建伪造的事件。
  159.             if (event) {
  160.                 data.unshift( {//存到数组中的第一个
  161.                     type : type,
  162.                     target : elem,
  163.                     preventDefault : function() {
  164.                     },
  165.                     stopPropagation : function() {
  166.                     },
  167.                     timeStamp : now()
  168.                 });
  169.                 data[0][expando] = true// 不需要修正伪造事件
  170.             }
  171.             //防止事件名出错
  172.             data[0].type = type;
  173.             if (exclusive)
  174.                 data[0].exclusive = true;
  175.             // 触发事件
  176.             var handle = jQuery.data(elem, "handle");
  177.             if (handle)
  178.                 val = handle.apply(elem, data);
  179.             // Handle triggering native .onfoo handlers (and on links since we
  180.             // don't call .click() for links)
  181.             //处理触发.onfoo这样的本地处理方法,但是是对于links 's .click()不触发
  182.             if ((!fn || (jQuery.nodeName(elem, 'a') && type == "click"))
  183.                     && elem["on" + type]&& elem["on" + type].apply(elem, data) === false)
  184.                 val = false;
  185.             // Extra functions don't get the custom event object
  186.             if (event)
  187.                 data.shift();
  188.             // 处理触发extra事件
  189.             if (extra && jQuery.isFunction(extra)) {
  190.                 //执行extra,同时把结果存到data中。
  191.                 ret = extra.apply(elem, val == null ? data : data.concat(val));
  192.                 // if anything is returned, give it precedence and have it
  193.                 // overwrite the previous value
  194.                 if (ret !== undefined)
  195.                     val = ret;
  196.             }
  197.             // 触发本地事件
  198.             if (fn && donative !== false && val !== false
  199.                     && !(jQuery.nodeName(elem, 'a') && type == "click")) {
  200.                 this.triggered = true;
  201.                 try {
  202.                     elem[type]();
  203.                     //对于一些hidden的元素,IE会报错
  204.                 } catch (e) {
  205.                 }
  206.             }
  207.             this.triggered = false;
  208.         }
  209.         return val;
  210.     },
  211.     handle : function(event) {
  212.         // 返回 undefined or false
  213.         var val, ret, namespace, all, handlers;
  214.         event = arguments[0] = jQuery.event.fix(event || window.event);
  215.         // 命名空间处理
  216.         namespace = event.type.split(".");
  217.         event.type = namespace[0];
  218.         namespace = namespace[1];
  219.         // all = true 表明任何 handler
  220.         all = !namespace && !event.exclusive;
  221.         // 找到元素的events中缓存的事件名的处理函数列表
  222.         handlers = (jQuery.data(this"events") || {})[event.type];
  223.         for (var j in handlers) {// 每个处理函数执行
  224.             var handler = handlers[j];
  225.             // Filter the functions by class
  226.             if (all || handler.type == namespace) {
  227.                 // 传入引用,为了之后删除它们
  228.                 event.handler = handler;
  229.                 event.data = handler.data;
  230.                 ret = handler.apply(this, arguments);// 执行事件处理函数
  231.                 if (val !== false)
  232.                     val = ret;// 只要有一个处理函数返回false,本函数就返回false.
  233.                 if (ret === false) {// 不执行浏览器默认的动作
  234.                     event.preventDefault();
  235.                     event.stopPropagation();
  236.                 }
  237.             }
  238.         }
  239.         return val;
  240.     },
  241.     props : "altKey attrChange attrName bubbles button cancelable charCode clientX "
  242.             + "clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode "
  243.             + "metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX "
  244.             + "screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which"
  245.                     .split(" "),
  246.     //对事件进行包裹。
  247.     fix : function(event) {
  248.         if (event[expando] == true)//表明事件已经包裹过
  249.             return event;
  250.         //保存原始event,同时clone一个。
  251.         var originalEvent = event;
  252.         event = {
  253.             originalEvent : originalEvent
  254.         };
  255.         for (var i = this.props.length, prop;i;) {
  256.             prop = this.props[--i];
  257.             event[prop] = originalEvent[prop];
  258.         }
  259.         
  260.         event[expando] = true;
  261.         
  262.         //加上preventDefault and stopPropagation,在clone不会运行
  263.         event.preventDefault = function() {
  264.             // 在原始事件上运行
  265.             if (originalEvent.preventDefault)
  266.                 originalEvent.preventDefault();
  267.             
  268.             originalEvent.returnValue = false;
  269.         };
  270.         event.stopPropagation = function() {
  271.             // 在原始事件上运行
  272.             if (originalEvent.stopPropagation)
  273.                 originalEvent.stopPropagation();
  274.             
  275.             originalEvent.cancelBubble = true;
  276.         };
  277.         // 修正 timeStamp
  278.         event.timeStamp = event.timeStamp || now();
  279.         // 修正target
  280.         if (!event.target)
  281.             event.target = event.srcElement || document;            
  282.         if (event.target.nodeType == 3)//文本节点是父节点。
  283.             event.target = event.target.parentNode;
  284.         // relatedTarget
  285.         if (!event.relatedTarget && event.fromElement)
  286.             event.relatedTarget = event.fromElement == event.target
  287.                     ? event.toElement
  288.                     : event.fromElement;
  289.         // Calculate pageX/Y if missing and clientX/Y available
  290.         if (event.pageX == null && event.clientX != null) {
  291.             var doc = document.documentElement, body = document.body;
  292.             event.pageX = event.clientX
  293.                     + (doc && doc.scrollLeft || body && body.scrollLeft || 0)
  294.                     - (doc.clientLeft || 0);
  295.             event.pageY = event.clientY
  296.                     + (doc && doc.scrollTop || body && body.scrollTop || 0)
  297.                     - (doc.clientTop || 0);
  298.         }
  299.         // Add which for key events
  300.         if (!event.which
  301.                 && ((event.charCode || event.charCode === 0)
  302.                         ? event.charCode
  303.                         : event.keyCode))
  304.             event.which = event.charCode || event.keyCode;
  305.         // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
  306.         if (!event.metaKey && event.ctrlKey)
  307.             event.metaKey = event.ctrlKey;
  308.         // Add which for click: 1 == left; 2 == middle; 3 == right
  309.         // Note: button is not normalized, so don't use it
  310.         if (!event.which && event.button)
  311.             event.which = (event.button & 1 ? 1 : (event.button & 2
  312.                     ? 3
  313.                     : (event.button & 4 ? 2 : 0)));
  314.         return event;
  315.     },
  316.     proxy : function(fn, proxy) {
  317.         // 作用就是分配全局guid.
  318.         proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
  319.         return proxy;
  320.     },
  321.     special : {
  322.         ready : {
  323.             // Make sure the ready event is setup
  324.             setup : bindReady,
  325.             teardown : function() {
  326.             }
  327.         }
  328.     }
  329. };
  330. if (!jQuery.browser.msie) {
  331.     // Checks if an event happened on an element within another element
  332.     // Used in jQuery.event.special.mouseenter and mouseleave handlers
  333.     var withinElement = function(event) {
  334.         // Check if mouse(over|out) are still within the same parent element
  335.         var parent = event.relatedTarget;
  336.         // Traverse up the tree
  337.         while (parent && parent != this)
  338.             try {
  339.                 parent = parent.parentNode;
  340.             } catch (e) {
  341.                 parent = this;
  342.             }
  343.         if (parent != this) {
  344.             // set the correct event type
  345.             event.type = event.data;
  346.             // handle event if we actually just moused on to a non sub-element
  347.             jQuery.event.handle.apply(this, arguments);
  348.         }
  349.     };
  350.     jQuery.each( {
  351.         mouseover : 'mouseenter',
  352.         mouseout : 'mouseleave'
  353.     }, function(orig, fix) {
  354.         jQuery.event.special[fix] = {
  355.             setup : function() {
  356.                 jQuery.event.add(this, orig, withinElement, fix);
  357.             },
  358.             teardown : function() {
  359.                 jQuery.event.remove(this, orig, withinElement);
  360.             }
  361.         };
  362.     });
  363. }
  364. jQuery.fn.extend( {
  365.     bind : function(type, data, fn) {
  366.         return type == "unload" ? this.one(type, data, fn) : this
  367.                 .each(function() {// fn || data, fn && data实现了data参数可有可无
  368.                     jQuery.event.add(this, type, fn || data, fn && data);
  369.                 });
  370.     },
  371.         // 为每一个匹配元素的特定事件(像click)绑定一个一次性的事件处理函数。
  372.         // 在每个对象上,这个事件处理函数只会被执行一次。其他规则与bind()函数相同。
  373.         // 这个事件处理函数会接收到一个事件对象,可以通过它来阻止(浏览器)默认的行为。
  374.         // 如果既想取消默认的行为,又想阻止事件起泡,这个事件处理函数必须返回false。
  375.         one : function(type, data, fn) {
  376.             var one = jQuery.event.proxy(fn || data, function(event) {
  377.                 jQuery(this).unbind(event, one);
  378.                 return (fn || data).apply(this, arguments);// this-->当前的元素
  379.                 });
  380.             return this.each(function() {
  381.                 jQuery.event.add(this, type, one, fn && data);
  382.             });
  383.         },
  384.         // bind()的反向操作,从每一个匹配的元素中删除绑定的事件。
  385.         // 如果没有参数,则删除所有绑定的事件。
  386.         // 你可以将你用bind()注册的自定义事件取消绑定。
  387.         // I如果提供了事件类型作为参数,则只删除该类型的绑定事件。
  388.         // 如果把在绑定时传递的处理函数作为第二个参数,则只有这个特定的事件处理函数会被删除。
  389.         unbind : function(type, fn) {
  390.             return this.each(function() {
  391.                 jQuery.event.remove(this, type, fn);
  392.             });
  393.         },
  394.     
  395.         trigger : function(type, data, fn) {
  396.             return this.each(function() {
  397.                 jQuery.event.trigger(type, data, thistrue, fn);
  398.             });
  399.         },
  400.         //这个特别的方法将会触发指定的事件类型上所有绑定的处理函数。但不会执行浏览器默认动作.
  401.         triggerHandler : function(type, data, fn) {
  402.             return this[0]
  403.                     && jQuery.event.trigger(type, data, this[0], false, fn);
  404.         },
  405.         
  406.         //每次点击后依次调用函数。
  407.         toggle : function(fn) {     
  408.             var args = arguments, i = 1;
  409.             
  410.             while (i < args.length)//每个函数分配GUID
  411.                 jQuery.event.proxy(fn, args[i++]);
  412.             return this.click(jQuery.event
  413.                     .proxy(fn, function(event) {//分配GUID                    
  414.                             this.lastToggle = (this.lastToggle || 0) % i;//上一个函数                            
  415.                             event.preventDefault();//阻止缺省动作
  416.                             //执行参数中的第几个函数,apply可以采用array-like的参数
  417.                             //With apply, you can use an array literal, 
  418.                             //for example, fun.apply(this, [name, value]),
  419.                             //or an Array object, for example, fun.apply(this, new Array(name, value)). 
  420.                             return args[this.lastToggle++].apply(this,
  421.                                     arguments) || false;
  422.                         }));
  423.         },
  424.         
  425.         //一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法。
  426.         //这是一个自定义的方法,它为频繁使用的任务提供了一种“保持在其中”的状态。
  427.         //当鼠标移动到一个匹配的元素上面时,会触发指定的第一个函数。当鼠标移出这个元素时,
  428.         //会触发指定的第二个函数。而且,会伴随着对鼠标是否仍然处在特定元素中的检测(例如,处在div中的图像),
  429.         //如果是,则会继续保持“悬停”状态,而不触发移出事件(修正了使用mouseout事件的一个常见错误)。
  430.         hover : function(fnOver, fnOut) {
  431.             return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
  432.         },
  433.         
  434.         //dom ready时执行 fn
  435.         ready : function(fn) {          
  436.             bindReady();//注册监听          
  437.             if (jQuery.isReady)//ready就运行               
  438.                 fn.call(document, jQuery);          
  439.             else
  440.                 // 增加这个函数到queue中。可见支持无数的ready的调用。
  441.                 jQuery.readyList.push(function() {
  442.                     return fn.call(this, jQuery);
  443.                 });
  444.             return this;
  445.         }
  446.     });
  447. jQuery.extend( {
  448.     isReady : false,
  449.     readyList : [],
  450.     // Handle when the DOM is ready
  451.         ready : function() {            
  452.             if (!jQuery.isReady) {      
  453.                 jQuery.isReady = true;
  454.                 
  455.                 if (jQuery.readyList) {                 
  456.                     jQuery.each(jQuery.readyList, function() {
  457.                         this.call(document);
  458.                     });             
  459.                     jQuery.readyList = null;
  460.                 }
  461.                 
  462.                 jQuery(document).triggerHandler("ready");
  463.             }
  464.         }
  465.     });
  466. var readyBound = false;
  467. function bindReady() {
  468.     if (readyBound)
  469.         return;
  470.     readyBound = true;
  471.     // Mozilla, Opera, webkit nightlies 支持DOMContentLoaded事件    
  472.     if (document.addEventListener && !jQuery.browser.opera)
  473.         //当DOMContentLoaded事件触发时就运行jQuery.ready
  474.         document.addEventListener("DOMContentLoaded", jQuery.ready, false);
  475.     //IE或不是frame的window
  476.     if (jQuery.browser.msie && window == top)
  477.         (function() {
  478.             if (jQuery.isReady)
  479.                 return;
  480.             try {
  481.                 // 在ondocumentready之前,一直都会抛出异常              
  482.                 // http://javascript.nwbox.com/IEContentLoaded/
  483.                 document.documentElement.doScroll("left");
  484.             } catch (error) {
  485.                 //一直运行bindReady()(=arguments.callee)
  486.                 setTimeout(arguments.callee, 0);
  487.                 return;
  488.             }           
  489.             jQuery.ready();//documentready就运行jQuery.ready
  490.         })();
  491.     if (jQuery.browser.opera)
  492.         document.addEventListener("DOMContentLoaded"function() {
  493.             if (jQuery.isReady)
  494.                 return;
  495.                 //只有styleSheets完全enable时,才是完全的load,其实还有pic
  496.             for (var i = 0;i < document.styleSheets.length; i++)
  497.                 if (document.styleSheets[i].disabled) {//通过styleSheets来判断
  498.                     setTimeout(arguments.callee, 0);
  499.                     return;
  500.                 }           
  501.                 jQuery.ready();
  502.             }, false);
  503.     if (jQuery.browser.safari) {
  504.         var numStyles;
  505.         (function() {
  506.             if (jQuery.isReady)
  507.                 return;
  508.                 //首先得得到readyState=loaded或=complete
  509.             if (document.readyState != "loaded"
  510.                     && document.readyState != "complete") {
  511.                 setTimeout(arguments.callee, 0);
  512.                 return;
  513.             }
  514.             //取得style的length,比较它们之间的长度,看看是不是完成loaded
  515.             if (numStyles === undefined)
  516.                 numStyles = jQuery("style, link[rel=stylesheet]").length;
  517.             if (document.styleSheets.length != numStyles) {
  518.                 setTimeout(arguments.callee, 0);
  519.                 return;
  520.             }           
  521.             jQuery.ready();
  522.         })();
  523.     }
  524.     //最后只能依赖于window.load.
  525.     jQuery.event.add(window, "load", jQuery.ready);
  526. }
  527. //为jquery对象增加常用的事件方法
  528. jQuery
  529.         .each(
  530.                 ("blur,focus,load,resize,scroll,unload,click,dblclick,"
  531.                         + "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + "submit,keydown,keypress,keyup,error")
  532.                         .split(","), function(i, name) {                    
  533.                 jQuery.fn[name] = function(fn) {
  534.                     return fn ? this.bind(name, fn) : this.trigger(name);
  535.                 };
  536.             });
  537. // Prevent memory leaks in IE
  538. // And prevent errors on refresh with events like mouseover in other browsers
  539. // Window isn't included so as not to unbind existing unload events
  540. jQuery(window).bind('unload'function() {
  541.     for (var id in jQuery.cache)
  542.         // Skip the window
  543.         if (id != 1 && jQuery.cache[id].handle)
  544.             jQuery.event.remove(jQuery.cache[id].handle.elem);
  545. });
资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 四路20秒声光显示计分抢答器Multisim14仿真源文件+设计文档资料摘要 数字抢答器由主体电路与扩展电路组成。优先编码电路、锁存器、译码电路将参赛队的输入信号在显示器上输出;用控制电路和主持人开关启动报警电路,以上两部分组成主体电路。通过定时电路和译码电路将秒脉冲产生的信号在显示器上输出实现计时功能,构成扩展电路。经过布线、焊接、调试等工作后数字抢答器成形。关键字:开关阵列电路;触发锁存电路;解锁电路;编码电路;显示电路 一、设计目的 本设计是利用已学过的数电知识,设计的4人抢答器。(1)重温自己已学过的数电知识;(2)掌握数字集成电路的设计方法和原理;(3)通过完成该设计任务掌握实际问题的逻辑分析,学会对实际问题进行逻辑状态分配、化简;(4)掌握数字电路各部分电路与总体电路的设计、调试、模拟仿真方法。 二、整体设计 (一)设计任务与要求: 抢答器同时供4名选手或4个代表队比赛,分别用4个按钮S0 ~ S3表示。 设置一个系统清除和抢答控制开关S,该开关由主持人控制。 抢答器具有锁存与显示功能。即选手按动按钮,锁存相应的编号,并在LED数码管上显示,同时扬声器发出报警声响提示。选手抢答实行优先锁存,优先抢答选手的编号一直保持到主持人将系统清除为止。 参赛选手在设定的时间内进行抢答,抢答有效,定时器停止工作,显示器上显示选手的编号和抢答的时间,并保持到主持人将系统清除为止。 如果定时时间已到,无人抢答,本次抢答无效。 (二)设计原理与参考电路 抢答器的组成框图如下图所示。它主要由开关阵列电路、触发锁存电路、解锁电路、编码电路和显示电路等几部分组成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值