JavaScriptで長押ししますか?


117

JavaScript(またはjQuery)で「長押し」を実装することは可能ですか?どうやって?

代替テキスト
(ソース:androinica.com

HTML

<a href="" title="">Long press</a>

JavaScript

$("a").mouseup(function(){
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  return false; 
});

7
私はおそらく、コードをベースとして使用してカスタムjQueryイベントを作成するので、あなたはそれを行うことができますjQuery(...).longclick(function() { ... });
Matti Virkkunen

1
質問はjQueryでタグ付けされていませんが、タグ付けされています。この質問では、最初に、私が好む純粋なJavascriptソリューション、またはオプションで(括弧内に)jQueryソリューションを求めます。ほとんどの回答は、標準の想定としてデフォルトでjQueryになっているようです。私は常にjQueryを軽んじており、一度もそれを使用したことはなく、また、それに対する強制的な必要性も感じていません。一部の人はそれを自分自身で使用することを楽しんでいます。どちらの手法を使用しても、何の問題もありません。しかし、質問はjQueryソリューションを受け入れるため、jQueryタグはより多くの注目を集め、うまくいけばより良い答えを得る可能性があります。ここでのjQueryの回答はあまりよくありません。

回答:


159

「jQuery」の魔法はなく、JavaScriptタイマーのみです。

var pressTimer;

$("a").mouseup(function(){
  clearTimeout(pressTimer);
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  pressTimer = window.setTimeout(function() { ... Your Code ...},1000);
  return false; 
});

39
ドラッグでこの火災も発生しませんか?
ガラル

11
おそらく呼び出すことによって、それに見てかなり簡単だろう@Gallal clearTimeout(pressTimer)mousemove、私は何かが欠けていない限り、。確かにこれは前例のないことではないでしょう。
David John Welsh

5
@DavidJohnWelsh私が見ているだけで、マウスを動かしたくないだけです-指をしっかりと動かさずに1px動かさないのはかなり難しいです!しきい値を適用する必要があります(マウスが10px移動していない場合)など。かなり複雑になります。
イアン・

6
これが電話で機能することを期待している場合、それらは多くの場合、独自のデフォルトの長押し動作を持っています(たとえば、Androidのクロムは、リンクを長押しするとさまざまなオプションのあるモーダルメニューを表示します)。私はこれを防ぐために多くの幸運がありませんでした、そしてブラウザーのデフォルトの動作を正直に妨害することはとにかく何にも隠されません。
dartacus 2016年

4
これは選択された回答ですが、実際には質問への回答ではありません。それは過度に単純で素朴です。長押しイベントは、この回答が無視する複数の問題に対処する必要があります。1)長押しをドラッグとジェスチャーからマルチタッチからの区別(つまり、ピンチズームインまたはズームアウト)2)要素またはブラウザー領域の外に移動した場合はキャンセル3)多数のプラットフォームとデバイスでのテキスト選択のデフォルトの動作に対処4)許可マジックナンバーに依存せず、感度の設定可能なしきい値。アクセシビリティの問題に特に役立ちますが、これに限定されません。

34

Maycow Mouraの答えに基づいて、私はこれを書きました。また、ユーザーが右クリックを行わなかったことも保証されます。これにより、長押しがトリガーされ、モバイルデバイスで機能します。デモ

var node = document.getElementsByTagName("p")[0];
var longpress = false;
var presstimer = null;
var longtarget = null;

var cancel = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }

    this.classList.remove("longpress");
};

var click = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }

    this.classList.remove("longpress");

    if (longpress) {
        return false;
    }

    alert("press");
};

var start = function(e) {
    console.log(e);

    if (e.type === "click" && e.button !== 0) {
        return;
    }

    longpress = false;

    this.classList.add("longpress");

    if (presstimer === null) {
        presstimer = setTimeout(function() {
            alert("long click");
            longpress = true;
        }, 1000);
    }

    return false;
};

