2013-04-20 74 views
2

我試圖從Greasemonkey腳本使用jQuery Waypoint插件,並且似乎無法使基本測試工作。有誰知道一個原因Waypoint不會從用戶腳本工作?從Greasemonkey jQuery Waypoint

@require線:

// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js 
// @require  http://cdn.jsdelivr.net/jquery.waypoints/2.0.2/waypoints.min.js 

腳本:

$('div.container').waypoint(function(){ 
    alert('you hit bottom'); 
},{ offset: 'bottom-in-view' }); 

有趣的是,如果這與 「容器」 類存在的div腳本休息,而這個聲明之外的代碼將無法運行。如果我改變選擇器來找到一些不存在的元素,腳本的其餘部分運行良好。

有沒有人有任何想法這裏發生了什麼?我把頭撞在牆上。謝謝!

PS。我也嘗試將Waypoints插件代碼直接粘貼到腳本中(而不是使用CDN),並獲得相同的結果。

回答

2

不幸的是,該擴展沒有像許多其他jQuery擴展那麼好寫。它使用thisjQuery,讓我們說,「不幸」的方式。這意味着即使設置了@grant none,它也會從用戶腳本範圍中崩潰。

對於庫,這樣,你的選擇是:

  • 找到一個更好的庫(推薦)。

  • 找到一個更好的方法來自己編碼,如果它不太涉及。

  • 如果頁面沒有使用jQuery,或者使用兼容版本的jQuery,那麼您可以通過腳本注入來使用此類擴展。見下文。

  • 如果頁面使用的是不兼容的jQuery版本,那麼在沒有中斷頁面的情況下,您可能無法做任何事情。 有時解決方法是可能的,但這是另一個問題。


情況下的頁面已經用了jQuery的兼容版本:

你只需要注入航點,並使用航點的任何代碼。請勿使用@require
像這樣:

// ==UserScript== 
// @name  _YOUR_SCRIPT_NAME 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @grant  GM_addStyle 
// ==/UserScript== 
/*- The @grant directive is needed to work around a design change 
    introduced in GM 1.0. It restores the sandbox. 
*/ 

function GM_main() { 
    $('div.container').waypoint(function(){ 
     alert('you hit bottom'); 
    },{ offset: 'bottom-in-view' }); 
} 

addJS_Node (
    null, 
    "http://cdn.jsdelivr.net/jquery.waypoints/2.0.2/waypoints.min.js", 
    null, 
    function() {addJS_Node (null, null, GM_main); } 
); 

//-- This is a standard-ish utility function. 
function addJS_Node (text, s_URL, funcToRun, runOnLoad) { 
    var D         = document; 
    var scriptNode       = D.createElement ('script'); 
    if (runOnLoad) { 
     scriptNode.addEventListener ("load", runOnLoad, false); 
    } 
    scriptNode.type       = "text/javascript"; 
    if (text)  scriptNode.textContent = text; 
    if (s_URL)  scriptNode.src   = s_URL; 
    if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()'; 

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; 
    targ.appendChild (scriptNode); 
} 

情況下的頁面不使用jQuery都:

你需要注入的jQuery,然後連鎖航點的注射以及使用航點的任何代碼。請勿使用@require
像這樣:

// ==UserScript== 
// @name  _YOUR_SCRIPT_NAME 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @grant  GM_addStyle 
// ==/UserScript== 
/*- The @grant directive is needed to work around a design change 
    introduced in GM 1.0. It restores the sandbox. 
*/ 

function GM_main() { 
    $('div.container').waypoint(function(){ 
     alert('you hit bottom'); 
    },{ offset: 'bottom-in-view' }); 
} 

//-- Add jQuery. 
addJS_Node (
    null, 
    "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js", 
    null, 
    addWaypointsAndFireMain 
); 

function addWaypointsAndFireMain() { 
    addJS_Node (
     null, 
     "http://cdn.jsdelivr.net/jquery.waypoints/2.0.2/waypoints.min.js", 
     null, 
     function() {addJS_Node (null, null, GM_main); } 
    ); 
} 

//-- This is a standard-ish utility function. 
function addJS_Node (text, s_URL, funcToRun, runOnLoad) { 
    var D         = document; 
    var scriptNode       = D.createElement ('script'); 
    if (runOnLoad) { 
     scriptNode.addEventListener ("load", runOnLoad, false); 
    } 
    scriptNode.type       = "text/javascript"; 
    if (text)  scriptNode.textContent = text; 
    if (s_URL)  scriptNode.src   = s_URL; 
    if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()'; 

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; 
    targ.appendChild (scriptNode); 
} 


不幸的是,當你有注入腳本代碼,它變得更加混亂使用GM_功能。如果這適用於您,請參閱:"How to call Greasemonkey's GM_ functions from code that must run in the target page scope?"

+0

感謝您的全面解釋!不幸的是,我確實需要提供一個jQuery庫並在這種情況下使用GM_函數,所以我可能會自己編寫一些代碼,而不是嘗試對Waypoint進行修改(所以我沒有測試過這些代碼片斷,儘管它們非常讚賞),但至少現在我知道我並不瘋狂。再次感謝:) – equazcion 2013-04-20 08:26:48

+0

沒問題,我在發佈它們之前測試了這些*完整的工作腳本*(僅更改'@ include')。對不起Waypoints沒有爲你工作。祝你好運! – 2013-04-20 09:01:23

+0

更新:似乎'.scroll'事件在用戶腳本範圍內完全不可用。我確定,在我試過的所有庫和自定義代碼失敗後 - 這促使我簡單地測試jQuery'.scroll'事件,並且也失敗了。最後的工作是'unsafeWindow.onscroll'事件。例如:'unsafeWindow.onscroll = function(){alert('你滾動')};'我猜測Greasemonkey的安全包裝會導致腳本認爲沒有實際移動。 – equazcion 2013-04-20 10:52:39