为啥出现意外字符串(帮助重写丑陋的代码)

Posted

技术标签:

【中文标题】为啥出现意外字符串(帮助重写丑陋的代码)【英文标题】:Why Unexpected string (Help rewriting ugly code)为什么出现意外字符串(帮助重写丑陋的代码) 【发布时间】:2018-09-15 03:26:39 【问题描述】:

注意事项:chrome.browserAction.onClicked.addListener with popupChrome Extension get selected text Window.postMessage()Capturing ctrl+z key combination in javascript 相关范式解释:(() => ES6 Arrow Function Is Simple, This Article Just Made It Simpler For JS Beginners (() What do parentheses surrounding an object/function/class declaration mean? return What do curly braces in JavaScript mean?

我正在寻求有关如何正确理解和重写丑陋代码的帮助。

这是给我的有效且经过测试的代码:

document.body.appendChild(document.createElement('script')).text = '(' + (() => 
 addEventListener('message', function _(e) 
   if (e.data && e.data.type === 'getSelectedTextReply') 
     removeEventListener('message', _);
     alert('SUCCESS:\n' + e.data.selectedText);
   
 );
 document.getElementById('plugin').postMessage(type: 'getSelectedText', '*');
   ) + ')()';

脚本的当前状态,经过测试和工作:

function onKeyboardKeyDown() 
    //Checking if Content-Script is inserted inside PDF viewer extension)
    if (document.getElementById('plugin')) 
        alert('This is a PDF file opened by Chrome PDF viewer');


        //After opening a PDF page with Chrome PDF viewer
        //Assign a listener to the browser window,
        //to listen for a Selected Content by an User
        function addTextSelectionListener() 
            function receiveMessage(e) 
                if (e.data && e.data.type === 'getSelectedTextReply') 
                    removeEventListener('message', receiveMessage);
                    alert('SUCCESS:\n' + e.data.selectedText);
                
            
            //Setup listener to listen for a message from Chrome PDF viewer API
            window.addEventListener('message', receiveMessage);
            //Send request to get Selected Text from Chrome PDF viewer
            document.getElementById('plugin').postMessage(
                type: 'getSelectedText'
            , '*');
        


        //add Self executable addListener() function to the Script Tag
        //before appending it to the PDF viewer
        var scriptElement = document.createElement('script');
        scriptElement.text = '(' + addTextSelectionListener + ')()';
        document.body.appendChild(scriptElement);

     else 
        //alert("This is not a PDF file page opened by Chrome PDF viewer");
    


document.onkeydown = onKeyboardKeyDown;


之前,已解决:


这是我目前所做的:

var scriptElement = document.createElement('script');

function listener()
  return 
     addEventListener('message', function _(e) 
       if (e.data && e.data.type === 'getSelectedTextReply') 
         removeEventListener('message', _);
         alert('SUCCESS:\n' + e.data.selectedText);
       
     );
     document.getElementById('plugin').postMessage(type: 'getSelectedText', '*');
   ;


scriptElement.text = '(' + listener + ')()';
document.body.appendChild(scriptElement);

但是,现在它有错误:

Uncaught SyntaxError: Unexpected string myscript.js:5

这是第五行,出现语法错误:

addEventListener('message', function _(e) 

【问题讨论】:

那么我们最终会收到垃圾邮件。 我隐藏了它,因为它可以隐藏它。需要理解代码中写的内容。 随着您从答案中获得有关问题的更多信息,问题会发生变化。 在这种情况下 - 这是问题的详细信息。 这还开着吗?我以为这已经解决了。 【参考方案1】:

你需要清楚你打算用listener方法做什么。

scriptElement.text = '(' + listener + ')()'; 这一行来看,我相信您希望您的addEventListener 和其余逻辑在listener 被附加到正文后立即运行。

仔细看,你实际上是在返回一个围绕你的逻辑的包装器,一个对象。

function listener()
  return 
    ...
  ;
  ...

您的代码不会在您的脚本被附加到 DOM 后立即执行,而是您对 listener 的调用只会返回一个包装器(至少应该是这样,但那里也有一个错误)。

如果是这样,则寻找 Solution 1Solution 2,否则寻找 Solution 3(推荐)

解决方案 1 如果您打算返回一个围绕您的逻辑的包装器,并且它必须立即运行,那么将侦听器实现更改为如下所示 -

function listener() 
    return function () 
        addEventListener('message', function _(e) 
          if (e.data && e.data.type === 'getSelectedTextReply') 
              removeEventListener('message', _);
              alert('SUCCESS:\n' + e.data.selectedText);
          
        );
        document.getElementById('plugin').postMessage( type: 'getSelectedText' , '*');
    

和你的listener 这样的电话 - scriptElement.text = '(' + listener + ')()()';

解决方案 2(不太可能)

如果您打算返回一个围绕您的逻辑的包装器并且该包装器也是一个对象,那么您会遇到多个语法错误。 喜欢-

1.您正在返回一个对象但未指定键,因此 addEventListener 调用返回的值不会被分配给返回对象中的任何道具。

这就是解释器报告 unexpected string 错误的原因,因为根据旧 ES,必须使用以下语法定义包含函数的对象:

 'addEventListener': function (msg, callBack)  

根据 ES6,对象可以采用这样的形状 -


  addListener (msg, callBack) 

正如你所见,在这两种情况下,我们都没有调用 addListener 函数,只是将它定义为对象中的 prop。 但是在您的代码中,在返回的函数中,您实际上调用了 addListener 方法,并且没有地方可以保存返回的值。

2. 对象中不能有分号分隔的键值对。这也是我认为您不打算返回对象的原因。

如果您打算返回一个对象,请将您的侦听器实现更改为如下所示 -

function listener()
  return 
    methodName () 
      addEventListener('message', function _(e) 
        if (e.data && e.data.type === 'getSelectedTextReply') 
        removeEventListener('message', _);
        alert('SUCCESS:\n' + e.data.selectedText);
      
    );
   document.getElementById('plugin').postMessage(type: 'getSelectedText', '*');
   
  

解决方案 3(根据场景推荐)

只要去掉return语句,你的函数应该是这样的-

function listener() 
  addEventListener('message', function _(e) 
      if (e.data && e.data.type === 'getSelectedTextReply') 
          removeEventListener('message', _);
          alert('SUCCESS:\n' + e.data.selectedText);
      
  );
  document.getElementById('plugin').postMessage( type: 'getSelectedText' , '*');

一旦脚本附加到正文节点,所有设置都会执行。

【讨论】:

谢谢 Himanshu,由于您的解释和正常工作,现在脚本处于更好的状态。对于大多数旁观者来说,它仍然看起来不太好。但至少现在更容易理解脚本的大部分功能。 如果您能给我您对脚本当前状态的意见,那就太好了。 还有,addEventListener('message', callback);分配给? w3schools.com/jsref/met_element_addeventlistener.asp w3school 似乎只建议这种语法:element.addEventListener(event, function, useCapture) 但是在这种情况下,没有元素,只有函数:addEventListener('message', callback);【参考方案2】:

你需要放一个

function()

在第 4 行的括号之前。在 javascript 中,您必须使用 function() 才能使某些东西成为函数。

您的新代码将更像:

return function()
...;

【讨论】:

以上是关于为啥出现意外字符串(帮助重写丑陋的代码)的主要内容,如果未能解决你的问题,请参考以下文章

错误:我的代码中出现意外的符号/输入/字符串常量/数字常量/SPECIAL

为啥此 Django API 调用出现意外的关键字参数错误?

在c中打印字符串后出现意外结果[重复]

将静态图像添加到 php 邮件系统时,为啥会出现“意外 CID”错误?

JSON数据后出现意外的非空白字符?

SyntaxError:JSON.parse:JSON 的第 1 行第 2 列出现意外字符