node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);

また、CSSアニメーションを使用していくつかのインジケーターを含める必要があります。

p {
    background: red;
    padding: 100px;
}

.longpress {
    -webkit-animation: 1s longpress;
            animation: 1s longpress;
}

@-webkit-keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}

@keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}

ボタンをjsfiddle押されている間、常に何かを行うために、この変更バージョンを作成しましたが、Androidでは何らかの理由で、+ボタンのタッチを停止した後でも実行されます...
Xander

@Xander:おそらく:hoverタッチデバイスでの状態がベタベタしているからかもしれませんが、それはここでも当てはまります。
kelunik 2015

おっと、長押しをサポートするモバイルサイトで-/ +数値インクリメントボタンを動作させる方法はあるのでしょうか。私が見つけるすべての方法は、繰り返しクリックする必要があることだけをサポートしています。ありがとう!
Xander

@Xander:実際には、touchendIMOを起動する必要があります。タッチデバイス用の特別なコードの場合、スティッキーにする必要はありません。おそらく、明日何かを試すつもりです。
kelunik

1
Androidで問題を解決しました。を押すと、マウスダウンとタッチスタートの両方が起動するので、2つのタイマーが実行されていましたが、指を離しても1つしかキャンセルされませんでした。タイマーがまだアクティブになっていないことを確認するために、プレスタイマーをif(presstimer === null)でラップしました。
Xander


16

これを解決するために長押しイベント (0.5kの純粋なJavaScript)を作成しましたlong-press。これにより、DOMにイベントが追加されます。

任意の要素でa long-pressをリッスンします。

// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
  console.log(e.target);
});

以下のために聞くlong-press特定の要素:

// get the element
var el = document.getElementById('idOfElement');

// add a long-press event listener
el.addEventListener('long-press', function(e) {

    // stop the event from bubbling up
    e.preventDefault()

    console.log(e.target);
});

IE9 +、Chrome、Firefox、Safari、ハイブリッドモバイルアプリ(iOS / AndroidのCordovaおよびIonic)で動作します

デモ


2
すごい、仲間!
ジェフT.

1
このソリューションモンキーは、window.CustomEventオブジェクトに、いくぶん不規則で不完全な非標準的な方法でパッチを適用します。読み取り専用プロパティを読み取り専用として適切に作成するのではなく、読み取り/書き込みを作成します。具体的には、returnValue、type、timeStamp、isTrustedが欠落しています。ドラッグ、ジェスチャー、ピンチズームインまたはズームアウト、または長押しによるマルチタッチのミスファイアについては対処していません。また、500ミリ秒でも長押ししてテキスト選択にデフォルト設定する多数のデバイスやプラットフォームの問題については対処していません。ライブラリには、これらの条件のテストケースがありません。

4
それはオープンソースです。プロジェクトに貢献してください:)
John Doherty

@JohnDoherty素晴らしい!しかし、同じ要素で「onClick」を使用できますか?
Devashish

2
「長押し遅延」タイマーが作動する前に長押しがリリースされる限り、「onclick」イベントを引き続き取得する必要があります
John Doherty

15

タイムアウトといくつかのマウスイベントハンドラーを使用して独自に実装するのに十分簡単に​​見えますが、同じ要素でプレスと長押しの両方をサポートするクリックアンドドラッグリリースのような場合を考えると、少し複雑になります。 、iPadのようなタッチデバイスでの作業。私はlongclick jQueryプラグインGithub)を使用することになりました。携帯電話などのタッチスクリーンデバイスのみをサポートする必要がある場合は、jQuery Mobileのタップホールドイベントも試してみてください。


Githubリンクは機能しますが、プロジェクトは2010年以降更新されておらず、現在のjqueryバージョンでは機能しません。ただし、ソースコードでhandle.applyをdispatch.applyに置き換えると修正されます。
arlomedia 2016年

11

