1 (function(win, undefined) { 2 var SELECTORS = transformSelector; 3 4 function insertTemplate(callback) { 5 getTemplate(\'views/price-alert-messager.html\', function(template) { 6 $(document.body).append(template).attr(\'data-ruyitao-price-mind-inserted\', 1) 7 callback && callback() 8 }) 9 } 10 11 function getItemTemplate(item) { 12 var currentPrice = parseFloat(item.original_price) - parseFloat(item.reduction_price) 13 var html = \'<li class="\' + SELECTORS(\'pamb-message\') + \'" data-id=\' + item.id +\'>\' 14 html += \'<div class="\' + SELECTORS(\'pamb-product-img\') + \'"><img src="\' + item.small_image +\'" /></div>\' 15 html += \'<div class="\' + SELECTORS(\'pamb-product-info\') + \'">\' 16 html += \'<div class="\' + SELECTORS(\'pamb-product-title\') + \'">\' + item.title + \'</div>\' 17 html += \'<div class="\' + SELECTORS(\'pamb-current-price-wrap\') + \'"><span>已经降到了</span>\' 18 html += \'<span class="\' + SELECTORS(\'pamb-current-price\') + \'">¥\' + currentPrice.toFixed(2) + \'</span></div>\' 19 html += \'<div class="\' + SELECTORS(\'pamb-price-reduction-wrap\') + \'">降了¥\' + item.reduction_price + \'</div></div></li>\' 20 return html 21 } 22 23 function bindEvents() { 24 $(\'#\' + SELECTORS(\'pamb-messages\')).delegate(\'.\' + SELECTORS(\'pamb-message\') , \'click\', function() { 25 var itemId = $(this).attr(\'data-id\') 26 var url = \'http://ruyi.taobao.com/item/\' + encodeURIComponent(itemId) + \'?utm_medium=ext&utm_source=ruyi\' 27 openTab(url, true) 28 }) 29 30 $(\'#\' + SELECTORS(\'pamb-close\')).click(function() { 31 hide() 32 }) 33 } 34 35 function show() { 36 var $wrapper = $(\'#\' + SELECTORS(\'pamb-wrapper\')) 37 $wrapper.css(\'bottom\', 0) 38 } 39 40 function hide() { 41 var $wrapper = $(\'#\' + SELECTORS(\'pamb-wrapper\')) 42 var outerHeight = $wrapper.outerHeight() 43 $wrapper.css(\'bottom\', -outerHeight + \'px\') 44 } 45 46 function clearUnreadPriceMindMessages() { 47 chrome.runtime.sendMessage({ 48 topic: \'clear_unread_price_mind_messages\' 49 }) 50 } 51 52 function render(messages) { 53 if (messages && messages.length > 0) { 54 var templateInserted = $(document.body).attr(\'data-ruyitao-price-mind-inserted\') == 1 55 if (templateInserted) { 56 callback() 57 } else { 58 insertTemplate(callback) 59 } 60 } 61 62 function callback() { 63 var html = \'\' 64 var i = 0 65 var len = messages.length 66 len = len < 3 ? len : 3 67 for (; i < len; i++) { 68 html += getItemTemplate(messages[i]) 69 } 70 71 $(\'#\' + SELECTORS(\'pamb-messages\')).html(html) 72 !templateInserted && bindEvents() 73 show() 74 clearUnreadPriceMindMessages() 75 } 76 } 77 78 function replaceTemplateSelectors(html) { 79 return html.replace(/ruyitao-selector-prefix-([\w_-]+)/g, function() { 80 return transformSelector(arguments[1]); 81 }); 82 } 83 84 function getTemplate(pageName, callback) { 85 var self = this; 86 chrome.runtime.sendMessage({ 87 topic: "get_template", 88 page: pageName 89 }, function (res) { 90 var template = replaceTemplateSelectors(res.template); 91 sanitizeHTML(template, function(sanitizedTemplate) { 92 callback(sanitizedTemplate); 93 }) 94 }); 95 } 96 97 function sanitizeHTML (htmlString, callback) { 98 var rScript = /<script\b[\s\S]*?<\/script\s*>/g; 99 var rOnEvent = /\bon[A-z]+\s*=\s*[\'"]?[^>"]+[\'"]?/g; 100 var rHref = /href\s*=\s*[\'"]?\s*javascript:/g; 101 var result = htmlString.replace(rScript, \'\').replace(rOnEvent, \' \').replace(rHref, \' \'); 102 callback(result) 103 } 104 105 function openTab(url, select) { 106 select = select || false; 107 chrome.runtime.sendMessage({ 108 topic: \'tab_open\', 109 url: url, 110 selected: select 111 }); 112 } 113 114 var _selectors = {}; 115 var _selectors_seen = {}; 116 function generateRandomString() { 117 var rand_str = String.fromCharCode(Math.floor(Math.random() * 25 + 97)) + 118 Math.floor(Math.random() * 134217728).toString(36); 119 if ( typeof _selectors_seen[rand_str] != "undefined" ) { 120 return generateRandomString(); 121 } else { 122 _selectors_seen[rand_str] = true; 123 return rand_str; 124 } 125 } 126 127 function transformSelector(selector) { 128 // return \'ruyitao-\' + selector; 129 if ( typeof _selectors[selector] != "undefined" ) { 130 return _selectors[selector]; 131 } 132 // @if firefox 133 var prefix = \'ryt-\'; 134 // @else 135 var prefix = \'\'; 136 // @endif 137 return _selectors[selector] = prefix + generateRandomString(); 138 } 139 140 chrome.runtime.onMessage.addListener(function(req, sender) { 141 Uncaught TypeError: Cannot read property \'onMessage\' of undefined 142 switch (req.topic) { 143 case \'show_price_mind_messages\': 144 render(req.messages) 145 break; 146 } 147 }); 148 })(window);
近来做javascript开发,应该是做javascript平台维护,遇到很多莫名其妙的问题,脚本报错,刚开始以为是浏览器兼容性问题,后来试了很多方法,自身代码没问题,就是找不到原因,利用浏览器自带的调试工具,发现是软件在偷偷的干事情, 以上就是证据。
报错内容:Uncaught TypeError: Cannot read property \'onMessage\' of undefined
类似的还有金山毒霸在网页中内嵌脚本,嵌入脚本都没关系,你不要导致别人的应用程序报错啊。因为毒霸植入的脚本导致ie浏览器下有兼容性问题而报错,对于开发和客户来说根本不知道是什么原因报错啊。找到原因之后,我亲自联系过毒霸开发人员交流,最后毒霸开发人员更新他们的内库后解决问题。通过此事还认识了一位c++高手,可惜他不懂网页,好几次问我javascript方面的东西,瞬间变成x牛了。
以下是毒霸内嵌脚本,留个记号:
<script defer="" type="text/javascript">
function getOffsetLeft(o)
{
var left=0;
while (o!=null && o!=document.body)
{
left+=o.offsetLeft;
o=o.offsetParent;
}
return left;
}
function getOffsetTop(o)
{
var top=0;
while(o!=null && o!= document.body)
{
top+=o.offsetTop;
o=o.offsetParent;
}
return top;
}
function GetUrlFromPos(x, y, dep, doc)
{
var xVarTemp = 0;
var yVarTemp = 0;
if (!doc) doc = document;
if (!dep) dep = 1;
if (dep == 4)
{
return "";
}
var ele = doc.elementFromPoint(x, y);
if (ele)
{
if (ele.nodeName == "A")
{
return ele.href;
}
if (ele.nodeName == "AREA")
{
return ele.href;
}
if (ele.nodeName == "IFRAME" || ele.nodeName == "FRAME")
{
xVarTemp = x - getOffsetLeft(ele) + doc.body.scrollLeft + document.documentElement.scrollLeft;
yVarTemp = y - getOffsetTop(ele) + doc.body.scrollTop + document.documentElement.scrollTop;
if (x == xVarTemp && yVarTemp == y)
{
return "";
}
x = xVarTemp;
y = yVarTemp;
//alert(x + \' \' + getOffsetLeft(ele) + \' \' + doc.body.scrollLeft + document.documentElement.scrollLeft + \' \' + y + \' \' + getOffsetTop(ele) + \' \' + doc.body.scrollTop + document.documentElement.scrollTop)
return GetUrlFromPos(x, y, dep+1, ele.contentDocument || ele.contentWindow.document);
}
else
{
var p = ele.parentElement;
for (var i=0; i < 4; i++)
{
if (p && p.nodeName == "A")
{
return p.href;
}
if (p && p.nodeName == "AREA")
{
return p.href;
}
if ((p && p.parentElement))
{
p = p.parentElement;
}
else
{
break;
}
}
}
}
return "";
}
</script>