2012-11-02 5 views
5

Ich habe ein Javascript-Bookmarklet, das ich zusammenstelle, um eine mühsame Aufgabe ein wenig erträglicher zu machen. Im Wesentlichen durchlaufe ich hunderte von Seiten Trainingsmaterial und stelle sicher, dass alles von Helvetica zu Arial richtig ausgetauscht wurde. Der Bookmarklet-Code ist unten, aber eine kurze Aufschlüsselung ist, dass es einen MouseMove Event Listener und ein kleines, absolut positioniertes div erzeugt. Bei movemove-Ereignissen bewegt sich das div zur neuen Mausposition (um 10 px nach unten und rechts versetzt), ruft das Element unter der Maus mit elementFromPoint ab und zeigt die font-family -Eigenschaft für dieses Element an. oh und es ändert seine Hintergrundfarbe basierend darauf, ob Arial in der Eigenschaft erscheint.elementFromPoint gibt null zurück, nachdem die Seite gescrollt wurde

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); 
    } 
}; 

(für die Aufzeichnung, stahl ich den Stil aus einer Antwort hier auf SO Bestimmung Code, aber ich verlor die Registerkarte nicht lange nach Danke, anonymen Internet-Typ.!) diese Also alles funktioniert super - bis ich Versuchen Sie, den Mauszeiger über einen Teil der Seite zu bewegen, der von oben nach unten gescrollt wird. Das div sitzt an der Stelle, an der es wäre, wenn ich die Maus ganz unten auf dem Bildschirm hätte, während ich zum oberen Rand der Seite scrollte, und wenn ich weit genug nach unten scrolle, beginnt Firebug zu loggen, dass e.pageX nicht definiert ist.

Irgendwelche Ideen?

Antwort

6

Alrighty dann, es herausgefunden. Ich sah http://www.daniweb.com/web-development/javascript-dhtml-ajax/threads/276742/elementfrompoint-problems-when-window-has-been-scrolled- und dachte, es bedeutete, dass ich den Seitenversatz direkt von den e.pageX/Y-Werten abmildern musste, bevor ich es zur Berechnung der div-Position oder irgendetwas anderes verwendete, dies brach einfach alles für mich, also nahm ich an, dass es gewesen sein muss nicht verwandt - nicht so! Von dem, was ich jetzt verstehe, nimmt die Methode elementFromPoint einen Punkt relativ in der aktuellen Ansicht des Browsers, das heißt, auf der linken oberen Ecke von dem, was derzeit gesehen werden kann, nicht die Seite als Ganzes. Ich habe es behoben, indem ich den Offset von den X- und Y-Werten genommen habe, als ich das Element bekommen habe. Der jetzt funktionierende Code ist unten.

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, anstatt mit der Maus zu überprüfen, warum nicht einfach jeden Blattknoten überprüfen? Wenn ein Blattknoten eine Schriftartfamilie von Arial aufweist, sollte dies anzeigen, dass einer seiner Vorfahren eine Schriftartfamilie von Arial aufweist.

Zuerst müssen Sie jquery auf die Seite bekommen. Versuchen Sie, diese bookmarklet

Dann diesen Code ausführen:

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

Die arialNodes Variable sollte jeder Blattknoten enthalten, die eine Schriftfamilie von ‚Arial‘ hat. Sie können dann verwenden, um herauszufinden, welches Elternelement die Deklaration hat.

Oder wenn Sie nur sehen wollen, ob eine Seite konform ist oder nicht, überprüfen Sie einfach die Länge.

Aktualisiert

aktualisiert, um Kommentare unterhalb

(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, vielen Dank, dass du die Mühe in eine originelle und andere Lösung gebracht hast. Leider wird es in diesem Fall nicht für mich funktionieren. Ich hatte ursprünglich darüber nachgedacht, jeden Knoten zu durchlaufen, um dies zu überprüfen (nicht mit jQuery, da ich noch nicht wirklich viel darüber gelernt habe, aber hey), aber als ich mit der Programmierung anfing, erkannte ich, dass die Liste der Ausnahmen zu " Muss Arial sein "Regel würde dazu führen, dass jede Ausgabe, die ich davon bekam, fast nutzlos war, da ich immer noch durchgehen müsste, um herauszufinden, ob jeder Knoten eine Ausnahme ist oder nicht. Die Mausbewegung kann ich einfach über den Körper fegen. –

+1

Wenn Sie herausfinden möchten, welche Elemente die Regel "Muss Arial" verletzen, können Sie diese Liste von ArialNodes für gemeinsame Eltern filtern. Lass mich meine Antwort aktualisieren. –

+0

Ich versuche, die Elemente zu finden, die nicht arial sind, aber alle Menüs, die links und oben auf der Seite sitzen, sind Ausnahmen von der Regel - in Arial werden sie schwer zu lesen. Ebenso gibt es Orte, an denen ein Div in der Mitte des Inhalts steht und ein Zitat darstellt - das sind nicht Arial. Es gibt vielleicht 30 verschiedene Situationen, in denen etwas nicht Arial sein sollte, aber sie teilen keine einheitliche Klasse/ID, so dass es schwierig wäre, sie programmatisch zu bestimmen. Visuell ist es jedoch leicht zu erkennen, weshalb die Verwendung der Maus der beste Weg schien. –