2012-11-02 11 views
5

Ho un bookmarklet javascript che ho messo insieme per rendere un compito arduo un po 'più sopportabile. Essenzialmente sto esaminando centinaia di pagine di materiale di formazione e mi assicuro che tutto sia stato correttamente scambiato da Helvetica ad Arial. Il codice bookmarklet è sotto, ma una rapida ripartizione è che crea un listener di eventi in mousemove e un div piccolo, posizionato in modo assoluto. Su eventi mousemove, il div si sposta sulla nuova posizione del mouse (spostata di 10px verso il basso e verso destra), ottiene l'elemento sotto il mouse con elementFromPoint e mostra la proprietà family-font per quell'elemento. oh e cambia il suo colore di sfondo in base al fatto che Arial appaia all'interno della proprietà.elementFromPoint restituisce null dopo aver scrollato la pagina

var bodyEl=document.getElementsByTagName("body")[0]; 
var displayDiv=document.createElement("div"); 
displayDiv.style.position="absolute"; 
displayDiv.style.top="0px"; 
displayDiv.style.top="0px"; 
bodyEl.appendChild(displayDiv); 


function getStyle(el,styleProp) { 
    var camelize = function (str) { 
    return str.replace(/\-(\w)/g, function(str, letter){ 
     return letter.toUpperCase(); 
    }); 
    }; 

    if (el.currentStyle) { 
    return el.currentStyle[camelize(styleProp)]; 
    } else if (document.defaultView && document.defaultView.getComputedStyle) { 
    return document.defaultView.getComputedStyle(el,null) 
           .getPropertyValue(styleProp); 
    } else { 
    return el.style[camelize(styleProp)]; 
    } 
} 
function getTheElement(x,y) {return document.elementFromPoint(x,y);} 

fn_displayFont=function displayFont(e) { 
    e = e || window.event; 
    var divX=e.pageX+10; 
    var divY=e.pageY+10; 
    var font=getStyle(getTheElement(e.pageX,e.pageY),"font-family"); 
    if (font.toLowerCase().indexOf("arial") != -1) { 
     displayDiv.style.backgroundColor = "green"; 
    } else { 
     displayDiv.style.backgroundColor = "red"; 
    } 
    displayDiv.style.top= divY.toString() + "px"; 
    displayDiv.style.left= divX.toString() + "px"; 
    displayDiv.style.fontFamily=font; 
    displayDiv.innerHTML=font; 
} 

window.addEventListener('mousemove', fn_displayFont); 
document.onkeydown = function(evt) { 
    evt = evt || window.event; 
    if (evt.keyCode == 27) { 
     window.removeEventListener('mousemove', fn_displayFont); 
     bodyEl.removeChild(displayDiv); 
    } 
}; 

(per la cronaca, mi ha donato lo stile di determinare il codice da una risposta qui su SO, ma ho perso la scheda non molto tempo dopo, grazie, ragazzo internet anonimo.!) Quindi questo tutte le grandi opere - FINO I prova a passare con il mouse su una parte della pagina che scorre verso il basso dall'alto. Il div si siede dove sarebbe se avessi il mouse nella parte inferiore dello schermo mentre si scorre verso la parte superiore della pagina, e se si scorre verso il basso abbastanza firebug inizia a registrare che e.pageX non è definito.

Qualche idea?

risposta

6

Alrighty allora, capito. Ho visto http://www.daniweb.com/web-development/javascript-dhtml-ajax/threads/276742/elementfrompoint-problems-when-window-has-been-scrolled- e ho pensato che avrei dovuto togliere il pageoffset subito dai valori e.pageX/Y, prima che lo usassi per calcolare la posizione div o qualsiasi altra cosa, questo ha rotto tutto per me quindi ho pensato che fosse stato non correlato - non è così! Da quello che ora capisco il metodo elementFromPoint prende un punto relativo nella vista corrente del browser, vale a dire, si basa sull'angolo in alto a sinistra di ciò che può essere visto attualmente, non sulla pagina nel suo complesso. L'ho risolto prendendo l'offset dai valori X e Y quando stavo ottenendo l'elemento. Il codice ora funzionante è sotto.

var bodyEl=document.getElementsByTagName("body")[0]; 
var displayDiv=document.createElement("div"); 
displayDiv.style.position="absolute"; 
displayDiv.style.top="0px"; 
displayDiv.style.top="0px"; 
bodyEl.appendChild(displayDiv); 