jQueryプラグイン。置くだけ$(expression).longClick(function() { <your code here> });。2番目のパラメーターはホールド期間です。デフォルトのタイムアウトは500ミリ秒です。

(function($) {
    $.fn.longClick = function(callback, timeout) {
        var timer;
        timeout = timeout || 500;
        $(this).mousedown(function() {
            timer = setTimeout(function() { callback(); }, timeout);
            return false;
        });
        $(document).mouseup(function() {
            clearTimeout(timer);
            return false;
        });
    };

})(jQuery);

これは通話中に保持されません。
Champ

こんにちはブロ我々は基幹イベントとしてそれを使用することができます
user2075328

6

クロスプラットフォームの開発者向け(これまでの回答はすべてiOSでは機能しません)

マウスアップ/ダウンは、Androidでは問題なく動作するようですが、すべてのデバイス(samsung tab4)ではありません。iOSではまったく機能しませんでした。

さらなる研究は、これは要素が選択を持っているためであり、ネイティブの倍率がリスナーを邪魔するためであるようです。

このイベントリスナーを使用すると、ユーザーが画像を500ミリ秒間保持した場合に、サムネイル画像をブートストラップモーダルで開くことができます。

レスポンシブ画像クラスを使用するため、画像のより大きなバージョンが表示されます。このコードは完全にテストされています(iPad / Tab4 / TabA / Galaxy4):

var pressTimer;  
$(".thumbnail").on('touchend', function (e) {
   clearTimeout(pressTimer);
}).on('touchstart', function (e) {
   var target = $(e.currentTarget);
   var imagePath = target.find('img').attr('src');
   var title = target.find('.myCaption:visible').first().text();
   $('#dds-modal-title').text(title);
   $('#dds-modal-img').attr('src', imagePath);
   // Set timeout
   pressTimer = window.setTimeout(function () {
      $('#dds-modal').modal('show');
   }, 500)
});

iOS向けの優れたソリューション
eric xu

サムネイルで始まるタッチをどのように防ぐことができますか?言い換えれば、タッチスタート/インプレースの終了ではなく、ハンドラーを備えた要素で開始されたが、最終的にはスクロールになるタッチ
Akin Hwan

5
$(document).ready(function () {
    var longpress = false;

    $("button").on('click', function () {
        (longpress) ? alert("Long Press") : alert("Short Press");
    });

    var startTime, endTime;
    $("button").on('mousedown', function () {
        startTime = new Date().getTime();
    });

    $("button").on('mouseup', function () {
        endTime = new Date().getTime();
        longpress = (endTime - startTime < 500) ? false : true;
    });
});

デモ


2
このコードは、500msの最後にlongclickが発生しないことを示しています。ユーザーはマウスをクリックして死ぬことができます:)。長いクリックは、ユーザーがボタンをクリックするのをやめた場合にのみ発生します。
jedi

これは、ユーザーが同じ場所で長押しを終了する代わりにスクロールを開始した場合をカバーしますか?
Akin Hwan

@AkinHwanいいえ、同じ要素上でマウスクリックがリリースされた場合にのみトリガーされます。
ラズ

4

Diodeusの答えは素晴らしいですが、onClick関数を追加することはできません。onclickを配置した場合、ホールド関数は実行されません。そしてRazzakの答えはほぼ完璧ですが、それはマウスアップでのみホールド機能を実行し、通常、ユーザーがホールドし続けても機能は実行されます。

だから、私は両方に参加し、これを作りました:

$(element).on('click', function () {
    if(longpress) { // if detect hold, stop onclick function
        return false;
    };
});

$(element).on('mousedown', function () {
    longpress = false; //longpress is false initially
    pressTimer = window.setTimeout(function(){
    // your code here

    longpress = true; //if run hold function, longpress is true
    },1000)
});

$(element).on('mouseup', function () {
    clearTimeout(pressTimer); //clear time on mouseup
});

