2016-06-13 49 views
0

我創建一個列表,每個列表都有輸入,這意味着它可以被編輯。但是,我有一個問題。我可以使用箭頭鍵瀏覽此列表,並集中目標輸入嗎?使用angularjs或jquery瀏覽列表

.content ul { 
 
    padding: 0; 
 
} 
 
.content ul li { 
 
    list-syle: none; 
 
}
<div class="content"> 
 
    <ul> 
 
    <li><textarea name="text" id=""></textarea></li> 
 
    <li><textarea name="text" id=""></textarea></li> 
 
    <li><textarea name="text" id=""></textarea></li> 
 
    </ul> 
 
</div>

+1

你想用tab鍵代替箭頭鍵。 – Win

+0

目前還不清楚這與angularjs有什麼關係。 – Claies

+0

我想擁有相同的樣子:https://app.asana.com/ –

回答

1

我剛剛發現這個解決方案導航指令,它的工作對我來說:

var setSelectionByCharacterOffsets = null; 
 
// set cursor 
 
if (window.getSelection && document.createRange) { 
 
    setSelectionByCharacterOffsets = function(containerEl, start, end) { 
 
     var charIndex = 0, range = document.createRange(); 
 
     range.setStart(containerEl, 0); 
 
     range.collapse(true); 
 
     var nodeStack = [containerEl], node, foundStart = false, stop = false; 
 

 
     while (!stop && (node = nodeStack.pop())) { 
 
      if (node.nodeType == 3) { 
 
       var nextCharIndex = charIndex + node.length; 
 
       if (!foundStart && start >= charIndex && start <= nextCharIndex) { 
 
        range.setStart(node, start - charIndex); 
 
        foundStart = true; 
 
       } 
 
       if (foundStart && end >= charIndex && end <= nextCharIndex) { 
 
        range.setEnd(node, end - charIndex); 
 
        stop = true; 
 
       } 
 
       charIndex = nextCharIndex; 
 
      } else { 
 
       var i = node.childNodes.length; 
 
       while (i--) { 
 
        nodeStack.push(node.childNodes[i]); 
 
       } 
 
      } 
 
     } 
 

 
     var sel = window.getSelection(); 
 
     sel.removeAllRanges(); 
 
     sel.addRange(range); 
 
    } 
 
} else if (document.selection) { 
 
    setSelectionByCharacterOffsets = function(containerEl, start, end) { 
 
     var textRange = document.body.createTextRange(); 
 
     textRange.moveToElementText(containerEl); 
 
     textRange.collapse(true); 
 
     textRange.moveEnd("character", end); 
 
     textRange.moveStart("character", start); 
 
     textRange.select(); 
 
    }; 
 
} 
 

 
var setCaret = function(element, index) { 
 
    setSelectionByCharacterOffsets(element, index, index); 
 
}; 
 

 
function cursorIndex() { 
 
    return window.getSelection().getRangeAt(0).startOffset; 
 
} 
 

 
// splits text into array of lines 
 
(function($) { 
 
$.fn.lines = function(){ 
 
    words = this.text().split(" "); //split text into each word 
 
    lines = []; 
 
    
 
    hiddenElement = this.clone(); //copies font settings and width 
 
    hiddenElement.empty();//clear text 
 
    hiddenElement.css("visibility", "hidden"); 
 
    
 
    jQuery('body').append(hiddenElement); // height doesn't exist until inserted into document 
 
    
 
    hiddenElement.text('i'); //add character to get height 
 
    height = hiddenElement.height(); 
 
    hiddenElement.empty(); 
 
    
 
    startIndex = -1; // quick fix for now - offset by one to get the line indexes working 
 
    jQuery.each(words, function() { 
 
     lineText = hiddenElement.text(); // get text before new word appended 
 
     hiddenElement.text(lineText + " " + this); 
 
     if(hiddenElement.height() > height) { // if new line 
 
      lines.push({text: lineText, startIndex: startIndex, endIndex: (lineText.length + startIndex)}); // push lineText not hiddenElement.text() other wise each line will have 1 word too many 
 
      startIndex = startIndex + lineText.length +1; 
 
      hiddenElement.text(this); //first word of the next line 
 
     } 
 
    }); 
 
    lines.push({text: hiddenElement.text(), startIndex: startIndex, endIndex: (hiddenElement.text().length + startIndex)}); // push last line 
 
    hiddenElement.remove(); 
 
    lines[0].startIndex = 0; //quick fix for now - adjust first line index 
 
    return lines; 
 
} 
 
})(jQuery); 
 

 
(function($) { // to save a bit of typing 
 
    $.fn.lastLine = function() { 
 
     return this.lines()[this.lines().length-1]; 
 
    } 
 
})(jQuery); 
 

 
function findLineViaCaret(textElement,caretIndex){ 
 
    jQuery.each(textElement.lines(), function() { 
 
     if(this.startIndex <= caretIndex && this.endIndex >= caretIndex) { 
 
      r = this; 
 
      return false; // exits loop 
 
     } 
 
    }); 
 
    return r; 
 
} 
 

 
function distanceToCaret(textElement,caretIndex){ 
 

 
    line = findLineViaCaret(textElement,caretIndex); 
 
    if(line.startIndex == 0) { 
 
    // +1 needed for substring to be correct but only first line? 
 
     relativeIndex = caretIndex - line.startIndex +1; 
 
    } else { 
 
     relativeIndex = caretIndex - line.startIndex; 
 
    } 
 
    textToCaret = line.text.substring(0, relativeIndex); 
 
    
 
    hiddenElement = textElement.clone(); //copies font settings and width 
 
    hiddenElement.empty();//clear text 
 
    hiddenElement.css("visibility", "hidden"); 
 
    hiddenElement.css("width", "auto"); //so width can be measured 
 
    hiddenElement.css("display", "inline-block"); //so width can be measured 
 

 
    jQuery('body').append(hiddenElement); // doesn't exist until inserted into document 
 
    
 
    hiddenElement.text(textToCaret); //add to get width 
 
    width = hiddenElement.width(); 
 
    hiddenElement.remove(); 
 
    
 
    return width; 
 
} 
 

 
function getCaretViaWidth(textElement, lineNo, width) { 
 
    line = textElement.lines()[lineNo-1]; 
 
     
 
    lineCharacters = line.text.replace(/^\s+|\s+$/g, '').split(""); 
 
    
 
    hiddenElement = textElement.clone(); //copies font settings and width 
 
    hiddenElement.empty();//clear text 
 
    hiddenElement.css("visibility", "hidden"); 
 
    hiddenElement.css("width", "auto"); //so width can be measured 
 
    hiddenElement.css("display", "inline-block"); //so width can be measured 
 
    
 
    jQuery('body').append(hiddenElement); // doesn't exist until inserted into document 
 
    
 
    if(width == 0) { //if width is 0 index is at start 
 
     caretIndex = line.startIndex; 
 
    } else {// else loop through each character until width is reached 
 
     hiddenElement.empty(); 
 
     jQuery.each(lineCharacters, function() { 
 
      text = hiddenElement.text(); 
 
      prevWidth = hiddenElement.width(); 
 
      hiddenElement.text(text + this); 
 
      elWidth = hiddenElement.width(); 
 
      caretIndex = hiddenElement.text().length + line.startIndex; 
 
      if(hiddenElement.width() > width) { 
 
       // check whether character after width or before width is closest 
 
       if(Math.abs(width - prevWidth) < Math.abs(width - elWidth)) { 
 
        caretIndex = caretIndex -1; // move index back one if previous is closes 
 
       } 
 
       return false; 
 
      } 
 
     }); 
 
    } 
 
    hiddenElement.remove(); 
 
    return caretIndex; 
 
} 
 

 
// arrow key conditions 
 
