Putting functionality back into <blockquote />

Discussion in 'HTML' started by Toby A Inkster, Feb 14, 2004.

  1. In "the other place" Jukka has pointed out that semantically <blockquote/>
    is useless in many browsers, so I'm experimenting with Javascript to put
    some functionality back into <blockquote/>.

    The basic idea is to use Javascript to pop up a small link to the
    blockquote's cite attribute on hover.

    You can see what I have so far here:

    http://www.goddamn.co.uk/tobyink/scratch/bq

    There are two things that still need fixing though, and that is where all
    you lovely people come in, as I sadly don't have the JS knowledge to fix
    it on my own.

    1. When the "cite" text is hovered over, the link goes invisible. The link
    still works, but this is certainly not desirable behaviour. I believe it
    has to do with event bubbling. Any ideas?

    2. I need a way to attach the bqHover and bqHoverOut functions to the
    blockquote without using the onmouseover and onmouseout HTML attributes so
    that all the JS can go in one external script file. I think
    addEventListener comes into play here, but I don't know very much about
    that and have never gotten such things to work in anything besides Gecko.
    Ideally I'd want a solution that works in IE6/Win, Gecko and Opera 7.
    Konqueror, Safari and IE5 for Windows and/or Mac would be a bonus. But
    I'll take what I can get.

    Thanks in advance for any light you can shed onto the matter.

    --
    Toby A Inkster BSc (Hons) ARCS
    Contact Me - http://www.goddamn.co.uk/tobyink/?page=132
     
    Toby A Inkster, Feb 14, 2004
    #1
    1. Advertising

  2. Toby A Inkster wrote:

    > In "the other place" Jukka has pointed out that semantically <blockquote/>
    > is useless in many browsers, so I'm experimenting with Javascript to put
    > some functionality back into <blockquote/>.


    I'm not well-versed in HTML subtleties, but according to the HTML
    reference, BLOCKQUOTE elements only offer a "cite" attribute, aside of
    the ones defined by the %attrs; entity. Since you're likely to want to
    precise source, date, author etc, ISTM that blockquote cannot be
    particularly enhanced, you'd indeed use a larger structure most of the
    time (for instance a DIV as a container and other tags for other
    information).

    The enhancement you want to set up is probably the only logical one
    (apart from working with extended DTD), although I think that having the
    link already existing as part of an additional tag would probably be
    safer (for instance you position your link relatively to the top-left
    blockquote point, but what if the quotation needs scrolling?).

    > 1. When the "cite" text is hovered over, the link goes invisible. The link
    > still works, but this is certainly not desirable behaviour. I believe it
    > has to do with event bubbling.


    That's correct, moving into an inner element fires the mouseout event of
    the outer element, then the event mouseover event is fired from the
    inner element and bubbles to the outer element; each time the
    appropriate handlers being triggered.

    You can manage this issue by studying the origin/direction of the event
    and taking adapted decision (or using mouseenter-mouseleave non-standard
    events).

    > 2. I need a way to attach the bqHover and bqHoverOut functions to the
    > blockquote without using the onmouseover and onmouseout HTML attributes so
    > that all the JS can go in one external script file. I think
    > addEventListener comes into play here,


    You can always define mouseover/mouseout handlers outside of the tag
    declaration, using a reference to the element, so that's not a problem.
    Alternatively, you could also set up some kind of mousemove conception,
    though this would be more complex to manage.

    "addEventListener" is a way to define a handler, it is useful when you
    want to set up many listeners to the object (and for the sort of script
    you want to design it would indeed make sense to use addEventListener
    and IE's attachEvent methods - I prefer using a specific function for
    that, though).

    Here's a simple example of what you're asking; tested IE6, Mozilla 1.5,
    Opera 7 - you might surprisingly experience flickering with IE if you
    include several block-level elements in the blockquote - I think that
    nothing can be done about that. All the script part can be safely
    inserted as a js include if needed.


    <script type="text/javascript">
    (function(){

    var CITE_VALUE="Jump!";
    var CITE_CLASS="jsCite";

    function _e(obj, evt, func) {
    if(obj[evt]) {
    obj[evt]=(function(originalHandler) {
    return function () {
    func.apply(obj, arguments);
    return originalHandler.apply(obj, arguments);
    }
    })(obj[evt]);
    } else
    obj[evt]=func;
    }

    function contains(container, containee) {
    if(container.contains) {
    return container.contains(containee);
    } else {
    while(containee && containee!=container)
    containee=containee.parentNode;
    return !!containee;
    }
    }

    function mover (evt) {
    evt=evt||window.event;
    var related=evt.fromElement||evt.relatedTarget;
    if(related) {
    if(!contains(this, related)) {
    Cite.define(this.citeObject, this);
    Cite.setVisible(true);
    }
    }
    }

    function mout(evt){
    evt=evt||window.event;
    var related=evt.toElement||evt.relatedTarget;
    if(related) {
    if(!contains(this, related)) {
    Cite.define(this.citeObject, this);
    Cite.setVisible(false);
    }
    }
    }

    var Cite = (function() {
    var $child, $parent;
    return {
    define:function(child, parent){
    if(!child) {
    var a, c, d=document;
    if((c=parent.getAttribute("cite"))!="") {
    a=d.createElement("a");
    a.href=c;
    a.appendChild(d.createTextNode(CITE_VALUE));
    parent.citeObject=d.createElement("span");
    parent.citeObject.className=CITE_CLASS;
    parent.citeObject.appendChild(a);
    child=parent.citeObject;
    }
    }
    $child=child;
    $parent=parent;
    },
    setVisible:function(bVisible){
    if($child && $parent)
    $parent[(bVisible?"append":"remove")+"Child"]($child);
    }
    }
    })();

    if(typeof Function!="undefined" &&
    Function.prototype &&
    Function.prototype.apply) {
    _e(window, "onload",
    function(evt){
    var d=document;
    if(d && d.body && d.createElement && d.body.appendChild &&
    typeof d.body.parentNode!="undefined" &&
    d.getElementsByTagName) {

    var bq=d.getElementsByTagName("blockquote");
    for(var ii=0; ii<bq.length; ii++) {
    _e(bq[ii], "onmouseover", mover);
    _e(bq[ii], "onmouseout", mout);
    }

    }
    }
    );
    }
    })();
    </script>

    <style type="text/css">
    blockquote {
    position: relative;
    margin-left:0; padding-left:4em;
    }
    blockquote .jsCite {
    font-size: 85%;
    position: absolute; top: 0; left: 0;
    padding: 1px;
    border: 1px dotted black;
    }
    </style>

    <blockquote cite="hello.html">
    <p>Hello</p>
    </blockquote>



    HTH
    Yep.
     
    Yann-Erwan Perio, Feb 14, 2004
    #2
    1. Advertising

  3. "Yann-Erwan Perio" <> wrote in message
    news:402e9700$0$28743$...
    <snip>
    > function contains(container, containee) {
    > if(container.contains) {
    > return container.contains(containee);
    > } else {
    > while(containee && containee!=container)
    > containee=containee.parentNode;
    > return !!containee;
    > }
    > }


    Knowing your interest in such things, you might like to know that I
    recently did a speed test of:-

    var boolValue = !!x;

    - against -

    var boolValue = Boolean(x);

    - (both executed in the context of a global function) and
    type-converting to boolean by calling the Boolean constructor as a
    function outperformed the double NOT operation by about a factor of 4
    (with the usual browser variations). Unfortunately they are not directly
    comparable operations, as the scope resolution of - Boolean - as an
    identifier would influence the results. With a long scope chain the
    extra work in the resolution of the identifier might swing the
    performance of the forced type-conversion back in favour of double NOT.

    <snip>
    > if(typeof Function!="undefined" &&
    > Function.prototype &&
    > Function.prototype.apply) {
    > _e(window, "onload",
    > function(evt){
    > var d=document;
    > if(d && d.body && d.createElement && d.body.appendChild &&
    > typeof d.body.parentNode!="undefined" &&
    > d.getElementsByTagName) {

    <snip>

    I was a little surprised not to see an explicit test for
    d.body.removeChild among those. ;-)

    Richard.
     
    Richard Cornford, Feb 16, 2004
    #3
  4. Richard Cornford wrote:


    > Knowing your interest in such things,


    Indeed:)

    > you might like to know that I
    > recently did a speed test of:-
    >
    > var boolValue = !!x;
    >
    > - against -
    >
    > var boolValue = Boolean(x);
    >
    > - (both executed in the context of a global function) and
    > type-converting to boolean by calling the Boolean constructor as a
    > function outperformed the double NOT operation by about a factor of 4
    > (with the usual browser variations).


    I believe that according to Ecma, this would make sense, although the
    implementation of Boolean isn't described (it is just said it should
    call toBoolean).

    Ah! but now I'm quite confused with the following simple test case here,
    which gives opposite results on my WinXP/PIII450:

    IE6 Mozilla1.5 Opera7.23
    Using Boolean 3265 650 1372
    using !! 2584 271 1062



    <textarea id="results" rows="10" cols="60"></textarea>
    <script type="text/javascript">
    function test(){
    var d1, d2, d3, b;

    d1=new Date();
    for(var ii=0; ii<100000; ii++)
    b=Boolean(document);
    d2=new Date();
    for(var k=0; k<100000; k++)
    b=!!document;
    d3=new Date();

    document.getElementById("results").value+=
    "Boolean:"+(d2-d1)+" !!:"+(d3-d2)+"\n";
    }

    test();
    </script>


    What do I miss?

    >> if(d && d.body && d.createElement && d.body.appendChild &&
    >> typeof d.body.parentNode!="undefined" &&
    >> d.getElementsByTagName) {


    > I was a little surprised not to see an explicit test for
    > d.body.removeChild among those. ;-)


    Argh! You're right of course, this test is absolutely required here - it
    seems I tend to be dreaming too much when finishing writing scripts:)


    Cheers,
    Yep.
     
    Yann-Erwan Perio, Feb 16, 2004
    #4
  5. "Yann-Erwan Perio" <> wrote in message
    news:403125ce$0$22520$...
    <snip>
    >Ah! but now I'm quite confused with the following simple test
    >case here, which gives opposite results on my WinXP/PIII450:
    >
    >IE6 Mozilla1.5 Opera7.23
    >Using Boolean 3265 650 1372
    >using !! 2584 271 1062

    <snip>
    > What do I miss?


    Probably a mistake in my test script. I cannot find it now, which is odd
    because I keep all my seed test scripts together (I also cannot find a
    similar test comparing concatenation with the String constructor when
    forcing type-conversion to a string). But I recreated the script and got
    opposite results, specifically double NOT outperformed the Boolean
    constructor (by a factor of 10 this time). Sorry for being misleading.
    <snip>

    Richard.
     
    Richard Cornford, Feb 17, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. GaryB
    Replies:
    6
    Views:
    347
    Steven Cheng[MSFT]
    Nov 15, 2004
  2. Saurabh
    Replies:
    6
    Views:
    4,542
    Chris Smith
    May 30, 2004
  3. GaryB

    Putting ASPX functionality into a component

    GaryB, Nov 12, 2004, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    104
    GaryB
    Nov 12, 2004
  4. CBlair1986
    Replies:
    4
    Views:
    136
    CBlair1986
    Nov 18, 2006
  5. Toby A Inkster

    Putting functionality back into <blockquote />

    Toby A Inkster, Feb 14, 2004, in forum: Javascript
    Replies:
    4
    Views:
    99
    Richard Cornford
    Feb 17, 2004
Loading...

Share This Page