function getStyle(el,styleProp) { 
    var camelize = function (str) { 
    return str.replace(/\-(\w)/g, function(str, letter){ 
     return letter.toUpperCase(); 
    }); 
    }; 

    if (el.currentStyle) { 
    return el.currentStyle[camelize(styleProp)]; 
    } else if (document.defaultView && document.defaultView.getComputedStyle) { 
    return document.defaultView.getComputedStyle(el,null) 
           .getPropertyValue(styleProp); 
    } else { 
    return el.style[camelize(styleProp)]; 
    } 
} 
function getTheElement(x,y) {return document.elementFromPoint(x,y);} 

fn_displayFont=function displayFont(e) { 
    e = e || window.event; 
    var divX=e.pageX + 10; 
    var divY=e.pageY + 10; 
    var font=getStyle(getTheElement(e.pageX - window.pageXOffset,e.pageY - window.pageYOffset),"font-family"); 
    if (font.toLowerCase().indexOf("arial") != -1) { 
     displayDiv.style.backgroundColor = "green"; 
    } else { 
     displayDiv.style.backgroundColor = "red"; 
    } 
    displayDiv.style.top= divY.toString() + "px"; 
    displayDiv.style.left= divX.toString() + "px"; 
    displayDiv.style.fontFamily=font; 
    displayDiv.innerHTML=font; 
} 

document.addEventListener('mousemove', fn_displayFont); 
document.onkeydown = function(evt) { 
    evt = evt || window.event; 
    if (evt.keyCode == 27) { 
     window.removeEventListener('mousemove', fn_displayFont); 
     bodyEl.removeChild(displayDiv); 
    } 
}; 
0

Hmm invece di controllare con il mouse, perché non controllare solo ogni nodo foglia? Se un nodo foglia ha una famiglia di caratteri arial, allora dovrebbe indicare che uno dei suoi antenati ha una famiglia di caratteri di Arial.

Per prima cosa devi inserire jquery nella pagina. Prova questa bookmarklet

Poi eseguire questo codice:

(function(){ 
    var arialNodes = $('div:not(:has(*))').filter(function(){ 
     return $(this).css('font-family').toLowerCase().indexOf("arial") != -1; 
    }); 
})(); 

La variabile arialNodes dovrebbe contenere ogni nodo foglia che ha un font-family di 'Arial'. Puoi quindi usarlo per capire quale elemento genitore ha la dichiarazione.

Oppure, se vuoi solo vedere se una pagina è conforme o meno, basta controllare la lunghezza.

Updated

aggiornati per riflettere commenti qui sotto

(function() { 
    var arialNodes = $('*:not(:has(*))', $('body')).filter(function() { 
     return $(this).css('font-family').toLowerCase().indexOf("arial") === -1; 
    }); 

    var offendingParents = []; 
    arialNodes.each(function(){ 
     var highestOffendingParent = $(this).parentsUntil('body').filter(function(){ 
      return $(this).css('font-family').toLowerCase().indexOf("arial") === -1; 
     }).last(); 
     if(offendingParents.indexOf(highestOffendingParent) === -1){ 
      offendingParents.push(highestOffendingParent); 
     } 
    }); 

})(); 
+0

Hey Clark, grazie mille per aver dedicato uno sforzo in una soluzione originale e diversa. Sfortunatamente in questo caso non funzionerà per me. Inizialmente avevo pensato di eseguire il looping di ognuno dei nodi per verificarlo (non con jQuery poiché è qualcosa che non ho ancora imparato molto, ma hey), ma quando ho iniziato a codificarlo ho capito che l'elenco delle eccezioni al " Deve essere Arial "la regola stava per rendere quasi inutile qualsiasi output che ne ricavavo, poiché dovrei ancora passare e capire se ogni nodo è un'eccezione o meno. Il modo in cui mousemove lo posso semplicemente spazzare via dal corpo. –

+1

Se si sta tentando di individuare quali elementi causano la violazione della regola "Deve essere Arial", è possibile filtrare tale elenco di arialNodes per i genitori comuni. Permettimi di aggiornare la mia risposta. –

+0

Sto cercando di trovare gli elementi che non sono arial, ma, tutti i menu che si trovano a sinistra e in cima alla pagina sono eccezioni alla regola - in Arial, diventano difficili da leggere. Allo stesso modo ci sono posti in cui un div è nel mezzo del contenuto e rappresenta una citazione - questi non sono Arial. Ci sono forse 30 diverse circostanze in cui qualcosa non dovrebbe essere Arial, ma non condividono classi/ID uniformi, quindi sarebbe difficile determinarli in modo programmatico. Visivamente, però, è facile da dire, ed è per questo che usare il mouse è sembrato il modo migliore qui. –