20

ページ上のすべてのリンクを変更して、クリックしたときに追加の作業を実行しようとしています。

些細なアプローチは次のようなものかもしれません:

function adaptLinks()
{
    var links = document.getElementsByTagName('a');
    for(i = 0; i != links.length; i++)
    {
        links[i].onclick = function (e)
        {
            <do some work>
            return true;
        }
    }
}

ただし、一部のリンクには、保持する必要があるonClickハンドラーが既に含まれています。私は次のことを試しました:

function adaptLinks()
{
    var links = document.getElementsByTagName('a');
    for(i = 0; i != links.length; i++)
    {
        var oldOnClick = links[i].onclick;
        links[i].onclick = function (e)
        {
            if(oldOnClick != null && !oldOnClick())
            {
                return false;
            }
            <do some work>
            return true;
        }
    }
}

しかし、 oldOnClickはハンドラーが呼び出されたときにのみ評価されるため、これは機能しません(この時点で最後のリンクの値が含まれています)。

4

7 に答える 7

18

onclick各リンクの元の値を保持するには、クロージャーを作成する必要があります。

<a href="#" onclick="alert('hi');return false;">Hi</a>
<a href="#" onclick="alert('there');return true;">There</a>
<script type="text/javascript">
function adaptLinks() {
    var links = document.getElementsByTagName('a');
    for (i = 0; i != links.length; i++) {
        links[i].onclick = (function () {
            var origOnClick = links[i].onclick;
            return function (e) {
                if (origOnClick != null && !origOnClick()) {
                    return false;
                }
                // do new onclick handling only if
                // original onclick returns true
                alert('some work');
                return true;
            }
        })();
    }
}
adaptLinks();
</script>

この実装は、元の onclick ハンドラーが true を返す場合にのみ、新しい onclick 処理を実行することに注意してください。それが必要な場合は問題ありませんが、元のハンドラーが false を返した場合でも、新しい onclick 処理を実行する場合は、コードを少し変更する必要があることに注意してください。

comp.lang.javascript FAQおよびDouglas Crockfordからのクロージャの詳細。

于 2009-05-21T16:39:32.777 に答える
0

この関数は使用可能である必要があります(イベントリスナーがアプローチします)。

function addEventListener(element, eventType, eventHandler, useCapture) {
    if (element.addEventListener) {
        element.addEventListener(eventType, eventHandler, useCapture);
        return true;
    } else if (element.attachEvent) {
        return element.attachEvent('on' + eventType, eventHandler);
    }
    element['on' + eventType] = eventHandler;
}

または、この関数を追加するコードをさらに保存できます(同じイベントリスナーを多くの要素に追加する必要がある場合)。

function addClickListener(element) {
    addEventListener(element, 'click', clickHandler, false);
}
于 2009-08-06T19:27:46.627 に答える
0

JQuery を使用すると、次のコードが機能します。

function adaptLinks(table, sortableTable)
{
    $('a[href]').click(function (e)
    {
        if(!e.isDefaultPrevented())
        {
            <do some work>
        }
    });
}

これには追加のライブラリを使用する必要がありますが、 addEventListener/attachEvent に存在するいくつかの問題を回避します (この参照に関する後者の問題など)。

落とし穴が 1 つだけあります。元のonClickハンドラが「通常の」JavaScript を使用して割り当てられている場合、次の行

...
if(!e.isDefaultPrevented())
...

元のハンドラーが false を返してイベントをキャンセルした場合でも、常にtrueに解決されます。これを修正するには、元のハンドラーでも JQuery を使用する必要があります。

于 2009-05-21T11:14:52.213 に答える