$(document).on('keydown', 'p[contenteditable="true"]', function(e) { 
 
    //if cursor on first line & up arrow key 
 
    if(e.which == 38 && (cursorIndex() < $(this).lines()[0].text.length)) { 
 
     e.preventDefault(); 
 
     if ($(this).prev().is('p')) { 
 
      prev = $(this).prev('p'); 
 
      getDistanceToCaret = distanceToCaret($(this), cursorIndex()); 
 
      lineNumber = prev.lines().length; 
 
      caretPosition = getCaretViaWidth(prev, lineNumber, getDistanceToCaret); 
 
      prev.focus(); 
 
      setCaret(prev.get(0), caretPosition); 
 
     } 
 
    // if cursor on last line & down arrow 
 
    } else if(e.which == 40 && cursorIndex() >= $(this).lastLine().startIndex && cursorIndex() <= ($(this).lastLine().startIndex + $(this).lastLine().text.length)) { 
 
     e.preventDefault(); 
 
     if ($(this).next().is('p')) { 
 
      next = $(this).next('p'); 
 
      getDistanceToCaret = distanceToCaret($(this), cursorIndex()); 
 
      caretPosition = getCaretViaWidth(next, 1, getDistanceToCaret); 
 
      next.focus(); 
 
      setCaret(next.get(0), caretPosition); 
 
     } 
 
     //if start of paragraph and left arrow 
 
    } else if(e.which == 37 && cursorIndex() == 0) { 
 
     e.preventDefault(); 
 
     if ($(this).prev().is('p')) { 
 
      prev = $(this).prev('p'); 
 
      prev.focus(); 
 
      setCaret(prev.get(0), prev.text().length); 
 
     } 
 
     // if end of paragraph and right arrow 
 
    } else if(e.which == 39 && cursorIndex() == $(this).text().length) { 
 
     e.preventDefault(); 
 
     if ($(this).next().is('p')) { 
 
      $(this).next('p').focus(); 
 
     } 
 
    }; 
 
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> 
 
<p contenteditable = "true" >Lorem ipsum dolor sit amet, consectetur adipiscing elit. pendisse potenti. Sed faucibus nunc sed erat pellentesque ac auctor massa posuere.</p> 
 
<p contenteditable = "true" >Nullam fringilla, urna nec consequat laoreet, massa nibh posuere mauris, id consequat lectus tellus facilisis nisl. Quisque quis lectus tellus. .</p> 
 
<p contenteditable = "true" >Aenean sit amet mattis diam. Cras sed augue et nunc citudin sed erat. Quisque at erat ut felis consequat luctus eget vitae lectus.</p>

1

創建使用keyUp功能通過textarea

<ul> 
    <li><textarea name="text" id="" focus-next=""></textarea></li> 
    <li><textarea name="text" id="" focus-next=""></textarea></li> 
    <li><textarea name="text" id="" focus-next=""></textarea></li> 
    </ul> 

.directive('focusNext', function() { 
    return { 
     restrict: 'A', 
     link: function(scope, elem, attrs) { 
     elem.bind('keydown', function(e) {   
      var code = e.keyCode || e.which; 
      if (code === 40) { 
      e.preventDefault(); 
      if(elem.parent().next().find('textarea')[0]) 
       elem.parent().next().find('textarea')[0].focus();    
      } 
     }); 
     } 
    }; 
    }); 

結賬小提琴 https://jsfiddle.net/ebinmanuval/n04n8gbh/