ユーザーがマウスダウン後にスクロールを開始し、長押しをするつもりがなかった場合
Akin Hwan


2

マウスダウンでその要素のタイムアウトを設定し、マウスアップでそれをクリアできます:

$("a").mousedown(function() {
    // set timeout for this element
    var timeout = window.setTimeout(function() { /* … */ }, 1234);
    $(this).mouseup(function() {
        // clear timeout for this element
        window.clearTimeout(timeout);
        // reset mouse up event handler
        $(this).unbind("mouseup");
        return false;
    });
    return false;
});

これにより、各要素は独自のタイムアウトを取得します。


1
$(this).mouseup(function(){});イベントハンドラーは削除されません。別のハンドラーが追加されます。.unbind代わりに使用してください。
Matti Virkkunen、2010

off()バインドを解除する代わりに今すぐ使用する必要があります。
dbinott 2016年

1

jquery-mobileのタップホールドを使用できます。jquery-mobile.jsを含めると、次のコードが正常に機能します

$(document).on("pagecreate","#pagename",function(){
  $("p").on("taphold",function(){
   $(this).hide(); //your code
  });    
});

jquery-mobileは優れた安定したフレームワークを提供するため、これは受け入れられる答えになるはずです
pasx

1

最もエレガントでクリーンなのは、jQueryプラグイン:https : //github.com/untill/jquery.longclick/で、packackeとしても入手できます:https ://www.npmjs.com/package/jquery.longclick 。

つまり、次のように使用します。

$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );

このプラグインの利点は、ここでの他のいくつかの回答とは対照的に、クリックイベントがまだ可能であることです。マウスを離す前に、デバイスを長押しするのと同じように、長クリックが発生することにも注意してください。それが特徴です。


0

私にとっては、そのコード(jQueryを使用)で動作します。

var int       = null,
    fired     = false;

var longclickFilm = function($t) {
        $body.css('background', 'red');
    },
    clickFilm = function($t) {
        $t  = $t.clone(false, false);
        var $to = $('footer > div:first');
        $to.find('.empty').remove();
        $t.appendTo($to);
    },
    touchStartFilm = function(event) {
        event.preventDefault();
        fired     = false;
        int       = setTimeout(function($t) {
            longclickFilm($t);
            fired = true;
        }, 2000, $(this)); // 2 sec for long click ?
        return false;
    },
    touchEndFilm = function(event) {
        event.preventDefault();
        clearTimeout(int);
        if (fired) return false;
        else  clickFilm($(this));
        return false;
    };

$('ul#thelist .thumbBox')
    .live('mousedown touchstart', touchStartFilm)
    .live('mouseup touchend touchcancel', touchEndFilm);

0

クリックまたは長押しを識別する時間を確認できます[jQuery]

function AddButtonEventListener() {
try {
    var mousedowntime;
    var presstime;
    $("button[id$='" + buttonID + "']").mousedown(function() {
        var d = new Date();
        mousedowntime = d.getTime();
    });
    $("button[id$='" + buttonID + "']").mouseup(function() {
        var d = new Date();
        presstime = d.getTime() - mousedowntime;
        if (presstime > 999/*You can decide the time*/) {
            //Do_Action_Long_Press_Event();
        }
        else {
            //Do_Action_Click_Event();
        }
    });
}
catch (err) {
    alert(err.message);
}
} 

0

このような?

doc.addEeventListener("touchstart", function(){
    // your code ...
}, false);    

0

