Chrome中已经定义了“$”?
如果您在没有脚本的纯HTML页面中的Chrome控制台中input$。 你会看到这个输出
> $ < bound(selector, startNode)
但是,当你做窗口$,输出是未定义的,
> window.$ < undefined
这里定义的$是什么,为什么我不能通过对象window
访问它?
$
是一个局部variables,通过包含代码的with
语句从__commandLineAPI
对象注入到控制台中(这就是为什么它不是全局variables)。 如果你仔细检查它(例如使用debugger; $('*');
),你会发现它基本上是一个绑定到当前窗口的函数。
$: function (selector, opt_startNode) { if (this._canQuerySelectorOnNode(opt_startNode)) return opt_startNode.querySelector(selector); return inspectedWindow.document.querySelector(selector); }
(在CommandLineAPIImpl.prototype
定义)
从命令行API参考 :
命令行API是用于使用Chrome开发人员工具执行常见任务的function集合。 这些包括select和检查DOM中的元素的便利function…
$(selector)返回指定CSSselect器的第一个DOM元素的引用。该函数是document.querySelector()函数的别名。
例如:
$('body')
添加到以前的答案,它可以在铬的VM的代码中find。
// NOTE: Please keep the list of API methods below snchronized to that in WebInspector.RuntimeModel! // NOTE: Argument names of these methods will be printed in the console, so use pretty names! /** * @type {!Array.<string>} * @const */ CommandLineAPI.members_ = [ "$", "$$", "$x", "dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear", "getEventListeners", "debug", "undebug", "monitor", "unmonitor", "table" ];
所有的实现可以在这里find
CommandLineAPIImpl.prototype = { /** * @param {string} selector * @param {!Node=} opt_startNode * @return {*} */ $: function (selector, opt_startNode) { if (this._canQuerySelectorOnNode(opt_startNode)) return opt_startNode.querySelector(selector); return inspectedWindow.document.querySelector(selector); }, /** * @param {string} selector * @param {!Node=} opt_startNode * @return {*} */ $$: function (selector, opt_startNode) { if (this._canQuerySelectorOnNode(opt_startNode)) return opt_startNode.querySelectorAll(selector); return inspectedWindow.document.querySelectorAll(selector); }, /** * @param {!Node=} node * @return {boolean} */ _canQuerySelectorOnNode: function(node) { return !!node && InjectedScriptHost.subtype(node) === "node" && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE); }, /** * @param {string} xpath * @param {!Node=} opt_startNode * @return {*} */ $x: function(xpath, opt_startNode) { var doc = (opt_startNode && opt_startNode.ownerDocument) || inspectedWindow.document; var result = doc.evaluate(xpath, opt_startNode || doc, null, XPathResult.ANY_TYPE, null); switch (result.resultType) { case XPathResult.NUMBER_TYPE: return result.numberValue; case XPathResult.STRING_TYPE: return result.stringValue; case XPathResult.BOOLEAN_TYPE: return result.booleanValue; default: var nodes = []; var node; while (node = result.iterateNext()) push(nodes, node); return nodes; } }, /** * @return {*} */ dir: function(var_args) { return InjectedScriptHost.callFunction(inspectedWindow.console.dir, inspectedWindow.console, slice(arguments)); }, /** * @return {*} */ dirxml: function(var_args) { return InjectedScriptHost.callFunction(inspectedWindow.console.dirxml, inspectedWindow.console, slice(arguments)); }, /** * @return {!Array.<string>} */ keys: function(object) { return Object.keys(object); }, /** * @return {!Array.<*>} */ values: function(object) { var result = []; for (var key in object) push(result, object[key]); return result; }, /** * @return {*} */ profile: function(opt_title) { return InjectedScriptHost.callFunction(inspectedWindow.console.profile, inspectedWindow.console, slice(arguments)); }, /** * @return {*} */ profileEnd: function(opt_title) { return InjectedScriptHost.callFunction(inspectedWindow.console.profileEnd, inspectedWindow.console, slice(arguments)); }, /** * @param {!Object} object * @param {!Array.<string>|string=} opt_types */ monitorEvents: function(object, opt_types) { if (!object || !object.addEventListener || !object.removeEventListener) return; var types = this._normalizeEventTypes(opt_types); for (var i = 0; i < types.length; ++i) { object.removeEventListener(types[i], this._logEvent, false); object.addEventListener(types[i], this._logEvent, false); } }, /** * @param {!Object} object * @param {!Array.<string>|string=} opt_types */ unmonitorEvents: function(object, opt_types) { if (!object || !object.addEventListener || !object.removeEventListener) return; var types = this._normalizeEventTypes(opt_types); for (var i = 0; i < types.length; ++i) object.removeEventListener(types[i], this._logEvent, false); }, /** * @param {*} object * @return {*} */ inspect: function(object) { return injectedScript._inspect(object); }, copy: function(object) { var string; if (injectedScript._subtype(object) === "node") { string = object.outerHTML; } else if (injectedScript.isPrimitiveValue(object)) { string = toString(object); } else { try { string = JSON.stringify(object, null, " "); } catch (e) { string = toString(object); } } var hints = { copyToClipboard: true, __proto__: null }; var remoteObject = injectedScript._wrapObject(string, "") InjectedScriptHost.inspect(remoteObject, hints); }, clear: function() { InjectedScriptHost.clearConsoleMessages(); }, /** * @param {!Node} node * @return {!Array.<!{type: string, listener: function(), useCapture: boolean, remove: function()}>|undefined} */ getEventListeners: function(node) { var result = nullifyObjectProto(InjectedScriptHost.getEventListeners(node)); if (!result) return result; /** @this {{type: string, listener: function(), useCapture: boolean}} */ var removeFunc = function() { node.removeEventListener(this.type, this.listener, this.useCapture); } for (var type in result) { var listeners = result[type]; for (var i = 0, listener; listener = listeners[i]; ++i) { listener["type"] = type; listener["remove"] = removeFunc; } } return result; }, debug: function(fn) { InjectedScriptHost.debugFunction(fn); }, undebug: function(fn) { InjectedScriptHost.undebugFunction(fn); }, monitor: function(fn) { InjectedScriptHost.monitorFunction(fn); }, unmonitor: function(fn) { InjectedScriptHost.unmonitorFunction(fn); }, table: function(data, opt_columns) { InjectedScriptHost.callFunction(inspectedWindow.console.table, inspectedWindow.console, slice(arguments)); }, /** * @param {number} num */ _inspectedObject: function(num) { return InjectedScriptHost.inspectedObject(num); }, /** * @param {!Array.<string>|string=} types * @return {!Array.<string>} */ _normalizeEventTypes: function(types) { if (typeof types === "undefined") types = ["mouse", "key", "touch", "control", "load", "unload", "abort", "error", "select", "input", "change", "submit", "reset", "focus", "blur", "resize", "scroll", "search", "devicemotion", "deviceorientation"]; else if (typeof types === "string") types = [types]; var result = []; for (var i = 0; i < types.length; ++i) { if (types[i] === "mouse") push(result, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout", "mousewheel"); else if (types[i] === "key") push(result, "keydown", "keyup", "keypress", "textInput"); else if (types[i] === "touch") push(result, "touchstart", "touchmove", "touchend", "touchcancel"); else if (types[i] === "control") push(result, "resize", "scroll", "zoom", "focus", "blur", "select", "input", "change", "submit", "reset"); else push(result, types[i]); } return result; }, /** * @param {!Event} event */ _logEvent: function(event) { inspectedWindow.console.log(event.type, event); } }
为了检查这个只是按下bound(selector, startNode)
这是一个活动的链接
这是一个只有内置function的控制台: