2015-01-29 16 views
10

Tôi đang làm việc trên ứng dụng dấu trang, nơi tôi phải lưu trữ từ khóa hoặc từ hoặc nội dung đã chọn của người dùng. Tôi đang sử dụng các phương thức javascript createRange() và addRange() để tạo phạm vi và sau đó tìm ra các phần tử/nội dung đã chọn bởi người dùng. Mã tôi viết cho điều này là như sau.Lựa chọn không tôn trọng không được hỗ trợ lỗi trong google chrome và chromium

<head> 
<script type="text/javascript"> 
    var storedSelections = []; 

    function StoreSelection() { 
     if (window.getSelection) { 
      var currSelection = window.getSelection(); 
      for (var i = 0; i < currSelection.rangeCount; i++) { 
       storedSelections.push (currSelection.getRangeAt (i)); 
      } 
      currSelection.removeAllRanges(); 
     } else { 
      alert ("Your browser does not support this example!"); 
     } 
    } 

    function ClearStoredSelections() { 
     storedSelections.splice (0, storedSelections.length); 
    } 

    function ShowStoredSelections() { 
     if (window.getSelection) { 
      var currSelection = window.getSelection(); 
      currSelection.removeAllRanges(); 
      for (var i = 0; i < storedSelections.length; i++) { 
       currSelection.addRange (storedSelections[i]); 
      } 
     } else { 
      alert ("Your browser does not support this example!"); 
     } 
    } 
</script> 
</head> 
<body> 
    Select some content on this page and use the buttons below.<br />   <br /> 
    <button onclick="StoreSelection();">Store the selection</button> 
    <button onclick="ClearStoredSelections();">Clear stored selections 
</button> 
    <button onclick="ShowStoredSelections();">Show stored selections</button> 

</body> 

Mã này đang làm việc một cách hoàn hảo trên Firefox. Tôi có thể chọn nhiều thứ từng cái một và có thể hiển thị lại nội dung đã chọn nhưng trên chrome và crom tôi gặp phải lỗi Discontiguous selection is not supported. khi tôi lưu trữ nhiều hơn một thành phần trong dãy ô và nhấp vào nút hiển thị lựa chọn được lưu trữ.

Trợ giúp sẽ được đánh giá cao. Và vui lòng đề nghị tôi nếu có một số lựa chọn thay thế khác thực hiện tác vụ đánh dấu trang này.

+0

Có thể [this] (https://code.google.com/p/rangy/issues/detail?id=208) trợ giúp không? – Siguza

+0

Có được rằng nó chỉ là một cảnh báo nhưng nếu bạn chạy mã trong cả hai firefox và chrome, bạn sẽ thấy sự khác biệt trong chức năng và sẽ thấy rằng nó là một lỗi trong chromium và chrom –

+0

Chỉ cần thử nghiệm nó trên OS X 10.10 với Chrome (40.0.2214.93, 64bit) và Safari (8.0.2, xây dựng 10600.2.5) - hoạt động với cả hai và không có gì trong giao diện điều khiển cả. – Siguza

Trả lời

6

Dưới đây là cách duy nhất có thể làm điều này mà tôi đã có thể đưa ra:

Bó lựa chọn trong <span style="background: Highlight;">...</span>.

Nhưng lưu ý:

  • Rõ ràng, bạn phải gỡ bỏ những nhịp trở lại ngay khi bất cứ điều gì khác được chọn, nhưng điều đó không nên quá khó khăn. Tuy nhiên, bạn nên sử dụng window.onmousedown cho rằng thay vì window.onclick, vì onclick được kích hoạt sau bất kỳ nút nào được nhấn, vì vậy khi nhấn nút "Hiển thị lựa chọn được lưu trữ", lựa chọn mới sẽ được tạo. bị bắt.
  • Xóa hoặc thay thế bất kỳ phần tử nào trong đó lựa chọn được lưu trữ bắt đầu hoặc kết thúc sẽ làm mất hiệu lực lựa chọn đó, vì vậy khi nhấp vào "Hiển thị lựa chọn được lưu trữ", sẽ không có nội dung nào hiển thị.
  • Nếu lựa chọn kéo dài trên nhiều phần tử, nó cần chia thành một lựa chọn cho mỗi phần tử, nếu không chèn khoảng thời gian sẽ không thành công hoặc cắt các phần tử khác (như nút) làm đôi.

Các mã sau (fiddle) là tốt nhất mà tôi đã có thể làm:

var storedSelections = []; 
 
var simulatedSelections = []; 
 

 
window.onmousedown = clearSimulatedSelections; 
 

 
function storeSelection() 
 
{ 
 
    if(window.getSelection) 
 
    { 
 
     var currSelection = window.getSelection(); 
 
     for(var i = 0; i < currSelection.rangeCount; i++) 
 
     { 
 
      storeRecursive(currSelection.getRangeAt(i)); 
 
     } 
 
     currSelection.removeAllRanges(); 
 
    } 
 
    else 
 
    { 
 
     alert("Your browser does not support this example!"); 
 
    } 
 
} 
 

 
function storeRecursive(selection, node, started) 
 
{ 
 
    node = node || document.body; 
 
    started = started || false; 
 
    var nodes = node.childNodes; 
 
    for(var i = 0; i < nodes.length; i++) 
 
    { 
 
     if(nodes[i].nodeType == 3) 
 
     { 
 
      var first = nodes[i] == selection.startContainer; 
 
      var last = nodes[i] == selection.endContainer; 
 
      if(first) 
 
      { 
 
       started = true; 
 
      } 
 
      if(started) 
 
      { 
 
       var sel = selection.cloneRange(); 
 
       if(!first) 
 
       { 
 
        sel.setStartBefore(nodes[i]); 
 
       } 
 
       if(!last) 
 
       { 
 
        sel.setEndAfter(nodes[i]); 
 
       } 
 
       storedSelections.push(sel); 
 
       if(last) 
 
       { 
 
        return false; 
 
       } 
 
      } 
 
     } 
 
     else 
 
     { 
 
      started = storeRecursive(selection, nodes[i], started); 
 
     } 
 
    } 
 
    return started; 
 
} 
 

 
function clearStoredSelections() 
 
{ 
 
    storedSelections = []; 
 
} 
 

 
function showStoredSelections() 
 
{ 
 
    if(window.getSelection) 
 
    { 
 
     var currSelection = window.getSelection(); 
 
     currSelection.removeAllRanges(); 
 
     for(var i = 0; i < storedSelections.length; i++) 
 
     { 
 
      var node = document.createElement("span"); 
 
      node.className = "highlight"; 
 
      storedSelections[i].surroundContents(node); 
 
      simulatedSelections.push(node); 
 
     } 
 
    } 
 
    else 
 
    { 
 
     alert("Your browser does not support this example!"); 
 
    } 
 
} 
 

 
function clearSimulatedSelections() 
 
{ 
 
    for(var i = 0; i < simulatedSelections.length; i++) 
 
    { 
 
     var sec = simulatedSelections[i]; 
 
     var pn = sec.parentNode; 
 
     while(sec.firstChild) 
 
     { 
 
      pn.insertBefore(sec.firstChild, sec); 
 
     } 
 
     pn.removeChild(sec); 
 
    } 
 
    simulatedSelections = []; 
 
}
.highlight 
 
{ 
 
    background: Highlight; 
 
}
Select some content on this page and use the buttons below.<br><br> 
 
<button onclick="storeSelection();">Store the selection</button> 
 
<button onclick="clearStoredSelections();">Clear stored selections</button> 
 
<button onclick="showStoredSelections();">Show stored selections</button>

Nó hoạt động trong Firefox, Safari và Chrome, nhưng có những thiếu sót sau đây:

  • Lựa chọn trên nhiều dòng không chọn vùng trống giữa đầu của l ine và đường viền của phần tử cha, giống như các lựa chọn thực tế.
  • Đôi khi khi bắt đầu lựa chọn tại một điểm trước khi bắt đầu lựa chọn được lưu trữ, hiển thị chúng sẽ hợp nhất các phạm vi, do đó, văn bản ở giữa cũng được chọn. Sắp xếp mảng các lựa chọn được lưu trữ dường như không giúp ích gì.
  • Trong Safari, tab bị lỗi nhiều lần với lỗi phân đoạn khi chọn nhiều dòng và kết thúc/bắt đầu lựa chọn ở giữa văn bản của nút.

Tuy nhiên, tôi nghi ngờ rằng bất cứ điều gì tốt hơn có thể có trong các trình duyệt khác ngoài Firefox, nhưng thậm chí là Firefox has a ticket to drop discontiguous selections.

+0

lỗi này xuất hiện khi bạn bật thanh công cụ thiết bị và làm mới trong chrome –

+0

@AdamClark Uhm ... lỗi nào? – Siguza

+0

sau khi làm mới trong devtools thanh công cụ thiết bị lỗi xuất hiện.https: //www.dropbox.com/s/ngab9c9ydy1r9ye/Screenshot%202016-08-23%2015.10.25.png? Dl = 0 –

3

FYI Tôi đã gặp lỗi tương tự khi cuộn tính năng "sao chép vào khay nhớ tạm" của riêng tôi. Tôi sẽ không giải quyết mã được cung cấp của OP, nhưng tôi sẽ cho bạn biết làm thế nào tôi sửa nó trong mã của riêng tôi.

tái sản xuất:

  1. Sao chép một số văn bản khác trên trang vào clipboard, ví dụ "foo".
  2. Dán văn bản vào một nơi nào đó. Nó xuất ra "foo".
  3. Nhấp vào nút "sao chép vào khay nhớ tạm thời" của bạn, bản sao, ví dụ: "quán ba".
  4. Dán văn bản vào một nơi nào đó.

dự kiến:

"thanh" được xuất ra.

Thực tế:

"lựa chọn không liên tục không được hỗ trợ"

Fix:

Gọi window.getSelection().removeAllRanges() tại bắt đầu của "sao chép vào clipboard" của bạn xử lý sự kiện. "Không liên tục" có nghĩa là "không được kết nối". Vì vậy, tôi đoán là trình duyệt sao chép phạm vi đầu tiên (nút chứa "foo"), và sau đó tức giận khi bạn cố gắng chọn một phạm vi khác không phải là bên cạnh nút đầu tiên.

+0

Hoàn hảo, nó hoạt động cho tôi và câu trả lời này đơn giản hơn nhiều so với những người khác. – Rav

+0

Lỗi có thể được khắc phục, kể từ 20Feb - https://bugs.chromium.org/p/chromium/issues/detail?id=353069#c4 – Dropout

Các vấn đề liên quan