var name = ‘World!‘; (function () {if (typeof name === ‘undefined‘) {...一道关于变量提升的面试题

本文探讨了JavaScript中变量提升的特性,通过具体代码示例解释了全局与局部作用域中变量声明与初始化的时机差异,以及这如何影响程序运行结果。
ar name = 'World!';
(function () {
    if (typeof name === 'undefined') {
        var name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

在 JavaScript中, Fun 和 var 会被提升

相当于

var name = 'World!';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

答案:Goodbye Jack

巩固一下:

 var str = 'World!';   
    (function (name) {
    if (typeof name === 'undefined') {
        var name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
    })(str);
    

答案:Hello World 因为name已经变成函数内局部变量

package com.hey.fgh; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.speech.tts.TextToSpeech; import android.speech.tts.UtteranceProgressListener; import android.util.Log; import android.view.View; import android.webkit.JavascriptInterface; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.regex.Pattern; import org.json.JSONArray; import org.json.JSONObject; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private WebView mWebView; private TextToSpeech tts; private boolean isSpeaking = false; private boolean isPaused = false; private int currentSentenceIndex = 0; private int currentCharIndex = 0; private String[] sentences; private String fullOriginalText; private List<NodeInfo> nodeInfoList = new ArrayList<>(); private final Handler handler = new Handler(); private SharedPreferences sharedPreferences; private boolean isTTSInitialized = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sharedPreferences = getSharedPreferences("TTSPreferences", MODE_PRIVATE); loadProgress(); initTextToSpeech(); setupWebView(); loadWebContent("file:///android_asset/index.html"); setupButtons(); } private void setupWebView() { mWebView = findViewById(R.id.mWebView); WebSettings settings = mWebView.getSettings(); settings.setJavaScriptEnabled(true); settings.setDomStorageEnabled(true); settings.setAllowFileAccess(true); settings.setAllowContentAccess(true); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { settings.setAllowUniversalAccessFromFileURLs(true); } mWebView.addJavascriptInterface(new TextNodeInterface(), "TextNodeInterface"); mWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { // 注入高亮工具函数 injectHighlightHelper(); // 延迟采集文本节点 handler.postDelayed(() -> collectTextNodes(), 1000); } }); } private void injectHighlightHelper() { String helperJs = "(function() {" + "if (window.createHighlightAtNodeByText) return;" + // 防止重复注入 "window.createHighlightAtNodeByText = function(targetText, localStart, localEnd) {" + " var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);" + " var node;" + " while (node = walker.nextNode()) {" + " if (node.nodeType !== Node.TEXT_NODE || !node.parentNode || node.parentNode.nodeType === Node.ELEMENT_NODE && ['SCRIPT','STYLE'].includes(node.parentNode.tagName)) continue;" + " if (node.textContent.includes(targetText)) {" + " var text = node.textContent;" + " var before = text.substring(0, localStart);" + " var middle = text.substring(localStart, localEnd);" + " var after = text.substring(localEnd);" + " var parent = node.parentNode;" + " parent.innerHTML = '';" + " parent.appendChild(document.createTextNode(before));" + " var mark = document.createElement('mark');" + " mark.className = 'highlight';" + " mark.style.backgroundColor = 'yellow';" + " mark.style.color = 'black';" + " mark.textContent = middle;" + " parent.appendChild(mark);" + " parent.appendChild(document.createTextNode(after));" + " return;" + " }" + " }" + "};" + "})();"; mWebView.evaluateJavascript(helperJs, null); } private void collectTextNodes() { loadJsFromAssets("collect_text_nodes.js"); // 确保这个JS存在assets中 } private void loadJsFromAssets(String fileName) { try { InputStream is = getAssets().open(fileName); byte[] buffer = new byte[is.available()]; is.read(buffer); is.close(); String jsCode = new String(buffer, StandardCharsets.UTF_8); mWebView.evaluateJavascript(jsCode, null); } catch (Exception e) { Log.e(TAG, "加载JS失败: " + fileName, e); Toast.makeText(this, "脚本加载失败", Toast.LENGTH_SHORT).show(); } } private void splitSentences(String rawText) { String filteredText = rawText.replaceAll("[\\r\\n]+", "\n").trim(); List<String> sentenceList = new ArrayList<>(); String[] paragraphs = filteredText.split("\\n\\s*\\n|\\r\\n\\s*\\r\\n"); Pattern sentenceEnd = Pattern.compile("[。.!??!]"); for (String para : paragraphs) { para = para.trim(); if (para.isEmpty()) continue; int last = 0; java.util.regex.Matcher matcher = sentenceEnd.matcher(para); while (matcher.find()) { String sentence = para.substring(last, matcher.end()).trim(); if (!sentence.isEmpty()) { sentenceList.add(sentence); } last = matcher.end(); } if (last < para.length()) { String remaining = para.substring(last).trim(); if (!remaining.isEmpty()) { sentenceList.add(remaining); } } } sentences = sentenceList.toArray(new String[0]); Log.d(TAG, "共分割出 " + sentences.length + " 个句子"); } private void highlightInOriginalText(int globalStart, int globalEnd) { Log.d(TAG, "高亮范围: [" + globalStart + ", " + globalEnd + ")"); if (fullOriginalText == null || globalStart >= globalEnd || globalEnd > fullOriginalText.length()) { return; } List<HighlightRange> ranges = findRangesInNodes(globalStart, globalEnd); if (ranges.isEmpty()) { Log.w(TAG, "未找到匹配节点进行高亮"); return; } StringBuilder js = new StringBuilder(); js.append("(function() {"); js.append(" var oldMarks = document.querySelectorAll('mark.highlight');") .append(" oldMarks.forEach(function(m) {") .append(" var p = m.parentNode;") .append(" p.replaceChild(document.createTextNode(m.textContent), m);") .append(" p.normalize();") .append(" });"); for (HighlightRange range : ranges) { String escapedText = escapeJsString(range.node.text.substring(range.startInNode, range.endInNode)); js.append(String.format( "createHighlightAtNodeByText('%s', %d, %d);", escapedText, range.startInNode, range.endInNode )); } js.append(" setTimeout(function(){") .append(" var h = document.querySelector('mark.highlight');") .append(" if(h)h.scrollIntoView({behavior:'smooth',block:'center'});") .append(" }, 50);"); js.append("})();"); mWebView.evaluateJavascript(js.toString(), null); } private List<HighlightRange> findRangesInNodes(int start, int end) { List<HighlightRange> result = new ArrayList<>(); for (NodeInfo node : nodeInfoList) { int ns = node.start; int ne = node.start + node.text.length(); if (end <= ns || start >= ne) continue; int ls = Math.max(0, start - ns); int le = Math.min(node.text.length(), end - ns); if (ls < le) { result.add(new HighlightRange(node, ls, le)); } } return result; } private String escapeJsString(String s) { return s.replace("\\", "\\\\") .replace("'", "\\'") .replace("\"", "\\\"") .replace("\n", "\\n") .replace("\r", "\\r") .replace("\t", "\\t"); } private void speakFromCurrentPosition() { if (sentences == null || currentSentenceIndex >= sentences.length) { stopSpeaking(); return; } String sentence = sentences[currentSentenceIndex].trim(); if (sentence.isEmpty()) { currentSentenceIndex++; handler.postDelayed(this::speakFromCurrentPosition, 50); return; } int pos = fullOriginalText.indexOf(sentence); if (pos == -1) { // 尝试去除空格再找一次 String cleanFull = fullOriginalText.replaceAll("\\s+", ""); String cleanSent = sentence.replaceAll("\\s+", ""); int idx = cleanFull.indexOf(cleanSent); if (idx != -1) { pos = approximateGlobalPosition(idx, cleanSent.length()); } } if (pos == -1) { Log.w(TAG, "无法定位句子: " + sentence); currentSentenceIndex++; handler.postDelayed(this::speakFromCurrentPosition, 50); return; } int highlightStart = pos + currentCharIndex; int highlightEnd = pos + sentence.length(); highlightInOriginalText(highlightStart, highlightEnd); String toSpeak = sentence.substring(currentCharIndex); Bundle params = new Bundle(); String utteranceId = UUID.randomUUID().toString(); params.putCharSequence(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId); int status = tts.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, params, utteranceId); if (status == TextToSpeech.ERROR) { Log.e(TAG, "TTS 播放错误"); } } private int approximateGlobalPosition(int cleanIndex, int cleanLength) { int realPos = 0; int cleanPos = 0; for (int i = 0; i < fullOriginalText.length(); i++) { char c = fullOriginalText.charAt(i); if (!Character.isWhitespace(c)) { if (cleanPos == cleanIndex) { return i; } cleanPos++; } } return -1; } private void setupButtons() { Button speakButton = findViewById(R.id.speakButton); speakButton.setOnClickListener(v -> { if (isPaused && currentSentenceIndex < sentences.length) { isPaused = false; isSpeaking = true; speakFromCurrentPosition(); } else { startSpeaking(); } }); Button pauseButton = findViewById(R.id.pauseButton); pauseButton.setOnClickListener(v -> { if (isSpeaking) { tts.stop(); isSpeaking = false; isPaused = true; } }); Button stopButton = findViewById(R.id.stopButton); stopButton.setOnClickListener(v -> stopSpeaking()); } private void startSpeaking() { if (sentences == null || sentences.length == 0) { Toast.makeText(this, "尚未加载文本内容", Toast.LENGTH_SHORT).show(); return; } isSpeaking = true; isPaused = false; currentCharIndex = 0; speakFromCurrentPosition(); } private void stopSpeaking() { if (tts != null) { tts.stop(); } isSpeaking = false; isPaused = false; currentCharIndex = 0; saveProgress(); removeHighlight(); } private void removeHighlight() { mWebView.evaluateJavascript("(function(){" + "var ms=document.querySelectorAll('mark.highlight');" + "ms.forEach(m=>{m.parentNode.replaceChild(document.createTextNode(m.textContent),m);});" + "})()", null); } private void saveProgress() { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putInt("currentSentenceIndex", currentSentenceIndex); editor.putInt("currentCharIndex", currentCharIndex); editor.apply(); } private void loadProgress() { currentSentenceIndex = sharedPreferences.getInt("currentSentenceIndex", 0); currentCharIndex = sharedPreferences.getInt("currentCharIndex", 0); } private void initTextToSpeech() { tts = new TextToSpeech(this, status -> { if (status == TextToSpeech.SUCCESS) { isTTSInitialized = true; setUtteranceProgressListener(); } else { Toast.makeText(this, "TTS初始化失败", Toast.LENGTH_SHORT).show(); } }); } private void setUtteranceProgressListener() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { tts.setOnUtteranceProgressListener(new UtteranceProgressListener() { @Override public void onStart(String utteranceId) {} @Override public void onDone(String utteranceId) { handler.post(() -> { currentSentenceIndex++; currentCharIndex = 0; if (currentSentenceIndex < sentences.length) { speakFromCurrentPosition(); } else { isSpeaking = false; saveProgress(); Toast.makeText(MainActivity.this, "朗读完成", Toast.LENGTH_SHORT).show(); } }); } @Override public void onError(String utteranceId) {} }); } } @Override protected void onDestroy() { if (tts != null) { tts.stop(); tts.shutdown(); } super.onDestroy(); } // --- 数据类 --- public static class NodeInfo { String text; int start; NodeInfo(String text, int start) { this.text = text; this.start = start; } } public static class HighlightRange { NodeInfo node; int startInNode, endInNode; HighlightRange(NodeInfo node, int start, int end) { this.node = node; this.startInNode = start; this.endInNode = end; } } // --- JS 接口 --- public class TextNodeInterface { @JavascriptInterface public void onTextNodesCollected(String fullText, String nodeInfoJson) { runOnUiThread(() -> { if (fullText == null || fullText.trim().isEmpty()) { Toast.makeText(MainActivity.this, "未提取到有效文本", Toast.LENGTH_SHORT).show(); return; } fullOriginalText = fullText; nodeInfoList.clear(); try { JSONArray arr = new JSONArray(nodeInfoJson); for (int i = 0; i < arr.length(); i++) { JSONObject obj = arr.getJSONObject(i); String text = obj.getString("text"); int start = obj.getInt("start"); nodeInfoList.add(new NodeInfo(text, start)); } Log.d(TAG, "✅ 成功解析 " + nodeInfoList.size() + " 个文本节点"); } catch (Exception e) { Log.e(TAG, "解析 nodeInfo 失败", e); Toast.makeText(MainActivity.this, "结构解析失败", Toast.LENGTH_SHORT).show(); return; } splitSentences(fullOriginalText); }); } } private void loadWebContent(String url) { mWebView.loadUrl(url); } @Override public void onBackPressed() { if (mWebView.canGoBack()) { mWebView.goBack(); } else { super.onBackPressed(); } }} 这是你修改的java代码 还有个名为:collect_text_nodes.js的代码如何 :// collect_text_nodes.js (function() { var textNodes = []; var fullText = ''; function traverse(node) { if (node.nodeType === Node.TEXT_NODE) { var text = node.textContent; if (text && text.length > 0) { textNodes.push({ text: text, start: fullText.length }); fullText += text; } } else if (node.nodeType === Node.ELEMENT_NODE) { var tag = node.tagName.toLowerCase(); if (tag !== 'script' && tag !== 'style' && tag !== 'noscript') { for (var i = 0; i < node.childNodes.length; i++) { traverse(node.childNodes[i]); } } } } var container = document.getElementById('content') || document.querySelector('.content') || document.body; traverse(container); var iframes = document.getElementsByTagName('iframe'); for (var i = 0; i < iframes.length; i++) { try { var iframeDoc = iframes[i].contentDocument || iframes[i].contentWindow.document; if (iframeDoc) { traverse(iframeDoc.body); } } catch (e) { console.log("跨域iframe不可访问: " + e.message); } } try { if (typeof window.TextNodeInterface !== 'undefined') { window.TextNodeInterface.onTextNodesCollected(fullText, JSON.stringify(textNodes)); } else { console.error("❌ 未注册 TextNodeInterface,请检查 addJavascriptInterface"); } } catch (e) { console.error("❌ 回传数据失败: ", e); } console.log("✅ collect_text_nodes.js 已执行,找到文本节点数:", textNodes.length); })();
最新发布
10-14
Strophe.Builder = function (name, attrs) { // Holds the tree being built. this.nodeTree = this._makeNode(name, attrs); // Points to the current operation node. this.node = this.nodeTree; }; Strophe.Builder.prototype = { /** Function: tree * Return the DOM tree. * * This function returns the current DOM tree as an element object. This * is suitable for passing to functions like Strophe.Connection.send(). * * Returns: * The DOM tree as a element object. */ tree: function () { return this.nodeTree; }, /** Function: toString * Serialize the DOM tree to a String. * * This function returns a string serialization of the current DOM * tree. It is often used internally to pass data to a * Strophe.Request object. * * Returns: * The serialized DOM tree in a String. */ toString: function () { return Strophe.serialize(this.nodeTree); }, /** Function: up * Make the current parent element the new current element. * * This function is often used after c() to traverse back up the tree. * For example, to add two children to the same element * > builder.c('child1', {}).up().c('child2', {}); * * Returns: * The Stophe.Builder object. */ up: function () { this.node = this.node.parentNode; return this; }, /** Function: attrs * Add or modify attributes of the current element. * * The attributes should be passed in object notation. This function * does not move the current element pointer. * * Parameters: * (Object) moreattrs - The attributes to add/modify in object notation. * * Returns: * The Strophe.Builder object. */ attrs: function (moreattrs) { for (var k in moreattrs) this.node.setAttribute(k, moreattrs[k]); return this; }, /** Function: c * Add a child to the current element and make it the new current * element. * * This function moves the current element pointer to the child. If you * need to add another child, it is necessary to use up() to go back * to the parent in the tree. * * Parameters: * (String) name - The name of the child. * (Object) attrs - The attributes of the child in object notation. * * Returns: * The Strophe.Builder object. */ c: function (name, attrs) { var child = this._makeNode(name, attrs); this.node.appendChild(child); this.node = child; return this; }, /** Function: cnode * Add a child to the current element and make it the new current * element. * * This function is the same as c() except that instead of using a * name and an attributes object to create the child it uses an * existing DOM element object. * * Parameters: * (XMLElement) elem - A DOM element. * * Returns: * The Strophe.Builder object. */ cnode: function (elem) { this.node.appendChild(elem); this.node = elem; return this; }, /** Function: t * Add a child text element. * * This *does not* make the child the new current element since there * are no children of text elements. * * Parameters: * (String) text - The text data to append to the current element. * * Returns: * The Strophe.Builder object. */ t: function (text) { var child = Strophe.xmlTextNode(text); this.node.appendChild(child); return this; }, /** PrivateFunction: _makeNode * _Private_ helper function to create a DOM element. * * Parameters: * (String) name - The name of the new element. * (Object) attrs - The attributes for the new element in object * notation. * * Returns: * A new DOM element. */ _makeNode: function (name, attrs) { var node = Strophe.xmlElement(name); for (var k in attrs) node.setAttribute(k, attrs[k]); return node; } }; /** PrivateClass: Strophe.Handler * _Private_ helper class for managing stanza handlers. * * A Strophe.Handler encapsulates a user provided callback function to be * executed when matching stanzas are received by the connection. * Handlers can be either one-off or persistant depending on their * return value. Returning true will cause a Handler to remain active, and * returning false will remove the Handler. * * Users will not use Strophe.Handler objects directly, but instead they * will use Strophe.Connection.addHandler() and * Strophe.Connection.deleteHandler(). */ /** PrivateConstructor: Strophe.Handler * Create and initialize a new Strophe.Handler. * * Parameters: * (Function) handler - A function to be executed when the handler is run. * (String) ns - The namespace to match. * (String) name - The element name to match. * (String) type - The element type to match. * (String) id - The element id attribute to match. * (String) from - The element from attribute to match. * * Returns: * A new Strophe.Handler object. */ Strophe.Handler = function (handler, ns, name, type, id, from) { this.handler = handler; this.ns = ns; this.name = name; this.type = type; this.id = id; this.from = from; // whether the handler is a user handler or a system handler this.user = true; }; Strophe.Handler.prototype = { /** PrivateFunction: isMatch * Tests if a stanza matches the Strophe.Handler. * * Parameters: * (XMLElement) elem - The XML element to test. * * Returns: * true if the stanza matches and false otherwise. */ isMatch: function (elem) { var nsMatch, i; nsMatch = false; if (!this.ns) { nsMatch = true; } else { var self = this; Strophe.forEachChild(elem, null, function (elem) { if (elem.getAttribute("xmlns") == self.ns) nsMatch = true; }); nsMatch = nsMatch || elem.getAttribute("xmlns") == this.ns; } if (nsMatch && (!this.name || Strophe.isTagEqual(elem, this.name)) && (!this.type || elem.getAttribute("type") == this.type) && (!this.id || elem.getAttribute("id") == this.id) && (!this.from || elem.getAttribute("from") == this.from)) { return true; } return false; }, /** PrivateFunction: run * Run the callback on a matching stanza. * * Parameters: * (XMLElement) elem - The DOM element that triggered the * Strophe.Handler. * * Returns: * A boolean indicating if the handler should remain active. */ run: function (elem) { var result = null; try { result = this.handler(elem); } catch (e) { if (e.sourceURL) { Strophe.fatal("error: " + this.handler + " " + e.sourceURL + ":" + e.line + " - " + e.name + ": " + e.message); } else if (e.fileName) { if (typeof(console) != "undefined") { console.trace(); console.error(this.handler, " - error - ", e, e.message); } Strophe.fatal("error: " + this.handler + " " + e.fileName + ":" + e.lineNumber + " - " + e.name + ": " + e.message); } else { Strophe.fatal("error: " + this.handler); } throw e; } return result; }, /** PrivateFunction: toString * Get a String representation of the Strophe.Handler object. * * Returns: * A String. */ toString: function () { return "{Handler: " + this.handler + "(" + this.name + "," + this.id + "," + this.ns + ")}"; } }; /** PrivateClass: Strophe.TimedHandler * _Private_ helper class for managing timed handlers. * * A Strophe.TimedHandler encapsulates a user provided callback that * should be called after a certain period of time or at regular * intervals. The return value of the callback determines whether the * Strophe.TimedHandler will continue to fire. * * Users will not use Strophe.TimedHandler objects directly, but instead * they will use Strophe.Connection.addTimedHandler() and * Strophe.Connection.deleteTimedHandler(). */ /** PrivateConstructor: Strophe.TimedHandler * Create and initialize a new Strophe.TimedHandler object. * * Parameters: * (Integer) period - The number of milliseconds to wait before the * handler is called. * (Function) handler - The callback to run when the handler fires. This * function should take no arguments. * * Returns: * A new Strophe.TimedHandler object. */ Strophe.TimedHandler = function (period, handler) { this.period = period; this.handler = handler; this.lastCalled = new Date().getTime(); this.user = true; }; Strophe.TimedHandler.prototype = { /** PrivateFunction: run * Run the callback for the Strophe.TimedHandler. * * Returns: * true if the Strophe.TimedHandler should be called again, and false * otherwise. */ run: function () { this.lastCalled = new Date().getTime(); return this.handler(); }, /** PrivateFunction: reset * Reset the last called time for the Strophe.TimedHandler. */ reset: function () { this.lastCalled = new Date().getTime(); }, /** PrivateFunction: toString * Get a string representation of the Strophe.TimedHandler object. * * Returns: * The string representation. */ toString: function () { return "{TimedHandler: " + this.handler + "(" + this.period +")}"; } }; /** PrivateClass: Strophe.Request * _Private_ helper class that provides a cross implementation abstraction * for a BOSH related XMLHttpRequest. * * The Strophe.Request class is used internally to encapsulate BOSH request * information. It is not meant to be used from user's code. */ /** PrivateConstructor: Strophe.Request * Create and initialize a new Strophe.Request object. * * Parameters: * (String) data - The data to be sent in the request. * (Function) func - The function that will be called when the * XMLHttpRequest readyState changes. * (Integer) rid - The BOSH rid attribute associated with this request. * (Integer) sends - The number of times this same request has been * sent. */ Strophe.Request = function (data, func, rid, sends) { this.id = ++Strophe._requestId; this.data = data; // save original function in case we need to make a new request // from this one. this.origFunc = func; this.func = func; this.rid = rid; this.date = NaN; this.sends = sends || 0; this.abort = false; this.dead = null; this.age = function () { if (!this.date) return 0; var now = new Date(); return (now - this.date) / 1000; }; this.timeDead = function () { if (!this.dead) return 0; var now = new Date(); return (now - this.dead) / 1000; }; this.xhr = this._newXHR(); }; Strophe.Request.prototype = { /** PrivateFunction: getResponse * Get a response from the underlying XMLHttpRequest. * * This function attempts to get a response from the request and checks * for errors. * * Throws: * "parsererror" - A parser error occured. * * Returns: * The DOM element tree of the response. */ getResponse: function () { var node = null; if (this.xhr.responseXML && this.xhr.responseXML.documentElement) { node = this.xhr.responseXML.documentElement; if (node.tagName == "parsererror") { Strophe.error("invalid response received"); Strophe.error("responseText: " + this.xhr.responseText); Strophe.error("responseXML: " + Strophe.serialize(this.xhr.responseXML)); throw "parsererror"; } } else if (this.xhr.responseText) { Strophe.error("invalid response received"); Strophe.error("responseText: " + this.xhr.responseText); Strophe.error("responseXML: " + Strophe.serialize(this.xhr.responseXML)); } return node; }, /** PrivateFunction: _newXHR * _Private_ helper function to create XMLHttpRequests. * * This function creates XMLHttpRequests across all implementations. * * Returns: * A new XMLHttpRequest. */ _newXHR: function () { var xhr = null; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); if (xhr.overrideMimeType) { xhr.overrideMimeType("text/xml"); } } else if (window.ActiveXObject) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } xhr.onreadystatechange = this.func.prependArg(this); return xhr; } };
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值