jqueryタッチイベントを使用できます。(こちらをご覧ください

  let holdBtn = $('#holdBtn')
  let holdDuration = 1000
  let holdTimer

  holdBtn.on('touchend', function () {
    // finish hold
  });
  holdBtn.on('touchstart', function () {
    // start hold
    holdTimer = setTimeout(function() {
      //action after certain time of hold
    }, holdDuration );
  });

0

長押しのキーボードイベントに何かが必要だったので、これを書きました。

var longpressKeys = [13];
var longpressTimeout = 1500;
var longpressActive = false;
var longpressFunc = null;

document.addEventListener('keydown', function(e) {
    if (longpressFunc == null && longpressKeys.indexOf(e.keyCode) > -1) {
        longpressFunc = setTimeout(function() {
            console.log('longpress triggered');
            longpressActive = true;
        }, longpressTimeout);

    // any key not defined as a longpress
    } else if (longpressKeys.indexOf(e.keyCode) == -1) {
        console.log('shortpress triggered');
    }
});

document.addEventListener('keyup', function(e) {
    clearTimeout(longpressFunc);
    longpressFunc = null;

    // longpress key triggered as a shortpress
    if (!longpressActive && longpressKeys.indexOf(e.keyCode) > -1) {
        console.log('shortpress triggered');
    }
    longpressActive = false;
});

0

私はこれがあなたを助けることができると思います:

var image_save_msg = 'You Can Not Save images!';
var no_menu_msg = 'Context Menu disabled!';
var smessage = "Content is protected !!";

function disableEnterKey(e) {
    if (e.ctrlKey) {
        var key;
        if (window.event)
            key = window.event.keyCode; //IE
        else
            key = e.which; //firefox (97)
        //if (key != 17) alert(key);
        if (key == 97 || key == 65 || key == 67 || key == 99 || key == 88 || key == 120 || key == 26 || key == 85 || key == 86 || key == 83 || key == 43) {
            show_wpcp_message('You are not allowed to copy content or view source');
            return false;
        } else
            return true;
    }
}

function disable_copy(e) {
    var elemtype = e.target.nodeName;
    var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
    elemtype = elemtype.toUpperCase();
    var checker_IMG = '';
    if (elemtype == "IMG" && checker_IMG == 'checked' && e.detail >= 2) {
        show_wpcp_message(alertMsg_IMG);
        return false;
    }
    if (elemtype != "TEXT" && elemtype != "TEXTAREA" && elemtype != "INPUT" && elemtype != "PASSWORD" && elemtype != "SELECT" && elemtype != "OPTION" && elemtype != "EMBED") {
        if (smessage !== "" && e.detail == 2)
            show_wpcp_message(smessage);

        if (isSafari)
            return true;
        else
            return false;
    }
}

function disable_copy_ie() {
    var elemtype = window.event.srcElement.nodeName;
    elemtype = elemtype.toUpperCase();
    if (elemtype == "IMG") {
        show_wpcp_message(alertMsg_IMG);
        return false;
    }
    if (elemtype != "TEXT" && elemtype != "TEXTAREA" && elemtype != "INPUT" && elemtype != "PASSWORD" && elemtype != "SELECT" && elemtype != "OPTION" && elemtype != "EMBED") {
        //alert(navigator.userAgent.indexOf('MSIE'));
        //if (smessage !== "") show_wpcp_message(smessage);
        return false;
    }
}

function reEnable() {
    return true;
}
document.onkeydown = disableEnterKey;
document.onselectstart = disable_copy_ie;
if (navigator.userAgent.indexOf('MSIE') == -1) {
    document.onmousedown = disable_copy;
    document.onclick = reEnable;
}

function disableSelection(target) {
    //For IE This code will work
    if (typeof target.onselectstart != "undefined")
        target.onselectstart = disable_copy_ie;

    //For Firefox This code will work
    else if (typeof target.style.MozUserSelect != "undefined") {
        target.style.MozUserSelect = "none";
    }

    //All other  (ie: Opera) This code will work
    else
        target.onmousedown = function() {
            return false
        }
    target.style.cursor = "default";
}
// on_body_load

window.onload = function() {
    disableSelection(document.body);
};



// disable_Right_Click



document.ondragstart = function() {
    return false;
}

function nocontext(e) {
    return false;
}
document.oncontextmenu = nocontext;

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.