928 votes

Comment Trello d'accès de l'utilisateur presse-papiers?

Lorsque vous passez la souris sur une carte, dans Trello et appuyez sur Ctrl+C, l'URL de cette carte est copié dans le presse-papiers. Comment font-ils cela?

Aussi loin que je peux dire, il n'y a pas de Flash film impliqués. J'ai Flashblock installé, et le Firefox onglet réseau montre pas de Flash film est chargé. (C'est la méthode habituelle, par exemple, par ZeroClipboard.)

Comment font-ils pour réaliser ce tour de magie?

(En ce moment je pense que j'ai eu une révélation: Vous ne pouvez pas sélectionner le texte sur la page, donc je suppose qu'ils ont un élément invisible, où ils créent une sélection de texte via du code JavaScript, et Ctrl+C déclenche le navigateur par défaut de comportement, la copie invisible nœud de la valeur de texte.)

1542voto

Daniel LeCheminant Points 28101

Divulgation: j'ai écrit le code qui utilise Trello; le code ci-dessous est le code source Trello utilise pour accomplir le presse-papiers truc.


Nous ne sommes pas réellement "l'accès de l'utilisateur presse-papiers", au lieu de nous aider à l'utilisateur un peu en sélectionnant quelque chose d'utile quand ils appuyez sur Ctrl+C.

Sonne comme vous avez pensé à elle; nous profitons du fait que, si vous voulez frapper Ctrl+C, vous devez frapper la touche Ctrl touche en premier. Lorsque la touche Ctrl est enfoncée, nous pop dans un textarea qui contient le texte que nous voulons pour finir sur le presse-papiers, et de sélectionner tout le texte, de sorte que la sélection est tous ensemble lors de la C touche. (Puis nous cacher le textarea quand le Ctrl clé vient)

Plus précisément, Trello fait ceci:

TrelloClipboard = new class
  constructor: ->
    @value = ""

    $(document).keydown (e) =>
      # Only do this if there's something to be put on the clipboard, and it
      # looks like they're starting a copy shortcut
      if !@value || !(e.ctrlKey || e.metaKey)
        return

      if $(e.target).is("input:visible,textarea:visible")
        return

      # Abort if it looks like they've selected some text (maybe they're trying
      # to copy out a bit of the description or something)
      if window.getSelection?()?.toString()
        return

      if document.selection?.createRange().text
        return

      _.defer =>
        $clipboardContainer = $("#clipboard-container")
        $clipboardContainer.empty().show()
        $("<textarea id='clipboard'></textarea>")
        .val(@value)
        .appendTo($clipboardContainer)
        .focus()
        .select()

    $(document).keyup (e) ->
      if $(e.target).is("#clipboard")
        $("#clipboard-container").empty().hide()

  set: (@value) ->

Dans les DOM, nous avons

<div id="clipboard-container"><textarea id="clipboard"></textarea></div>

CSS pour le presse-papiers trucs:

#clipboard-container {
  position: fixed;
  left: 0px;
  top: 0px;
  width: 0px;
  height: 0px;
  z-index: 100;
  display: none;
  opacity: 0;
}
#clipboard {
  width: 1px;
  height: 1px;       
  padding: 0px;
}

... et le CSS qu'il fait en sorte que vous ne pouvez pas voir le textarea quand il saute ... mais il est "visible" assez pour copier à partir de.

Lorsque vous passez la souris sur une carte, il appelle

TrelloClipboard.set(cardUrl)

... alors le presse-papiers helper sait que choisir lorsque la touche Ctrl est enfoncée.

79voto

Dhruv Vemula Points 501

J'en ai construit une extension Chrome qui fait exactement cela, et pour toutes les pages web. Le code source sur GitHub.

Je trouve trois bugs avec Trello est une approche qui, je le sais parce que j'ai été confronté à moi-même :)

La copie ne fonctionne pas dans ces scénarios:

  1. Si vous avez déjà Ctrl enfoncée, puis placez un lien et a frappé C, la copie ne fonctionne pas.
  2. Si votre curseur se trouve dans certains autres champ de texte dans la page, la copie ne fonctionne pas.
  3. Si votre curseur se trouve dans la barre d'adresse, la copie ne fonctionne pas.

J'ai résolu le numéro 1 en ayant toujours caché durée, plutôt que d'en créer un lorsque l'utilisateur appuie sur Ctrl/Cmd.

J'ai résolu #2 temporairement par la compensation de longueur nulle sélection, l'enregistrement de la position du curseur, en faisant la copie et la restauration de la position du curseur.

Je n'ai pas trouvé un correctif pour le #3 encore :) (Pour plus d'informations, consultez la question ouverte dans mon projet GitHub).

20voto

Felix Points 206

Avec l'aide de l'imperméable (lien vers github) code que j'ai réussi à obtenir une version en cours d'exécution accéder au presse-papiers avec du javascript.

function TrelloClipboard() {
    var me = this;

    var utils = {
        nodeName: function (node, name) {
            return !!(node.nodeName.toLowerCase() === name)
        }
    }
    var textareaId = 'simulate-trello-clipboard',
        containerId = textareaId + '-container',
        container, textarea

    var createTextarea = function () {
        container = document.querySelector('#' + containerId)
        if (!container) {
            container = document.createElement('div')
            container.id = containerId
            container.setAttribute('style', [, 'position: fixed;', 'left: 0px;', 'top: 0px;', 'width: 0px;', 'height: 0px;', 'z-index: 100;', 'opacity: 0;'].join(''))
            document.body.appendChild(container)
        }
        container.style.display = 'block'
        textarea = document.createElement('textarea')
        textarea.setAttribute('style', [, 'width: 1px;', 'height: 1px;', 'padding: 0px;'].join(''))
        textarea.id = textareaId
        container.innerHTML = ''
        container.appendChild(textarea)

        textarea.appendChild(document.createTextNode(me.value))
        textarea.focus()
        textarea.select()
    }

    var keyDonwMonitor = function (e) {
        var code = e.keyCode || e.which;
        if (!(e.ctrlKey || e.metaKey)) {
            return
        }
        var target = e.target
        if (utils.nodeName(target, 'textarea') || utils.nodeName(target, 'input')) {
            return
        }
        if (window.getSelection && window.getSelection() && window.getSelection().toString()) {
            return
        }
        if (document.selection && document.selection.createRange().text) {
            return
        }
        setTimeout(createTextarea, 0)
    }

    var keyUpMonitor = function (e) {
        var code = e.keyCode || e.which;
        if (e.target.id !== textareaId || code !== 67) {
            return
        }
        container.style.display = 'none'
    }

    document.addEventListener('keydown', keyDonwMonitor)
    document.addEventListener('keyup', keyUpMonitor)
}

TrelloClipboard.prototype.setValue = function (value) {
    this.value = value;
}

var clip = new TrelloClipboard();
clip.setValue("test");

Le seul problème, c'est que cette version ne fonctionne qu'avec Chrome.Le Trello plattform prend en charge tous les navigateurs. Ce que je suis absent?

Sovled grâce à VadimIvanov.

Voir un exemple: http://jsfiddle.net/AGEf7/

5voto

Boris Samardžija Points 1246

Quelque chose de très similaire peut être vu sur http://goo.gl lorsque vous raccourcir les URL.

Il y a un readonly élément de saisie obtient par programmation ciblée, d'info-bulle ", Appuyez sur CTRL-C pour copier". Lorsque vous appuyez sur ce raccourci, de l'apport de contenu est en fait dans le presse-papiers. Vraiment sympa :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X