2015-06-08 15 views
7

Zaman uyumsuz bir JSONP isteğinin sonucunu panoya kopyalamak için execCommand in Chrome (Yapı 43) programlı olarak kullanmaya çalışıyorum. İşte mantık snippet geçerli:Eşzamansız bağımlı içeriği bir tıklatmayla panoya nasıl programlanır?

loadContent() 

function loadContent(callback) { 
    $.getJSON('http://www.randomtext.me/api/lorem/p-5/10-20?&callback=myFunc',function(result){ 
    console.log('result=',result.text_out); 
    $("#container").html(result.text_out); 
    if (callback) { 
     callback(); 
    } 
    }); 
} 

function copyAjax() { 

loadContent(copy); 

} 

function copy() { 
    var copyDivText = $('#container').text(); 
    console.log('copyDivText=',copyDivText); 
    executeCopy(copyDivText); 
} 

document.addEventListener("DOMContentLoaded", function(){ 
     document.getElementById("copy").onclick = copy; 
    }); 


document.addEventListener("DOMContentLoaded", function(){ 
     document.getElementById("copyAjax").onclick = copyAjax; 
    }); 


// Copy text as text 
function executeCopy(text) { 
    var input = document.createElement('textarea'); 
    document.body.appendChild(input); 
    input.value = text; 
    input.focus(); 
    input.select(); 
    document.execCommand('Copy'); 
    input.remove(); 
} 

Ben başlayan kod Chrome 43 build panoya ile ExecCommand kullandıklarını biliyoruz. Bununla birlikte, sorun, kullanıcı kaynaklı bir olayın yürütülmesi (bunu, izinlerin yükseltildiği) içinde yapmanız gerektiğidir. Bu, ZeroClipboard flash tabanlı çözümün sahip olduğu benzer bir kısıtlamadır.

  1. JSONP yana: o (Ben şimdi yaklaşık düşünmek budur) mümkün olmadığını bir cevap, bunlar son çare olarak yapmayı düşündünüz diğer seçenekler girmesini hariç (uyarı, hepsi Hail Mary Passes vardır) senkronize edilemez, normal bir AJAX çağrısı kullanan bir şeye dönüştürün ve AJAX çağrısının kullanıcı olayının yürütme bağlamında senkronize olduğundan emin olun. Bu benim derinden kökleşmiş inancımla çelişiyor, kullanıcı deneyimini azalttığından senkronize XHR çağrıları yapmamalıyız.
  2. Kullanıcı, fareyle kopya düğmesine yaklaştıkça, sunucu isteğini önceden göndeririz ve kullanıcının düğmeyi tıklamadan önce yeterince hızlı olmasını umarız. Bu, zamanın bir parçası olmayan ve kopyalama düğmesine tıklamak yerine Ctrl/Command-C yapmak istediğinde belirli bir şekilde çalışmayacak olan bariz bir yarış durumudur.
  3. İki adımlı bir işlem gerçekleştirin. İçeriği kullanıma sunduğunda aramayı tetiklemek için tek bir tıklama, içeriğin kullanılabilir olduğunu gösteren bir mesaj göstererek panoya kopyalamak için msg alanına bir başka tıklama basın. Şimdiye kadarki en iyi UX etkileşimi gibi görünmüyor. Bu alternatifle this example'u oluşturdum. Tıklama, programatik olarak bir kullanıcı sorunları olayı oluşturmuyor.
  4. Basit bir Chrome uzantısı oluşturmanın ve kullanıcının bu uzantı için panoya kopyalamak üzere izin vermesi için bir yol olabilir. Bu, son kullanıcının yerel tarayıcı ayarlarını yüklemesi ve genişletmesi ve değiştirmesi gerektiğinden oluşur. Pek çok kullanıcının bunu yapmaya/yapmaya istekli olduğundan emin değil.

Zaten this gibi Stackoverflow sorularına baktım, ancak bunlar eşzamansız bir senaryoya hitap etmiyor. Lütfen başka bir işlenebilir çözüm bulabilirseniz (veya mevcut olanı çimdik) lütfen bana bildirin.

+0

Bunun için başka bir fikir daha buldunuz mu? Bir kullanıcının kopyalamayı istediği kesin bir duruma sahibim ve bir DB'den ayrıntıları almak için sunucuya gidiş dönüş yapmam gerekiyor. 3 öneriyi kullanmak 4 kötülüğün en iyisi gibi görünür :(.... – pythonator

+0

> 2. İki adımlı bir işlem gerçekleştirin Bunu yakın zamanda uyguladım.Temel UX, kullanıcı "Bağlantı Al" düğmesini tıkladığında, ajax isteğini yapar ve bir döndürücü görüntüler. İstek bittiğinde, yanında küçük bir kopya düğmesiyle birlikte bir metin girişi görüntülersiniz (bootstrap css input prepend simgesi gibi). Metnin girdide otomatik olarak seçildiğinden emin olun. Simgeye tıklamak kullanıcının panosuna kopyalanmalıdır. Kısıtlamalar göz önüne alındığında bunu mümkün olduğunca güzel yapmak için etkileşimleri düzenleyebilirsiniz (örneğin, girdiyi, tüm metni focusIn üzerine seçtim). – les2

cevap

2

Bu Snippet'inizdeki dayalı zaman aşımı yaklaşım çalışıyor:

HTML:

<div id="container"> 
Enter Text To Copy</br> 
<textarea id="clipboard"></textarea> 
</div> 
<input type="button" value="Copy" id="copy"/> 

JS:

var timeout = 600; // timeout based on ajax response time 
var loaded = false; 

function loadContent() { 
    loaded = false; 
    $.getJSON('http://codepen.io/gkohen/pen/QbvoQW.js',function(result){ 
    document.getElementById("clipboard").value = result.lorem; 
    loaded = true; 
    }); 
} 

// Copy text as text 
function copy() { 
    clipboard = document.getElementById("clipboard"); 
    if (!loaded || clipboard.value.length == 0) { 
    alert("Ajax timeout! TIP: Try to increase timeout value."); 
    return; 
    } 

    clipboard.focus(); 
    clipboard.select(); 

    if (document.execCommand('Copy')) 
    alert("Successfuly coppied to clipboard!"); 

    // set defaults 
    clipboard.value = ""; 
    loaded = false; 
} 

document.addEventListener("DOMContentLoaded", function(){ 
    document.getElementById("copy").onmousedown = loadContent; 
    document.getElementById("copy").onclick = function() { 
    setTimeout(copy, timeout); // wait for ajax 
    } 
}); 

ana konu execCommand özelliğidir. Güvenlik ve trusted eylemleri hakkında bazı kısıtlamalar vardır. Bu yüzden, olay çağıran kopya ve ajax çağrı aparte yapmak zorunda. Bu kirli yolla - sabit zaman aşımı (yukarıdaki kod) veya uygun şekilde - kırılabilir uyku ile yapılabilir. Yeni uyku özelliği here'dan bahsediliyor ve belki de clearTimeout ile kırılabilir varyant olarak değiştirilebilir, ancak denemedim.

+0

Belki de, burada bahsettiğim bir şey yapabilirdiniz: [ÇÖZÜLDÜ: AJAX ile çalışmayan belge yürütme komutu] (http://stackoverflow.com/questions/43380921/not-able-to-copy-a-link-directly -ne zaman-i-am-kullanma-ajax/43381458 # 43381458) –

İlgili konular